office-gobmx/bin/update/create_partial_update.py
Jens Carl 4dc85b98d7 Fix 'is' operator for comparison
The 'is' operator should not be used for comparison on some types of
literals. In CPython this works by accident and CPython 3.8 introduced a
SyntaxWarning (see https://bugs.python.org/issue34850).

Change-Id: I5cb7470132b26d87848c2bdc382b05477eb56afb
Reviewed-on: https://gerrit.libreoffice.org/83032
Tested-by: Jenkins
Reviewed-by: Jens Carl <j.carl43@gmx.de>
2019-11-24 07:41:58 +01:00

160 lines
5.6 KiB
Python
Executable file

#!/usr/bin/env python3
import requests
import json
import sys
import hashlib
import os
import subprocess
import errno
import json
from config import parse_config
from uncompress_mar import extract_mar
from tools import get_file_info, get_hash
from signing import sign_mar_file
from path import UpdaterPath, mkdir_p, convert_to_unix, convert_to_native
BUF_SIZE = 1024
current_dir_path = os.path.dirname(os.path.realpath(convert_to_unix(__file__)))
class InvalidFileException(Exception):
def __init__(self, *args, **kwargs):
super().__init__(self, *args, **kwargs)
def download_file(filepath, url, hash_string):
with open(filepath, "wb") as f:
response = requests.get(url, stream=True)
if not response.ok:
return
for block in response.iter_content(1024):
f.write(block)
file_hash = get_hash(filepath)
if file_hash != hash_string:
raise InvalidFileException("file hash does not match for file %s: Expected %s, Got: %s" % (url, hash_string, file_hash))
def handle_language(lang_entries, filedir):
mar = os.environ.get('MAR', 'mar')
langs = {}
for lang, data in lang_entries.items():
lang_dir = os.path.join(filedir, lang)
lang_file = os.path.join(lang_dir, "lang.mar")
mkdir_p(lang_dir)
download_file(lang_file , data["url"], data["hash"])
dir_path = os.path.join(lang_dir, "lang")
mkdir_p(dir_path)
extract_mar(lang_file, dir_path)
langs[lang] = dir_path
return langs
def download_mar_for_update_channel_and_platform(config, platform, temp_dir):
mar = os.environ.get('MAR', 'mar')
base_url = config.server_url + "update/partial-targets/1/"
url = base_url + platform + "/" + config.channel
r = requests.get(url)
if r.status_code != 200:
print(r.content)
raise Exception("download failed")
update_info = json.loads(r.content.decode("utf-8"))
update_files = update_info['updates']
downloaded_updates = {}
for update_file in update_files:
build = update_file["build"]
filedir = os.path.join(temp_dir, build)
mkdir_p(filedir)
filepath = filedir + "/complete.mar"
url = update_file["update"]["url"]
expected_hash = update_file["update"]["hash"]
download_file(filepath, url, expected_hash)
dir_path = os.path.join(filedir, "complete")
mkdir_p(dir_path)
extract_mar(filepath, dir_path)
downloaded_updates[build] = {"complete": dir_path}
langs = handle_language(update_file["languages"], filedir)
downloaded_updates[build]["languages"] = langs
return downloaded_updates
def generate_file_name(current_build_id, old_build_id, mar_name_prefix):
name = "%s_from_%s_partial.mar" %(mar_name_prefix, old_build_id)
return name
def generate_lang_file_name(current_build_id, old_build_id, mar_name_prefix, lang):
name = "%s_%s_from_%s_partial.mar" %(mar_name_prefix, lang, old_build_id)
return name
def add_single_dir(path):
dir_name = [os.path.join(path, name) for name in os.listdir(path) if os.path.isdir(os.path.join(path, name))]
return dir_name[0]
def main():
workdir = sys.argv[1]
updater_path = UpdaterPath(workdir)
updater_path.ensure_dir_exist()
mar_name_prefix = sys.argv[2]
update_config = sys.argv[3]
platform = sys.argv[4]
build_id = sys.argv[5]
current_build_path = updater_path.get_current_build_dir()
mar_dir = updater_path.get_mar_dir()
temp_dir = updater_path.get_previous_build_dir()
update_dir = updater_path.get_update_dir()
current_build_path = add_single_dir(current_build_path)
if sys.platform == "cygwin":
current_build_path = add_single_dir(current_build_path)
config = parse_config(update_config)
updates = download_mar_for_update_channel_and_platform(config, platform, temp_dir)
data = {"partials": []}
for build, update in updates.items():
file_name = generate_file_name(build_id, build, mar_name_prefix)
mar_file = os.path.join(update_dir, file_name)
subprocess.call([os.path.join(current_dir_path, 'make_incremental_update.sh'), convert_to_native(mar_file), convert_to_native(update["complete"]), convert_to_native(current_build_path)])
sign_mar_file(update_dir, config, mar_file, mar_name_prefix)
partial_info = {"file":get_file_info(mar_file, config.base_url), "from": build, "to": build_id, "languages": {}}
# on Windows we don't use language packs
if sys.platform != "cygwin":
for lang, lang_info in update["languages"].items():
lang_name = generate_lang_file_name(build_id, build, mar_name_prefix, lang)
# write the file into the final directory
lang_mar_file = os.path.join(update_dir, lang_name)
# the directory of the old language file is of the form
# workdir/mar/language/en-US/LibreOffice_<version>_<os>_archive_langpack_<lang>/
language_dir = add_single_dir(os.path.join(mar_dir, "language", lang))
subprocess.call([os.path.join(current_dir_path, 'make_incremental_update.sh'), convert_to_native(lang_mar_file), convert_to_native(lang_info), convert_to_native(language_dir)])
sign_mar_file(update_dir, config, lang_mar_file, mar_name_prefix)
# add the partial language info
partial_info["languages"][lang] = get_file_info(lang_mar_file, config.base_url)
data["partials"].append(partial_info)
with open(os.path.join(update_dir, "partial_update_info.json"), "w") as f:
json.dump(data, f)
if __name__ == '__main__':
main()