def write_to_package_job(control, path, callback_version_id): # copy to temporary """ This job will be called when any field in .deb file control part has been edited. :param control: New Control Dict :type control: dict :param path: Original Package Path :type path: str :param callback_version_id: Callback Version ID, for callback query :type callback_version_id: int """ abs_path = os.path.join(settings.MEDIA_ROOT, path) temp_path = os.path.join(settings.TEMP_ROOT, str(uuid.uuid1()) + '.deb') shutil.copyfile(abs_path, temp_path) # read new package temp_package = DebianPackage(temp_path) temp_package.control = control # save new package temp_package.save() t_version = Version.objects.get(id=callback_version_id) t_version.write_callback(temp_package.path)
def handle_uploaded_package(path): """ :param path: Package Uploaded Path :type path: str :return: Result Dict :rtype: dict """ result_dict = {} try: uploaded_package = DebianPackage(path) control = uploaded_package.control version_dir = os.path.join(settings.MEDIA_ROOT, 'versions') if not os.path.isdir(version_dir): mkdir_p(version_dir) target_dir = os.path.join(version_dir, str(uuid.uuid1())) if not os.path.isdir(target_dir): mkdir_p(target_dir) target_path = os.path.join( target_dir, control.get('Package', 'undefined') + '_' + control.get('Version', 'undefined') + '_' + control.get('Architecture', 'undefined') + '.deb') with transaction.atomic(): p_section = Section.objects.filter( name=control.get('Section', None)).last() if p_section: pass else: # create a new section p_section_name = control.get('Section', None) if p_section_name: p_section = Section(name=p_section_name) p_section.save() # search version p_version = Version.objects.filter( c_package=control.get('Package', None), c_version=control.get('Version', None)).last() if p_version: # version conflict result_dict.update({ "success": False, "exception": _("Version Conflict: %s") % p_version.c_version }) else: # os.rename(path, target_path) shutil.move(path, target_path) p_version = Version() p_version.c_package = control.get('Package', None) p_version.c_version = control.get('Version', None) p_version.storage = os.path.relpath(target_path, settings.MEDIA_ROOT) p_version.maintainer_name = DebianPackage.value_for_field( control.get('Maintainer', None)) p_version.maintainer_email = DebianPackage.detail_for_field( control.get('Maintainer', None)) p_version.c_description = control.get('Description', "") p_version.c_section = p_section p_version.c_tag = control.get('Tag', None) p_version.c_architecture = control.get('Architecture', None) p_version.c_name = control.get('Name', None) p_version.author_name = DebianPackage.value_for_field( control.get('Author', None)) p_version.author_email = DebianPackage.detail_for_field( control.get('Author', None)) p_version.sponsor_name = DebianPackage.value_for_field( control.get('Sponsor', None)) p_version.sponsor_site = DebianPackage.detail_for_field( control.get('Sponsor', None)) p_version.c_depiction = control.get('Depiction', None) p_version.c_homepage = control.get('Homepage', None) p_version.c_priority = control.get('Priority', None) p_version.c_installed_size = control.get( 'Installed-Size', None) p_version.c_essential = control.get('Essential', None) p_version.c_depends = control.get('Depends', None) p_version.c_pre_depends = control.get('Pre-Depends', None) p_version.c_recommends = control.get('Recommends', None) p_version.c_suggests = control.get('Suggests', None) p_version.c_breaks = control.get('Breaks', None) p_version.c_conflicts = control.get('Conflicts', None) p_version.c_replaces = control.get('Replaces', None) p_version.c_provides = control.get('Provides', None) p_version.c_build_essential = control.get( 'Build-Essential', None) p_version.c_origin = control.get('Origin', None) p_version.c_bugs = control.get('Bugs', None) p_version.c_multi_arch = control.get('Multi-Arch', None) p_version.c_source = control.get('Source', None) p_version.c_subarchitecture = control.get( 'Subarchitecture', None) p_version.c_kernel_version = control.get( 'Kernel-Version', None) p_version.c_installer_menu_item = control.get( 'Installer-Menu-Item', None) p_version.c_built_using = control.get('Built-Using', None) p_version.c_built_for_profiles = control.get( 'Built-For-Profiles', None) p_version.c_icon = control.get('Icon', None) p_version.update_hash() p_version.save() # move resource result_dict.update({"success": True, "version": p_version.id}) except Exception as e: # error handler result_dict.update({ "success": False, # TODO: fix unicode bug "exception": str(e) }) return result_dict
def build_procedure(conf): """ This is the main package list building procedure. """ if not conf["build_p_diff"]: # Build Package file build_all_versions_enabled = conf["build_all"] # Get Package List QuerySet if build_all_versions_enabled: version_set = Version.objects.filter(enabled=True).order_by('-id') version_count = version_set.count() else: version_set = Version.objects.raw( "SELECT * FROM `WEIPDCRM_version` " "WHERE `enabled` = TRUE " "GROUP BY `c_package` " "ORDER BY `c_package`, `id` DESC" ) version_count = 0 for version in version_set: version_count += 1 # Check Empty if version_count == 0: raise ValueError(_("No enabled package available.")) # Preparing Temp Directory build_temp_path = os.path.join(settings.TEMP_ROOT, str(conf["build_uuid"])) if not os.path.exists(build_temp_path): mkdir_p(build_temp_path) # Create Temp Package file build_temp_package = open(os.path.join(build_temp_path, "Packages"), "wb+") # Generate Control List depiction_url = "" if preferences.Setting.advanced_mode: site = Site.objects.get(id=settings.SITE_ID) scheme = "http" if settings.SECURE_SSL is True: scheme = "https" depiction_url = "%s://%s" % (scheme, site.domain) for version_instance in version_set: # !!! HERE WE SHOULD USE ADVANCED CONTROL DICT !!! control_dict = version_instance.get_advanced_control_dict() if (not version_instance.custom_depiction) and len(depiction_url) != 0: control_dict["Depiction"] = depiction_url + version_instance.get_absolute_url() if version_instance.online_icon is not None and len(str(version_instance.online_icon)) > 0: control_dict["Icon"] = depiction_url + os.path.join(str(preferences.Setting.resources_alias), version_instance.online_icon.name) DebianPackage.get_control_content(control_dict, build_temp_package) build_temp_package.write("\n".encode("utf-8")) # Compression Gzip build_temp_package.seek(0) if conf["build_compression"] == 1 \ or conf["build_compression"] == 2 \ or conf["build_compression"] == 5 \ or conf["build_compression"] == 6: build_temp_package_gz = gzip.open(os.path.join(build_temp_path, "Packages.gz"), mode="wb") while True: cache = build_temp_package.read(16 * 1024) # 16k cache if not cache: break build_temp_package_gz.write(cache) build_temp_package_gz.close() # Compression Bzip build_temp_package.seek(0) if conf["build_compression"] == 3 \ or conf["build_compression"] == 4 \ or conf["build_compression"] == 5 \ or conf["build_compression"] == 6: build_temp_package_bz2 = bz2.BZ2File(os.path.join(build_temp_path, "Packages.bz2"), mode="wb") while True: cache = build_temp_package.read(16 * 1024) # 16k cache if not cache: break build_temp_package_bz2.write(cache) build_temp_package_bz2.close() # Close original Package file build_temp_package.close() # Release active_release = Release.objects.get(id=conf["build_release"]) active_release_control_dict = active_release.get_control_field() build_temp_release = open(os.path.join(build_temp_path, "Release"), mode="wb") DebianPackage.get_control_content(active_release_control_dict, build_temp_release) # Checksum if conf["build_secure"] is True: def hash_file(hash_obj, file_path): with open(file_path, "rb") as f: for block in iter(lambda: f.read(65535), b""): hash_obj.update(block) checksum_list = [ "Packages", "Packages.gz", "Packages.bz2" ] build_validation_titles = [ "MD5Sum", "SHA1", "SHA256", "SHA512" ] build_validation_methods = [ hashlib.md5, hashlib.sha1, hashlib.sha256, hashlib.sha512 ] # Using a loop to iter different validation methods for build_validation_index in range(0, 3): if conf["build_validation"] > build_validation_index: build_temp_release.write((build_validation_titles[build_validation_index] + ":\n").encode("utf-8")) for checksum_instance in checksum_list: checksum_path = os.path.join(build_temp_path, checksum_instance) if os.path.exists(checksum_path): m2 = build_validation_methods[build_validation_index]() hash_file(m2, checksum_path) p_hash = m2.hexdigest() p_size = os.path.getsize(checksum_path) build_temp_release.write( (" " + p_hash + " " + str(p_size) + " " + checksum_instance + "\n").encode("utf-8") ) build_temp_release.close() if conf["build_secure"] is True: # GPG Signature """ Use 'gpg --gen-key' to generate GnuPG key before using this function. """ password = preferences.Setting.gpg_password if password is not None and len(password) > 0: subprocess.check_call( ["gpg", "-abs", "--homedir", os.path.join(settings.BASE_DIR, '.gnupg'), "--batch", "--yes", "--pinentry-mode=loopback", "--passphrase", password, "-o", os.path.join(build_temp_path, "Release.gpg"), os.path.join(build_temp_path, "Release"), ] ) else: subprocess.check_call( ["gpg", "-abs", "--homedir", os.path.join(settings.BASE_DIR, '.gnupg'), "--batch", "--yes", "-o", os.path.join(build_temp_path, "Release.gpg"), os.path.join(build_temp_path, "Release"), ] ) # Preparing Directory release_root = os.path.join( settings.MEDIA_ROOT, "releases", str(active_release.id), ) build_path = os.path.join( release_root, "builds", str(conf["build_uuid"]) ) if not os.path.isdir(build_path): mkdir_p(build_path) # Publish rename_list = [ "Release", "Release.gpg", "Packages", "Packages.gz", "Packages.bz2" ] for rename_instance in rename_list: rename_path = os.path.join(build_temp_path, rename_instance) rename_to_path = os.path.join(build_path, rename_instance) active_path = os.path.join(release_root, rename_instance) if os.path.exists(rename_path): if os.path.exists(active_path): os.unlink(active_path) shutil.copyfile(rename_path, active_path) os.chmod(active_path, 0o755) # os.rename(rename_path, rename_to_path) shutil.move(rename_path, rename_to_path) os.chmod(rename_to_path, 0o755) else: if os.path.exists(rename_to_path): os.unlink(rename_to_path) if os.path.exists(active_path): os.unlink(active_path) def thumb_png(png_path): img = Image.open(png_path) img.thumbnail((60, 60), Image.ANTIALIAS) img.save(png_path) # Cydia Icon cydia_icon_path = os.path.join(release_root, "CydiaIcon.png") if os.path.exists(cydia_icon_path): os.unlink(cydia_icon_path) if active_release.icon is not None and len(str(active_release.icon)) > 0: src_path = os.path.join(settings.MEDIA_ROOT, active_release.icon.name) if os.path.exists(src_path): shutil.copyfile( src_path, cydia_icon_path ) else: src_path = os.path.join(settings.STATIC_ROOT, "img/CydiaIcon.png") if os.path.exists(src_path): shutil.copyfile( src_path, cydia_icon_path ) if os.path.exists(cydia_icon_path): thumb_png(cydia_icon_path) os.chmod(cydia_icon_path, 0o755) build_instance = Build.objects.get(uuid=str(conf["build_uuid"])) if build_instance is not None: build_instance.is_finished = True build_instance.save() else: # TODO: Pdiffs Feature pass