Source code for bbarchivist.archivist

#!/usr/bin/env python3

import os  # filesystem read
import shutil  # directory read/write
import hashlib  # SHA-x, MD5
import time  # time for downloader
import math  # rounding of floats
try:
    from . import bbconstants  # @UnusedImport
except SystemError:
    import bbconstants  # @UnresolvedImport @Reimport
try:
    from . import utilities  # @UnusedImport
except SystemError:
    import utilities  # @UnresolvedImport @Reimport
try:
    from . import barutils  # @UnusedImport
except SystemError:
    import barutils  # @UnresolvedImport @Reimport
try:
    from . import networkutils  # @UnusedImport
except SystemError:
    import networkutils  # @UnresolvedImport @Reimport
try:
    from . import loadergen  # @UnusedImport
except SystemError:
    import loadergen  # @UnresolvedImport @Reimport
try:
    from . import hashwrapper  # @UnusedImport
except SystemError:
    import hashwrapper  # @UnresolvedImport @Reimport


[docs]def do_magic(osversion, radioversion, softwareversion, localdir, radios=True, compressed=True, deleted=True, hashed=True, crc32=False, adler32=False, sha1=True, sha224=False, sha256=False, sha384=False, sha512=False, md5=True, md4=False, ripemd160=False, whirlpool=False, cappath="cap.exe", download=True, extract=True, loaders=True, signed=True, compmethod="7z"): """ Wrap around multi-autoloader creation code. Some combination of creating, downloading, hashing, compressing and moving autoloaders. :param osversion: OS version, 10.x.y.zzzz. :type osversion: str :param radioversion: Radio version, 10.x.y.zzzz. :type radioversion: str :param softwareversion: Software release, 10.x.y.zzzz. :type softwareversion: str :param localdir: Working directory. Required. :type localdir: str :param radios: Whether to create radio autoloaders. True by default. :type radios: bool :param compressed: Whether to compress files. True by default. :type compressed: bool :param deleted: Whether to delete uncompressed files. True by default. :type deleted: bool :param hashed: Whether to hash files. True by default. :type hashed: bool :param crc32: Whether to use CRC32. False by default. :type crc32: bool :param adler32: Whether to use Adler-32. False by default. :type adler32: bool :param sha1: Whether to use SHA-1. True by default. :type sha1: bool :param sha224: Whether to use SHA-224. False by default. :type sha224: bool :param sha256: Whether to use SHA-256. False by default. :type sha256: bool :param sha384: Whether to use SHA-384. False by default. :type sha384: bool :param sha512: Whether to use SHA-512. False by default. :type sha512: bool :param md5: Whether to use MD5. True by default. :type md5: bool :param md4: Whether to use MD4. False by default. :type md4: bool :param ripemd160: Whether to use RIPEMD160. False by default. :type ripemd160: bool :param whirlpool: Whether to use Whirlpool. False by default. :type whirlpool: bool :param cappath: Path to cap.exe. Default is local dir 'cap.exe'. :type cappath: str :param download: Whether to download bar files. True by default. :type download: bool :param extract: Whether to extract bar files. True by default. :type extract: bool :param loaders: Whether to create autoloaders. True by default. :type loaders: bool :param signed: Whether to delete signed files. True by default. :type signed: bool :param compmethod: Compression method. Default is "7z" with fallback "zip". :type compmethod: str """ starttime = time.clock() version = bbconstants._version # update as needed print("~~~ARCHIVIST VERSION", version + "~~~") print("OS VERSION:", osversion) print("RADIO VERSION:", radioversion) print("SOFTWARE VERSION:", softwareversion) if compmethod == "7z": print("\nCHECKING PRESENCE OF 7ZIP...") psz = utilities.prep_seven_zip() if psz: print("7ZIP OK") szexe = utilities.get_seven_zip() else: szexe = "" print("7ZIP NOT FOUND") cont = utilities.str2bool(input("CONTINUE? Y/N ")) if cont: print("FALLING BACK TO ZIP...") compmethod = "zip" else: print("\nEXITING...") raise SystemExit # bye bye else: szexe = "" # Hash software version swhash = hashlib.sha1(softwareversion.encode('utf-8')) hashedsoftwareversion = swhash.hexdigest() # Root of all urls baseurl = "http://cdn.fs.sl.blackberry.com/fs/qnx/production/" baseurl += hashedsoftwareversion # List of OS urls osurls = [baseurl + "/winchester.factory_sfi.desktop-" + osversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.factory_sfi.desktop-" + osversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.factory_sfi_hybrid_qc8x30.desktop-" + osversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.factory_sfi_hybrid_qc8974.desktop-" + osversion + "-nto+armle-v7+signed.bar"] # List of radio urls radiourls = [baseurl + "/m5730-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.omadm-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.wtr-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8960.wtr5-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8930.wtr5-" + radioversion + "-nto+armle-v7+signed.bar", baseurl + "/qc8974.wtr2-" + radioversion + "-nto+armle-v7+signed.bar"] # Add URLs to dict, programmatically osdict = {} radiodict = {} for i in osurls: osdict[str(i)] = i for i in radiourls: radiodict[str(i)] = i # Check availability of software release print("\nCHECKING SOFTWARE RELEASE AVAILABILITY...") av = networkutils.availability(baseurl) if av: print("SOFTWARE RELEASE", softwareversion, "EXISTS") else: print("SOFTWARE RELEASE", softwareversion, "NOT FOUND") cont = utilities.str2bool(input("CONTINUE? Y/N ")) if cont: pass else: print("\nEXITING...") raise SystemExit # bye bye # Make dirs if not os.path.exists(localdir): os.makedirs(localdir) if not os.path.exists(os.path.join(localdir, 'bars')): os.mkdir(os.path.join(localdir, 'bars')) bardir = os.path.join(localdir, 'bars') if not os.path.exists(os.path.join(bardir, osversion)): os.mkdir(os.path.join(bardir, osversion)) bardir_os = os.path.join(bardir, osversion) if not os.path.exists(os.path.join(bardir, radioversion)): os.mkdir(os.path.join(bardir, radioversion)) bardir_radio = os.path.join(bardir, radioversion) if not os.path.exists(os.path.join(localdir, 'loaders')): os.mkdir(os.path.join(localdir, 'loaders')) loaderdir = os.path.join(localdir, 'loaders') if not os.path.exists(os.path.join(loaderdir, osversion)): os.mkdir(os.path.join(loaderdir, osversion)) loaderdir_os = os.path.join(loaderdir, osversion) if not os.path.exists(os.path.join(loaderdir, radioversion)): os.mkdir(os.path.join(loaderdir, radioversion)) loaderdir_radio = os.path.join(loaderdir, radioversion) if not os.path.exists(os.path.join(localdir, 'zipped')): os.mkdir(os.path.join(localdir, 'zipped')) zipdir = os.path.join(localdir, 'zipped') if not os.path.exists(os.path.join(zipdir, osversion)): os.mkdir(os.path.join(zipdir, osversion)) zipdir_os = os.path.join(zipdir, osversion) if not os.path.exists(os.path.join(zipdir, radioversion)): os.mkdir(os.path.join(zipdir, radioversion)) zipdir_radio = os.path.join(zipdir, radioversion) # Download files if download: print("\nBEGIN DOWNLOADING...") download_manager = networkutils.DownloadManager(radiodict, localdir, 5) download_manager.begin_downloads() download_manager.download_dict = osdict download_manager.begin_downloads() # Extract bar files if extract: print("\nEXTRACTING...") barutils.extract_bars(localdir) # Move bar files print("\nMOVING .bar FILES...") for files in os.listdir(localdir): if files.endswith(".bar"): print("MOVING: " + files) bardest_os = os.path.join(bardir_os, files) bardest_radio = os.path.join(bardir_radio, files) # even the fattest radio is less than 90MB if os.path.getsize(os.path.join(localdir, files)) > 90000000: try: shutil.move(os.path.join(localdir, files), bardir_os) except shutil.Error: os.remove(bardest_os) else: try: shutil.move(os.path.join(localdir, files), bardir_radio) except shutil.Error: os.remove(bardest_radio) # Create loaders if loaders: print("\nGENERATING LOADERS...") loadergen.generate_loaders(osversion, radioversion, radios, cappath, localdir) # Remove .signed files if signed: print("\nREMOVING .signed FILES...") for file in os.listdir(localdir): if os.path.join(localdir, file).endswith(".signed"): print("REMOVING: " + file) os.remove(os.path.join(localdir, file)) # If compression = true, compress if compressed: print("\nCOMPRESSING...") barutils.compress(localdir, compmethod, szexe) else: pass # Move zipped/unzipped loaders print("\nMOVING...") barutils.move_loaders(localdir, loaderdir_os, loaderdir_radio, zipdir_os, zipdir_radio) # Get hashes (if specified) if hashed: print("\nHASHING LOADERS...") print( "ADLER32:", adler32, "CRC32:", crc32, "MD4:", md4, "\nMD5:", md5, "SHA1:", sha1, "SHA224:", sha224, "\nSHA256:", sha256, "SHA384:", sha384, "SHA512:", sha512, "\nRIPEMD160:", ripemd160, "WHIRLPOOL:", whirlpool, "\n") blocksize = 32 * 1024 * 1024 if compressed: hashwrapper.verifier( zipdir_os, blocksize, crc32, adler32, sha1, sha224, sha256, sha384, sha512, md5, md4, ripemd160, whirlpool) if radios: hashwrapper.verifier( zipdir_radio, blocksize, crc32, adler32, sha1, sha224, sha256, sha384, sha512, md5, md4, ripemd160, whirlpool) if not deleted: hashwrapper.verifier( loaderdir_os, blocksize, crc32, adler32, sha1, sha224, sha256, sha384, sha512, md5, md4, ripemd160, whirlpool) if radios: hashwrapper.verifier( loaderdir_radio, blocksize, crc32, adler32, sha1, sha224, sha256, sha384, sha512, md5, md4, ripemd160, whirlpool) # Remove uncompressed loaders (if specified) if deleted: print("\nDELETING UNCOMPRESSED LOADERS...") shutil.rmtree(loaderdir) # Delete empty folders print("\nREMOVING EMPTY FOLDERS...") barutils.remove_empty_folders(localdir) print("\nFINISHED!") endtime = time.clock() - starttime endtime_proper = math.ceil(endtime * 100) / 100 print("\nCompleted in " + str(endtime_proper) + " seconds\n")