Create stanalone installer

This commit is contained in:
Kamte
2024-03-13 22:31:48 +06:30
committed by GitHub
parent d7f68fb4bf
commit 7769127675
25 changed files with 565 additions and 0 deletions

BIN
Set-up_v5.2.0.436.zip Normal file

Binary file not shown.

273
installer.py Normal file
View File

@@ -0,0 +1,273 @@
import os
import io
import sys
import platform
import subprocess
import string
import json
import random
import zipfile
from xml.etree import ElementTree as ET
try:
import requests
except ImportError:
sys.exit(
"""You need requests module!
install it from https://pypi.org/project/requests/
or run: pip3 install requests."""
)
try:
from tqdm.auto import tqdm
except ImportError:
sys.exit(
"""You need tqdm module!
install it from https://pypi.org/project/tqdm/
or run: pip3 install tqdm."""
)
VERSION_STR = "1.0.0"
ACC_URL = "https://cdn-ffc.oobesaas.adobe.com/core/v1/applications?name=CreativeCloud&name=CCLBS&osVersion={osVersion}&platform={osPlatform}&version={appVersion}"
ADOBE_REQ_HEADERS = {
"X-Adobe-App-Id": "accc-apps-panel-desktop",
"User-Agent": "Adobe Application Manager 2.0",
"X-Api-Key": "CC_HD_ESD_1_0",
"Cookie": "fg="
+ "".join(random.choice(string.ascii_uppercase + string.digits) for _ in range(26))
+ "======",
}
ADOBE_DL_HEADERS = {"User-Agent": "Creative Cloud"}
CURR_PATH = os.path.dirname(os.path.abspath(__file__))
ADOBE_SETUP_BIN = os.path.join(CURR_PATH, "Set-up.exe")
session = requests.sessions.Session()
def setup_version():
jsonFromPowerShell = subprocess.run(
[
"powershell.exe",
"(Get-Item "
+ ADOBE_SETUP_BIN
+ ").VersionInfo.FileVersion | ConvertTo-Json",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
).stdout
return json.loads(jsonFromPowerShell)
def os_data():
osVersionData = sys.getwindowsversion()
osFullVer = "{}.{}.0.{}".format(
osVersionData.major, osVersionData.minor, osVersionData.build
)
osVer = "{}.{}.0".format(osVersionData.major, osVersionData.minor)
osPlatform = "win32"
if platform.machine().endswith("64") == True:
osPlatform = "win64"
return osFullVer, osVer, osPlatform
def get_xml_data(url):
response = session.get(url, stream=True, headers=ADOBE_REQ_HEADERS)
response.encoding = "utf-8"
return ET.fromstring(response.content)
def file_download(url, dest_dir):
response = session.get(url, stream=True, headers=ADOBE_REQ_HEADERS)
total_size_in_bytes = int(response.headers.get("content-length", 0))
if total_size_in_bytes > 0:
name = os.path.basename(url)
dest_dir = os.path.join(dest_dir, name)
if (
os.path.isfile(dest_dir)
and os.path.getsize(dest_dir) == total_size_in_bytes
):
print("Downloaded file is OK. Skipping ...")
return
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm(total=total_size_in_bytes, unit="iB", unit_scale=True)
with open(dest_dir, "wb") as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
print("ERROR, something went wrong")
def get_packages():
setupVersion = setup_version()
print("\nGet Required packages for Adobe Installer v-{}".format(setupVersion))
winFullVer, winVer, winPlatform = os_data()
acc_xml_url = ACC_URL.format(
osVersion=winFullVer, osPlatform=winPlatform, appVersion=setupVersion
)
xml_data = get_xml_data(acc_xml_url)
accVersion = xml_data.find(".//application/version").text
if accVersion != setupVersion:
print("\nYour installer will not work! Please try Adobe Installer version 5x or 6x\n")
exit(1)
package_cdn = xml_data.find(".//cdn/secure").text
packageSets = xml_data.findall(".//packageSets/packageSet")
# sort by packageSet name
packageSets[:] = sorted(
packageSets, key=lambda packageSets: packageSets.findtext("sequenceNumber")
)
# appinfo data
xml_root = ET.Element("application")
for key, val in dict(
{
"name": xml_data.find(".//application/name").text,
"platform": xml_data.find(".//application/platform").text,
"lbsurl": "http://ccmdl.adobe.com/AdobeProducts/KCCC/1/win32/CreativeCloudSet-Up.exe",
}
).items():
child = ET.Element(key)
child.text = str(val)
xml_root.append(child)
xml_packagesets = ET.SubElement(xml_root, "packageSets")
# create packages dir
packages_dir = os.path.join(CURR_PATH, "packages")
os.makedirs(packages_dir, exist_ok=True)
for set in packageSets:
setName = set.find("name").text
installPath = set.find("installPath").text
if installPath == "[NOT-USED]":
continue
xml_packageSet = ET.SubElement(xml_packagesets, "packageSet")
for key, val in dict(
{
"name": setName,
"installPath": set.find("installPath").text,
"sequenceNumber": set.find("sequenceNumber").text,
}
).items():
child = ET.Element(key)
child.text = str(val)
xml_packageSet.append(child)
# create package
pkg_dir = os.path.join(packages_dir, setName)
os.makedirs(pkg_dir, exist_ok=True)
packages = set.findall(".//packages/package")
# sort by packageSet name
packages[:] = sorted(
packages, key=lambda packages: int(packages.findtext("sequenceNumber"))
)
xml_packages = ET.SubElement(xml_packageSet, "packages")
for pk in packages:
packageName = pk.find("name").text
manifestUrl = pk.find("manifestUrl").text
manifestXml = get_xml_data(package_cdn + manifestUrl)
# download sub package
sub_pkg_dir = os.path.join(pkg_dir, packageName)
os.makedirs(sub_pkg_dir, exist_ok=True)
assets = manifestXml.find(".//asset_list/asset/asset_path").text
print("\nDownloading package: " + packageName)
file_download(assets, sub_pkg_dir)
xml_package = ET.SubElement(xml_packages, "package")
for key, val in dict(
{
"name": packageName,
"sequenceNumber": pk.find("sequenceNumber").text,
"optional": pk.find("optional").text,
"pimxPath": "/"
+ "/".join([setName, packageName, packageName + ".pimx"]),
}
).items():
child = ET.Element(key)
child.text = str(val)
xml_package.append(child)
if pk.find("additionalInfo") is not None:
adInfo = pk.find("additionalInfo")
xml_pkg_adn = ET.SubElement(xml_package, "additionalInfo")
for elem in adInfo:
xml_pkg_adn.append(elem)
xml_filters = ET.SubElement(xml_packageSet, "filters")
xml_filter = ET.SubElement(xml_filters, "filter")
xml_filter.set("type", "operatingSystem")
xml_filter_config = ET.SubElement(xml_filter, "config")
xml_filter_config.text = winVer
if set.find("additionalInfo") is not None:
adInfo = set.find("additionalInfo")
xml_pkgSet_adn = ET.SubElement(xml_packageSet, "additionalInfo")
for elem in adInfo:
xml_pkgSet_adn.append(elem)
pkg_version = ET.SubElement(xml_root, "version")
pkg_version.text = xml_data.find(".//application/version").text
print("\nCreating ApplicationInfo.xml")
tree = ET.ElementTree(xml_root)
ET.indent(tree, space=" ", level=0)
xml_file = os.path.join(packages_dir, "ApplicationInfo.xml")
tree.write(xml_file, encoding="utf-8", xml_declaration=True)
get_pim_dll(packages_dir)
def get_pim_dll(packages_dir):
print("\nGetting AdobePIM.dll")
res_dir = "resources"
os.makedirs(res_dir, exist_ok=True)
core_package = os.path.join(packages_dir, "ADC", "Core", "Core.zip")
with zipfile.ZipFile(core_package, "r") as cp:
for file in cp.namelist():
if file.endswith("AdobePIM.dll"):
cp.extract(file, res_dir)
elif file.endswith("Core.pima"):
pimaData = io.BytesIO(cp.read(file))
with zipfile.ZipFile(pimaData) as pima:
for pim in pima.namelist():
if pim.endswith("AdobePIM.dll"):
pima.extract(pim, res_dir)
if __name__ == "__main__":
ye = int((32 - len(VERSION_STR)) / 2)
print("=================================")
print("= Build Adobe Installer =")
print(
"{} {} {}\n".format("=" * ye, VERSION_STR, "=" * (31 - len(VERSION_STR) - ye))
)
get_packages()
print("\nSuccessfully downloaded installer files\n")

1
resources/Config.xml Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Config><UIConfig><HideVersion>false</HideVersion><SkipLaunch>true</SkipLaunch><HidePIIScreen>true</HidePIIScreen><ShowInstallOptions>true</ShowInstallOptions><SkipAccLaunch>true</SkipAccLaunch></UIConfig></Config>

View File

@@ -0,0 +1,8 @@
{
"Name": "Výukové lekce k aplikaci Photoshop 2021",
"SubTitle": "Začněte, naučte se základy a nechte se inspirovat.",
"Operating1xWin": "Windows 10 version 1809 (64bitová verze) (minimální požadavek)",
"OperatingSystemMac": "Mac OS 10.14 (minimální požadavek)",
"Memory": "Instalace aplikace vyžaduje alespoň 8 GB paměti RAM",
"TextSlide1": "Plná náruč kreativity"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 – Tutorials",
"SubTitle": "Erste Schritte, Grundlagen, Inspirationen.",
"Operating1xWin": "Windows 10 version 1809 (64-Bit) (mindestens erforderlich)",
"OperatingSystemMac": "Mac OS 10.14 (mindestens erforderlich)",
"Memory": "Sie benötigen mindestens 8 GB RAM, um die Anwendung zu installieren",
"TextSlide1": "Kreativität für alle."
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 tutorials",
"SubTitle": "Get started, get the essentials, get inspired.",
"Operating1xWin": "Windows 10 version 1809 (64-bit) (Minimum required)",
"OperatingSystemMac": "Mac OS 10.14 (Minimum required)",
"Memory": "You need minimum 8Gb RAM to install the application",
"TextSlide1": "Creativity for all."
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Tutoriales de Photoshop 2021",
"SubTitle": "Empiece, descubra los fundamentos y encuentre inspiración.",
"Operating1xWin": "Windows 10 version 1809 (64 bits) (mínimo requerido)",
"OperatingSystemMac": "Mac OS 10.14 (mínimo requerido)",
"Memory": "Se necesita un mínimo de 8 GB de RAM para instalar la aplicación",
"TextSlide1": "Creatividad para todos"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Tutoriels Photoshop 2021",
"SubTitle": "Lancez-vous, saisissez l'essentiel, soyez inspiré.",
"Operating1xWin": "Windows 10 version 1809 (minimum requis)",
"OperatingSystemMac": "Mac OS 10.14 (minimum requis)",
"Memory": "Vous avez besoin de 8 Go de mémoire vive minimum pour installer l'application.",
"TextSlide1": "La créativité pour tous.",
}

View File

@@ -0,0 +1,9 @@
{
"Name": "Esercitazioni di Photoshop 2021",
"SubTitle": "Iniziate, raccogliete tutto ciò che vi serve e lasciatevi ispirare.",
"Operating1xWin": "Windows 10 version 1809 (64 bit) (versione minima richiesta)",
"OperatingSystemMac": "Mac OS 10.14 (versione minima richiesta)",
"Memory": "Sono necessari almeno 8 Gb di RAM per installare l'applicazione",
"TextSlide1": "Colora consente di ricolorare le fotografie in bianco e nero.",
"TextSlide2": "Creatività per tutti."
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 チュートリアル",
"SubTitle": "はじめに、基本事項を学び、ヒントを得てください。",
"Operating1xWin": "Windows 10 version 1809 (64-bit) (以上)",
"OperatingSystemMac": "Mac OS 10.14 (以上)",
"Memory": "アプリケーションをインストールするには、最低 8GB の RAM が必要です。",
"TextSlide1": "すべての人に「つくる力」を"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 자습서",
"SubTitle": "시작하여 필수 기능을 이용해 보십시오.",
"Operating1xWin": "Windows 10 version 1809 (64비트)(최소 요구 사양)",
"OperatingSystemMac": "Mac OS 10.14(최소 요구 사양)",
"Memory": "애플리케이션을 설치하려면 최소 8GB의 RAM이 필요합니다.",
"TextSlide1": "모두를 위한 크리에이티브"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Zelfstudies voor Photoshop 2021",
"SubTitle": "Ga aan de slag met handige tools en laat u inspireren.",
"Operating1xWin": "Windows 10 version 1809 (64-bits) (minimaal vereist)",
"OperatingSystemMac": "Mac OS 10.14 (minimaal vereist)",
"Memory": "U hebt minimaal 8 GB RAM nodig om de toepassing te installeren",
"TextSlide1": "Creativiteit voor iedereen."
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Samouczki programu Photoshop 2021",
"SubTitle": "Rozpocznij, poznaj wszystkie podstawy, zainspiruj się.",
"Operating1xWin": "Windows 10 version 1809 (64-bitowy) (minimalna wymagana wersja)",
"OperatingSystemMac": "Mac OS 10.14 (minimalna wymagana wersja)",
"Memory": "Do instalacji aplikacji wymagane są co najmniej 8 GB pamięci RAM.",
"TextSlide1": "Kreatywność dla wszystkich"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Руководства по Photoshop 2021",
"SubTitle": "Создавайте работы, узнавайте новое, получайте вдохновение.",
"Operating1xWin": "Windows 10 версия 1809 (64-разрядная) (минимально допустимая версия)",
"OperatingSystemMac": "Mac OS 10.14 (минимально допустимая версия)",
"Memory": "Для установки приложения требуется минимум 8 ГБ ОЗУ",
"TextSlide1": "Проявить себя в творчестве может каждый!"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Självstudiekurser för Photoshop 2021",
"SubTitle": "Kom igång, lär dig det grundläggande och bli inspirerad.",
"Operating1xWin": "Windows 10 version 1809 (64-bitars) krävs",
"OperatingSystemMac": "macOS 10.14 krävs",
"Memory": "Om du vill installera programmet måste du ha minst 8 GB med RAM-minne",
"TextSlide1": "Kreativitet för alla."
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 教程",
"SubTitle": "快速入门,获得必备工具,获得灵感。",
"Operating1xWin": "Windows 10 version 1809 (64 位)(最低要求)",
"OperatingSystemMac": "Mac OS 10.14(最低要求)",
"Memory": "您至少需要 8GB RAM 才能安装此应用程序",
"TextSlide1": "人人都能發揮創意"
}

View File

@@ -0,0 +1,8 @@
{
"Name": "Photoshop 2021 教學課程",
"SubTitle": "開始使用、瞭解基本知識、取得靈感。",
"Operating1xWin": "Windows 10 version 1809 (64 位元) (最低需求)",
"OperatingSystemMac": "Mac OS 10.14 (最低需求)",
"Memory": "您需要至少 8 GB 的 RAM 才能安裝應用程式",
"TextSlide1": "人人都能發揮創意"
}

View File

@@ -0,0 +1,78 @@
$(document).ready(function () {
cecInit();
})
function cecInit() {
var jsonData;
var locale = getParameterByName('locale');
var isHighDpi = getParameterByName('isHighDpi');
cecGetLocaleJson(locale);
}
function resizeWin() {
myWindow.resizeTo(455, 239);
}
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
for (i = 0; i < slides.length; i++) {
console.log(slides[i]);
slides[i].style.opacity = "0";
slides[i].style.visibility = "hidden";
}
slideIndex++;
if (slideIndex > slides.length) {slideIndex = 1}
slides[slideIndex-1].style.opacity = "1";
slides[slideIndex-1].style.visibility = "visible";
var x = document.getElementsByTagName('video');
if (slideIndex == 99) {
x[0].currentTime = 0;
}
setTimeout(showSlides, 20000); // Change image every 20.00 seconds
}
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
function cecGetLocaleJson(locale)
{
console.log("cecGetLocaleJson");
var jsonLocation = "Dictionary/" + locale + "/locale.json";
$.getJSON(jsonLocation, function (data) {
cecDisplayContent(data, locale);
})
.fail(function () {
if(locale == "en_US") {
return;
}
cecGetLocaleJson("en_US");
})
}
function cecDisplayContent(data, locale)
{
var lcl = locale.slice(3,5);
var url = "https://www.adobe.com/"+lcl.toLowerCase()+"/products/photoshop-lightroom-classic.html";
if(locale == "en_us" || locale == "en_US") {
url = "https://www.adobe.com/products/photoshop-lightroom-classic.html";
}
if(locale == "zh_tw" || locale == "zh_TW") {
url = "https://www.adobe.com/tw/products/photoshop-lightroom-classic.html";
}
if(locale == "zh_cn" || locale == "zh_CN") {
url = "https://www.adobe.com/cn/products/photoshop-lightroom-classic.html";
}
document.getElementById("slideContainer").onclick =function() { parent.cecExternalLink(url) };
document.getElementById("slideText1").innerHTML = data["TextSlide1"];
}

