#!/usr/bin/env python3 import json import re from shutil import copyfile def remove_trailing_commas(json_like): """ Removes trailing commas from *json_like* and returns the result. Example:: >>> remove_trailing_commas('{"foo":"bar","baz":["blah",],}') '{"foo":"bar","baz":["blah"]}' """ trailing_object_commas_re = re.compile( r'(,)\s*}(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)') trailing_array_commas_re = re.compile( r'(,)\s*\](?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)') # Fix objects {} first objects_fixed = trailing_object_commas_re.sub("}", json_like) # Now fix arrays/lists [] and return the result return trailing_array_commas_re.sub("]", objects_fixed) def find_first_prime(str, ch): for i,c in enumerate(str): if c == ch: return i def find_last_prime(str, ch): for i,c in enumerate(str[::-1]): if c == ch: return len(str)-1-i def is_inserted_doublequote(line, i): if i >= len(line): return False if line[i] == "\"": if i == 0: return True elif (not line[i-1] == "\\"): return True return False return False def transform_back(proper_json): gyp_str = "" for line in proper_json.splitlines(): temp = '%s' % line # remove double quotes in the middle temp = temp.replace("'\": [[ \"'", "': [[ '") temp = temp.replace("'\": [ \"'", "': [ '") temp = temp.replace("'\": \"'", "': '") # remove all other double quotes for i,s in enumerate(temp): if is_inserted_doublequote(temp, i): if i == 0: temp = temp[1:] else: temp = temp[:i] + temp[i+1:] # replace \" to " temp = temp.replace("\\\"", "\"") # replace all double backslashes with single backslash temp = temp.replace("\\\\", "\\") gyp_str += temp + "\n" return gyp_str def read_file_to_proper_json(f): json_like = "" for line in f: # read it all in stripped_line = line.strip() if not stripped_line.startswith("#"): if stripped_line.find("'") != -1: # step 1: replace all " with \" stripped_line = stripped_line.replace("\\'", "\\\\'") stripped_line = stripped_line.replace("\"", "\\\"") first = find_first_prime(stripped_line, "'") last = find_last_prime(stripped_line, "'") # step 2: insert " before the first ' and after the last ' first_str = stripped_line[0:first] mid_str = stripped_line[first:last+1] last_str = stripped_line[last+1:] final_str = first_str + "\"" + mid_str + "\"" + last_str line = final_str # add double quotes for single quotes in the middle line = line.replace("': '", "'\": \"'") line = line.replace("': [ '", "'\": [ \"'") line = line.replace("': [[ '", "'\": [[ \"'") json_like += line else: json_like += line proper_json = remove_trailing_commas(json_like) return proper_json def load_json(filename): return json.loads(read_file_to_proper_json(open(filename))) def save_json(jsonobj, filename): # pass j = transform_back(jsonobj) # backup = filename + ".orig" # copyfile(filename, backup) f = open(filename, 'w') f.write(j) return def process_telegram_linux(jsonobj): child = jsonobj["'conditions'"][0][1]["'variables'"]["'pkgconfig_libs'"] child.append("'liblzma'") child.append("'openal'") child.append("'libavformat'") child.append("'libavcodec'") child.append("'libswresample'") child.append("'libswscale'") child.append("'libavutil'") child.append("'opus'") child.append("'libva-x11'") child.append("'libva-drm'") child.append("'libva'") child.append("'libdrm'") child.append("'zlib'") child.append("'minizip'") child.append("'openssl'") child = jsonobj["'conditions'"][0][1]["'variables'"]["'linux_path_opus_include%'"] child = "'/usr/include/opus'" child = jsonobj["'conditions'"][0][1]["'variables'"]["'linux_path_breakpad%'"] child = "'<(libs_loc)/breakpad'" child = jsonobj["'conditions'"][0][1]["'include_dirs'"] child.remove("'/usr/local/include'") child.remove("'<(linux_path_ffmpeg)/include'") child.remove("'<(linux_path_openal)/include'") child.append("'/usr/include/openssl'") child.append("'/usr/include'") child = jsonobj["'conditions'"][0][1]["'library_dirs'"] child.remove("'/usr/local/lib'") child.remove("'<(linux_path_ffmpeg)/lib'") child.remove("'<(linux_path_openal)/lib'") child.remove("'<(linux_path_va)/lib'") child.remove("'<(linux_path_vdpau)/lib'") child.append("'/usr/lib64/'") child = jsonobj["'conditions'"][0][1]["'libraries'"] child.remove("'breakpad_client'") child.remove("'composeplatforminputcontextplugin'") child.remove("'ibusplatforminputcontextplugin'") child.remove("'fcitxplatforminputcontextplugin'") child.remove("'himeplatforminputcontextplugin'") child.remove("'nimfplatforminputcontextplugin'") child.remove("'liblzma.a'") child.remove("'libopenal.a'") child.remove("'libavformat.a'") child.remove("'libavcodec.a'") child.remove("'libswresample.a'") child.remove("'libswscale.a'") child.remove("'libavutil.a'") child.remove("'libopus.a'") child.remove("'libva-x11.a'") child.remove("'libva-drm.a'") child.remove("'libva.a'") child.remove("'libvdpau.a'") child.remove("'libdrm.a'") child.remove("'libz.a'") child.append("'libbreakpad_client.a'") child.append("' /dev/null --libs <@(pkgconfig_libs))'") child = jsonobj["'conditions'"][0][1]["'cflags_cc'"] child.append("' /dev/null --cflags dee-1.0)'") return json.dumps(jsonobj) def process_qt(jsonobj): child = jsonobj["'variables'"]["'variables'"]["'variables'"]["'variables'"]["'variables'"]["'conditions'"][0] child[2]["'qt_version%'"] = "' /dev/null --libs xkbcommon xkbcommon-x11)'") child.append("' /dev/null --libs libpcre16)'") child.append("' /dev/null --libs zlib)'") child.append("' /dev/null --libs libpng16)'") child.append("' /dev/null --libs libwebp)'") child.append("' /dev/null --libs harfbuzz)'") child.append("' /dev/null --libs xcb-shm xcb-xfixes xcb-render xcb-renderutil xcb-sync xcb-randr xcb-xinerama xcb-xkb xcb-icccm xcb-image xcb-shape xcb-keysyms xcb-util)'") child = jsonobj["'conditions'"][0][1]["'ldflags'"] child.remove("'-static-libstdc++'") return json.dumps(jsonobj) def process_settings_linux(jsonobj): child = jsonobj["'conditions'"][0][1]["'variables'"]["'linux_common_flags'"] child.append("'-Wno-implicit-fallthrough'") child.remove("'-Werror'") child = jsonobj["'conditions'"][0][1]["'defines'"] child.remove("'QT_STATICPLUGIN'") return json.dumps(jsonobj) def process_telegram(jsonobj): child = jsonobj["'targets'"][0] child["'dependencies'"].remove("'utils.gyp:Updater'") child = jsonobj["'targets'"][0]["'defines'"] child.append("'__STDC_FORMAT_MACROS'") child.append("'TDESKTOP_DISABLE_AUTOUPDATE'") child.append("'TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME'") child.append("'TDESKTOP_DISABLE_UNITY_INTEGRATION'") child.append("'TDESKTOP_DISABLE_GTK_INTEGRATION'") child.append("'TDESKTOP_DISABLE_OPENAL_EFFECTS'") child.remove("'AL_LIBTYPE_STATIC'") child = jsonobj["'targets'"][0]["'include_dirs'"] child.remove("'<(libs_loc)/breakpad/src'") child.remove("'<(libs_loc)/lzma/C'") child.remove("'<(libs_loc)/zlib'") child.remove("'<(libs_loc)/ffmpeg'") child.remove("'<(libs_loc)/openal-soft/include'") child.remove("'<(libs_loc)/opus/include'") # child.remove("'<(libs_loc)/range-v3/include'") child.remove("'<(minizip_loc)'") child.remove("'<(sp_media_key_tap_loc)'") child.append("'<(libs_loc)/breakpad/include/breakpad'") child.append("'/usr/include/minizip'") return json.dumps(jsonobj) def process_moc(jsonobj): jsonobj["'rules'"][0]["'action'"][0] = "'/usr/bin/moc-qt5'" return json.dumps(jsonobj) def process_rcc(jsonobj): jsonobj["'rules'"][0]["'action'"][0] = "'/usr/bin/rcc-qt5'" return json.dumps(jsonobj) def process(filename, op): json = load_json(filename) json = op(json) save_json(json, filename) tl_path = './Telegram/gyp/telegram_linux.gypi' settings_path = './Telegram/gyp/settings_linux.gypi' qt_path = './Telegram/gyp/qt.gypi' tg_path = './Telegram/gyp/Telegram.gyp' moc_path = './Telegram/gyp/qt_moc.gypi' rcc_path = './Telegram/gyp/qt_rcc.gypi' tg_srcs = './Telegram/gyp/telegram_sources.txt' print("Patching %s ..." % tl_path) process(tl_path, process_telegram_linux) print("Patching %s ..." % settings_path) process(settings_path, process_settings_linux) print("Patching %s ..." % qt_path) process(qt_path, process_qt) print("Patching %s ..." % moc_path) process(moc_path, process_moc) print("Patching %s ..." % rcc_path) process(rcc_path, process_rcc) print("Patching %s ..." % tg_path) process(tg_path, process_telegram) print("Patching complete!")