def import_apks(apk_paths): apk_importer = ApkImporter(apk_paths, storage) for apk in apk_importer.import_apks(copy_apk = copy_apk, copy_to_mongodb = copy_to_mongodb, update = update, tag = tag): clilog.info("imported %s", apk.short_description()) # use shared memory counter if given if cnt_imported_apks is not None: with cnt_imported_apks.get_lock(): cnt_imported_apks.value += 1
def get_apks_or_paths_from_cli(self, **kwargs): ''' Returns either list<str> (paths to apks) or list<Apk> if taken from import database. Returns as second component if list is of type `Apk` or not. For additional keyword-arguments see :py:meth:`.ImportStorageInterface.get_imported_apks`. ''' from androlyze.loader.ApkImporter import ApkImporter args = self.args # apk paths supplied ? apk_paths = None try: apk_paths = args.apks except AttributeError: pass filter_args = CLIUtil.get_filter_options_from_cli(args) hashes, package_names, tags = filter_args res = None if apk_paths is not None: # list<str> res = ApkImporter.get_apks_from_list_or_dir(apk_paths) else: # list<Apk> res = self.storage.get_imported_apks(hashes, package_names, tags, **kwargs) return res, apk_paths is None
def action_import_apks(storage, apk_paths, copy_apk = False, copy_to_mongodb = False, update = False, tag = None, # shared memory cnt_imported_apks = None, total_apk_count = None, import_finished = None, # concurrent settings concurrency = None ): ''' Import the apks from the `apk_paths` and create the file system structure where the results will be kept, specified by `storage`. Parameters ---------- storage : RedundantStorage The store to use. apk_paths : iterable<str> The apk files and/or directories. copy_apk : bool Import the apk file to the `import_dir` (copy it). copy_to_mongodb : bool, optional (default is False) Also import into MongoDB. Useful for the distributed analysis. update : bool Update apks that have already been imported. tag : str, optional (default is None) Some tag cnt_imported_apks : multiprocessing.Value<int>, optional (default is None) If given, use for progress updating. total_apk_count : multiprocessing.Value<int>, optional (default is None) If given, use for total count of apks. import_finished : multiprocessing.Value<byte>, optional (default is None) If given, use to signal that import has been completed. concurrency : int, optional (default is number of cpus) Number of processes to use for the import. ''' from androlyze.loader.ApkImporter import ApkImporter # get single paths to apks so we get the correct total count of apks clilog.info("looking for apks in given paths ... ") apk_paths = ApkImporter.get_apks_from_list_or_dir(apk_paths) if total_apk_count is not None: # may be time consuming for recursive lookup apk_paths, total_apk_count.value = Util.count_iterable_n_clone(apk_paths) # create count if not given if cnt_imported_apks is None: cnt_imported_apks = Value('i', 0, lock = RLock()) # set concurrency if concurrency is None: concurrency = cpu_count() log.warn("Using %d processes", concurrency) clilog.info("Storage dir is %s" % storage.fs_storage.store_root_dir) if copy_apk: clilog.info("Copying APKs to %s ..." % storage.fs_storage.store_root_dir) def import_apks(apk_paths): apk_importer = ApkImporter(apk_paths, storage) for apk in apk_importer.import_apks(copy_apk = copy_apk, copy_to_mongodb = copy_to_mongodb, update = update, tag = tag): clilog.info("imported %s", apk.short_description()) # use shared memory counter if given if cnt_imported_apks is not None: with cnt_imported_apks.get_lock(): cnt_imported_apks.value += 1 pool = [] # don't convert generator to list if only 1 process wanted apk_paths = [apk_paths] if concurrency == 1 else Util.split_n_uniform_distri(list(apk_paths), concurrency) # start parallel import # multiprocessing's pool causes pickle errors for i in range(concurrency): p = Process(target = import_apks, args = (apk_paths[i], )) log.debug("starting process %s", p) pool.append(p) p.start() for it in pool: log.debug("joined on process %s", p) it.join() apks_imported = cnt_imported_apks.value != 0 # show some message that no APK has been imported if not apks_imported: log.warn("No .apk file has been imported! This means no .apk file has been found or they already have been imported.") else: clilog.info("done") # because not all apks may be importable, we cannot use we count for signal that the import is done if import_finished is not None: import_finished.value = 1 clilog.info("Imported %d apks", cnt_imported_apks.value)