View File

@@ -0,0 +1,7 @@
@charset "utf-8";
@font-face {
font-family: 'AdobeClean';
src: url('fonts/adobeclean/adobeclean-regular-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PHSP installer slideshow</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/styles.css">
<style>
html {
background-color: #fff;
}
* {box-sizing: border-box;}
body {
margin:0px;}
.mySlides {opacity: 0; position: absolute; transition: all 1s;}
img {vertical-align: middle;}
/* Slideshow container */
.slideshow-container {
max-width: 445px;
position: relative;
margin: auto;
cursor: pointer;
}
/* Caption text */
.text {
font-family: 'AdobeClean', Helvetica, Arial, sans-serif;
color: #fff;
font-weight: 450;
font-size: 15px;
letter-spacing: .3;
padding-left: 20px;
position: absolute;
bottom: 95px;
width: 30%;
text-align: center;
}
/* Number text (1/3 etc) */
.numbertext {
font-family: 'AdobeClean', Helvetica, Arial, sans-serif;
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.active {
background-color: #717171;
}
/* Fading animation */
.fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 1s;
animation-name: fade;
animation-duration: 1s;
}
@-webkit-keyframes fade {
from {opacity: .7}
to {opacity: 1}
}
@keyframes fade {
from {opacity: .1}
to {opacity: 1}
}
/* On smaller screens, decrease text size */
@media only screen and (max-width: 300px) {
.text {font-size: 11px}
}
</style>
</head>
<body>
<div class="slideshow-container" id="slideContainer" href="#">
<div class="mySlides fade" style="opacity: 1; visibility: visible;">
<video class="videos" autoplay loop muted style="width: 445px; height: 239px;"><source src="images/01_creativity_for_all_445x239.mp4" style="width: 445px; height: 239px;"></video>
<div class="text" id="slideText1">Creativity for all.</div>
</div>
</div>
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="carousel.js"></script>
</body>
</html>

2
resources/carousel/lib/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB