# This script is used to build the uos app package # Usage: # Just modify the app_name, app_version, app_description, app_author, app_email etc. # Rename this file to package_your_app.py (optional) # Open command and input 'python3 package_your_app.py' # Then the deb file will create in ./bin directory # Warning: # Your computer should installed 'dh_make', 'python3' and 'linuxdeployqt' # If your app_path have directory lib, it won't exec linuxdeployqt~ # Datetime: 2024/10/17 import os import json import shutil import glob # define your app information class App(object): app_name = 'SafeBroadClient' app_chn_name = 'EQM安播客户端' app_id = 'com.hzlh.cas-sbc' # not support upper,just lowwer and digit! app_version = '1.0.1.0' app_description = '联汇国产化智慧播控系统(EQM)' app_author = 'wangfang' app_email = 'wangfang@hzlh.com' icon_size = '200x200' # support 16/24/32/48/128/256/512 icon_name = 'logo.ico' # should put it in 'app_path/bin' app_path = '/SRC/' # your application path should be 'app_path/bin'!!! home_page = 'https://www.hzlh.com' depend_lib_path = '' # if needed, it'll add to Environment Path # global var ROOT_DIR = os.getcwd() CURRENT_USER = os.getenv("USER") or os.getenv("LOGNAME") #HOME_PATH = os.path.expanduser('~') def add_depend_libs_path(): if App.depend_lib_path != '': os.system('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:' + App.depend_lib_path) # switch to directory def switch_to_dir(dir_name): if not os.path.exists(dir_name): os.makedirs(dir_name) os.chdir(dir_name) # create target directory def create_target_dir(dir_name): target_dir = dir_name if not os.path.exists(target_dir): os.makedirs(target_dir) return target_dir # create a file def create_file(file_name): with open(file_name, 'w') as f: f.write('') # create your_app_id-6.0.0 directory # it always like ./bin/your_app_id-6.0.0 def create_app_dir(): app_dir = os.path.join(ROOT_DIR, 'bin', App.app_id + '-' + App.app_version) return create_target_dir(app_dir) # create a file nemed info def create_info_file(): data = { "appid": App.app_id, "name": App.app_name, "version": App.app_version, "arch": ["amd64"], "permissions": { "autostart": False, "notification": False, "trayicon": False, "clipboard": True, "account": False, "bluetooth": False, "camera": False, "audio_record": False, "installed_apps": False } } with open('info', 'w') as json_file: json.dump(data, json_file, indent=4) # create a file named your_app_id.desktop # Icon=/opt/apps/{App.app_id}/files/bin/{App.app_name}.png def create_desktop_entry_file(file_name): content = f"""[Desktop Entry] Name={App.app_name} Name[zh_CN]={App.app_chn_name} Comment={App.app_description} Exec=/opt/apps/{App.app_id}/files/AppRun Icon=/opt/apps/{App.app_id}/files/bin/{App.icon_name} Terminal=false Categories=Utility Type=Application """ with open(file_name, 'w') as file: file.write(content) def create_apprun_file(): content = f"""#!/bin/bash SELF=$(readlink -f "$0") HERE=${{SELF%/*}} ARCH="x86_64-linux-gnu" #ARCH="aarch64-linux-gnu" export PATH="${{HERE}}/bin:${{PATH:+:$PATH}}:$PATH" export LD_LIBRARY_PATH="${{HERE}}/lib" export XDG_DATA_DIRS="${{HERE}}/share:/usr/share" exec {App.app_name} $* """ with open('AppRun', 'w') as file: file.write(content) os.system('chmod 755 AppRun') def get_desktop_path(): user_dirs_path = os.path.expanduser('~/.config/user-dirs.dirs') desktop_path = os.path.expanduser('~/Desktop') # default if os.path.exists(user_dirs_path): with open(user_dirs_path) as f: for line in f: if "XDG_DESKTOP_DIR" in line: desktop_path = line.split("=")[1].strip().strip('"') desktop_path = desktop_path.replace('$HOME', os.path.expanduser('~')) break return desktop_path def create_install_file(): desktop_path = get_desktop_path() print('This user home path is ' + desktop_path) with open('install', 'w') as f: f.write(f'{App.app_id}/ /opt/apps\n') f.write(f'{App.app_id}/entries/applications/{App.app_id}.desktop /usr/share/applications\n') #f.write(f'{App.app_id}/entries/applications/{App.app_id}.desktop {desktop_path}\n') #f.write(f'{App.app_id}/files/lib/* /usr/lib\n') def modify_rules_file(): # append "xxx" to the rules file with open('rules', 'a') as f: f.write(""" override_dh_auto_build: override_dh_shlibdeps: --dpkg-shlibdeps-params=--ignore-missing-info override_dh_strip:""") def modify_control_file(): with open('control', 'r+') as f: data = f.read() start_pos = data.find('Description:') if start_pos != -1: insert_pos = start_pos + len('Description:') new_text = data[:insert_pos] + App.app_description + '\n' else: new_text = data line_datas = new_text.split('\n') new_datas = [] for line in line_datas: if line.startswith('Maintainer:'): new_datas.append(f'Maintainer:{App.app_author} {App.app_email}') elif line.startswith('Homepage:'): new_datas.append(f'Homepage:{App.home_page}') else: new_datas.append(line) f.seek(0) f.truncate() f.write('\n'.join(new_datas)) def create_postinst_file(): with open('postinst', 'w') as f: f.write(f''' #!/bin/bash set -e #chown -R {CURRENT_USER}:{CURRENT_USER} /opt/apps/{App.app_id}/files/bin || true chmod -R 777 /opt/apps/{App.app_id}/files/bin exit 0''') os.system('chmod 755 postinst') def is_bin_exists(): if not os.path.exists('bin'): return False return True # copy ./bin/your_app to ./your_app def copy_file_to_target_dir(src_path, target_path): shutil.copy(src_path, target_path) def circulate_copy_to_target_dir(src_path, target_path): for file in glob.glob(src_path): des = target_path + '/' + file.split('/')[-1] shutil.copy(file, des) # remove all files below this directory def remove_files_in_current_dir(current_dir): for item in os.listdir(current_dir): # 遍历当前目录下的所有文件和目录 item_path = os.path.join(current_dir, item) # 获取完整路径 if os.path.isfile(item_path): # 如果是文件 os.remove(item_path) # 删除文件 def is_packaged(): if os.path.exists('lib'): return True else: return False def package_app(): command = f"linuxdeployqt ./bin/{App.app_name} -appimage" os.system(command) if __name__ == '__main__': print('Start to build uos app package...') add_depend_libs_path() app_bin_dir = ROOT_DIR + App.app_path switch_to_dir(app_bin_dir) if not is_bin_exists(): print('The bin directory is not exists!') exit(1) if not is_packaged(): package_app() switch_to_dir(ROOT_DIR) app_dir = create_app_dir() switch_to_dir(app_dir) create_target_dir(App.app_id) data_dir = app_dir + '/' + App.app_id switch_to_dir(data_dir) # create entries and files directory create_target_dir('entries') create_target_dir('files') # create a file named info create_info_file() entries_dir = data_dir + '/entries' switch_to_dir(entries_dir) create_target_dir('applications') app_desktop_file = 'applications/' + App.app_id + '.desktop' create_file(app_desktop_file) create_desktop_entry_file(app_desktop_file) # create icons directory icon_path = 'icons/hicolor/' + App.icon_size + '/apps' create_target_dir(icon_path) # copy the icon file to the icons directory app_path = ROOT_DIR + App.app_path icon_file = app_path + 'bin/' + App.icon_name os.system(f'cp {icon_file} {icon_path}/{App.app_id}.png') files_dir = data_dir + '/files' # copy the app directory to the files directory os.system(f'cp -r {app_path}/* {files_dir}') switch_to_dir(files_dir) create_apprun_file() switch_to_dir(app_dir) # make debian directory,just exec 'dh_make --createorig -s' or 'apt install dh-make' first # if command'dh_make' not found os.system('dh_make --createorig -s -y') # if command dh_make not found, you can exec 'apt install dh-make' to install it # create install file, just like 'touch install': # install file format # com.hzlh.cas10m/ /opt/apps # com.hzlh.cas10m/entries/applications/cas10m.desktop /usr/share/applications # //com.hzlh.cas10m/files/lib/ /usr/lib debian_dir = app_dir + '/debian' switch_to_dir(debian_dir) create_install_file() # just for log and config file create_postinst_file() # modify the control file, like depends, description, etc. modify_control_file() # modify changelog file, read all data then replace 'app_version-1' to 'app_version' with open('changelog', 'r+') as f: data = f.read() data = data.replace(App.app_version + '-1', App.app_version) f.seek(0) f.truncate() f.write(data) # remove ex or EX files, just exec 'rm *.ex *.EX' os.system('rm *.ex *.EX') # modify the rules file modify_rules_file() switch_to_dir(app_dir) # make deb package, just exec 'dpkg-buildpackage -tc -uc -us -b -d' os.system('dpkg-buildpackage -tc -uc -us -b -d')