def unicode_find(needle_list): con = None try: parent_directory = os.path.split(os.path.dirname(__file__))[0] db_filepath = os.path.join(parent_directory, "glyphlist", "unicode.db") con = sqlite3.connect(db_filepath, isolation_level=None) cur = con.cursor() for needle in needle_list: cur.execute( "SELECT unicode, unishortname, unilongname FROM Unicodes WHERE unicode LIKE ?", (needle, )) result = cur.fetchone() if result is not None: if len(result[1]) > 0: result_string = result[0] + "\t" + result[ 1] + " '" + result[2] + "'" else: result_string = result[0] + "\t'" + result[2] + "'" stdout(result_string) else: stderr(needle + "\t" + "NOT FOUND") except Exception as e: stderr("[font-unicode]: Error: " + str(e), exit=1) finally: if con: con.close()
def pull_archive_runner(archive_url_dict): file_list = list(archive_url_dict) # the local outfile names in a list number_of_files = len(file_list) # the number of files included in the list if number_of_files > 0: if number_of_files > 1: # multiple binary file pull, each in separate process stdout("[*] doxx: Hang in there. Pulling " + str(number_of_files) + " entire file archives. This may take a bit of time...") processes = [] # list of spawned processes outputlock = Lock() # stdout / stderr writes lock iolock = Lock() # input/output lock # iterate through requested files and execute pull in separate process for each one for file_path in file_list: p = Process(target=_pull_archive_multiprocess, args=(file_path, archive_url_dict[file_path], outputlock, iolock)) p.start() processes.append(p) for process in processes: process.join(timeout=120) else: # single text file pull stdout("[*] doxx: Hang in there. Pulling the entire file archive. This may take a bit of time...") file_path = file_list[0] _pull_archive(file_path, archive_url_dict[file_path]) # file_path is local path for write, dictionary value is the URL else: stderr("[!] doxx: Unable to find archive files to pull in the key file", exit=0)
def name_find(name_list): con = None try: parent_directory = os.path.split(os.path.dirname(__file__))[0] db_filepath = os.path.join(parent_directory, "glyphlist", "unicode.db") con = sqlite3.connect(db_filepath, isolation_level=None) cur = con.cursor() for needle in name_list: modified_needle = "%" + needle + "%" cur.execute( "SELECT unicode, unishortname, unilongname FROM Unicodes WHERE unilongname LIKE ?", (modified_needle, )) result_list = cur.fetchall() if len(result_list) > 0: for result in result_list: stdout("'" + needle + "' ==> " + result[0] + " '" + result[2] + "'") else: stderr("[X] " + needle) except Exception as e: stderr("[font-unicode] Error: " + str(e), exit=1) finally: if con: con.close()
def unpack_and_get_keypath(self, project_path): # unpack the archive and get the root directory from the archive root_directory = unpack_run(project_path) if root_directory is None or root_directory == "": key_path = None try: for root, dirs, files in os.path.walk(cwd()): for test_file in files: if test_file == "project.yaml": key_path = make_path(root, dirs, test_file) except Exception as e: stderr("[!] doxx: Unable to locate the 'project.yaml' project settings file in your unpacked archive. Error: " + str(e), exit=1) if key_path is None: # can't find key path stderr("[!] doxx: Unable to locate the 'project.yaml' project settings file in your unpacked archive.", exit=1) else: return key_path # return key path to the calling method else: if root_directory == ".": key_path = 'project.yaml' # in current working directory else: # make the path to the key file root_directory = make_path(cwd(), root_directory) key_path = make_path(root_directory, 'project.yaml') # return the key path to the calling method return key_path
def _generate_tar(dir_path): """Private function that reads a local directory and generates a tar archive from it""" try: with tarfile.open(dir_path + '.tar', 'w') as tar: tar.add(dir_path) except tarfile.TarError as e: stderr("Error: tar archive creation failed [" + str(e) + "]", exit=1)
def _pull_archive_multiprocess(file_path, url, outputlock, iolock): """executes multi-process archive file pulls with I/O and stdout/stderr locks (private function)""" # create OS dependent file path (if necessary) file_path = _make_os_dependent_path(file_path) # make directory structure if necessary for the file path if os.path.dirname(file_path) is not "": iolock.acquire() _create_dirs(file_path) iolock.release() # pull the file and write to local filesystem try: pull_archive_file(url, file_path) except Exception as e: outputlock.acquire() stderr("[!] doxx: Unable to pull the archive file from the URL '" + url + "'. Error: " + str(e), exit=1) outputlock.release() if file_exists(file_path): root_dir = unpack_run(file_path) remove(file_path) outputlock.acquire() stdout("[+] doxx: '" + root_dir + "' ...check!") outputlock.release() else: outputlock.acquire() stderr("[!] doxx: There was an error pulling the repository file. Error: Unable to locate local archive file.", exit=1) outputlock.release()
def run_whatis(package_name): cache = DoxxCache() max_cache_seconds = 86400 # 24 hour file cache (same as search module) stdout("[*] doxx: Looking up the package description...") if cache.cached_file_exists('packages.json'): # does the cached file already exist if cache.does_cache_file_require_update(cache.package_repo_json_file, max_cache_seconds): # if so, has the cache time elapsed? master_descriptions = _pull_official_repository_descriptions() # pull new file cache.cache_packagerepo_json(master_descriptions) # push it into the file cache else: master_descriptions = cache.get_cached_packagerepo_json() # get the cached file if there is no need to pull a new version else: master_descriptions = _pull_official_repository_descriptions() # doesn't exist, go get it cache.cache_packagerepo_json(master_descriptions) # try to cache it if len(master_descriptions) > 0: # dictionary from JSON that contains the package descriptions by package name key descriptions_dict = json.loads(master_descriptions) test_package_name = package_name.lower().strip() if test_package_name in descriptions_dict: stdout(" ") stdout(" Package: " + test_package_name) stdout("Description: " + descriptions_dict[test_package_name]) else: stderr("[!] doxx: Unable to locate the package '" + test_package_name + "'", exit=1) else: stderr("[!] doxx: Unable to read the descriptions file. It appears to be empty...", exit=1)
def unpack_run(file_path): if tarfile.is_tarfile(file_path): return unpack_targz_archive_file(file_path) # returns the root directory from the unpack function below elif zipfile.is_zipfile(file_path): return unpack_zip_archive_file(file_path) # returns the root directory from the unpack function below else: stderr("[!] doxx: '" + file_path + "' does not appear to be a supported project archive type. Please review the project archive documentation and try again.", exit=1)
def make_template(self, outpath): try: fw = FileWriter(outpath) fw.write(template_stub) if file_exists(outpath): stdout("[+] doxx: The template stub '" + outpath + "' is now available in the current directory.") except Exception as e: stderr("[!] doxx: Unable to write the template stub to disk. Error: " + str(e), exit=1)
def _pull_official_repository_json(): package = OfficialPackage() master_package_json_url = package.get_master_package_description_json_url() http = HTTP(master_package_json_url) try: if http.get_status_ok(): master_list = http.res.text return master_list.strip() # strip additional spaces, blank end lines off of the list else: stderr("[!] Unable to pull the remote repository package descriptions (HTTP status code: " + str(http.res.status_code) + ")", exit=1) except Exception as e: stderr("[!] doxx: Unable to pull the remote repository package descriptions. Error: " + str(e), exit=1)
def setUp(self): self.pre_tardir_path = "testdir9/tar_dir" self.post_tardir_path = "testdir9/tar_dir.tar" self.pre_tardir2_path = "testdir9/tar_dir_two" self.post_tardir2_path = "testdir9/tar_dir_two.tar" self.pre_tardir_file_path = "testdir9/tar_dir/test.txt" self.pre_tardir2_file_path = "testdir9/tar_dir_two/test.txt" self.testdir_good_list = [self.pre_tardir_path] self.testdir_good_multidir_list = [ self.pre_tardir_path, self.pre_tardir2_path ] self.delete_files = [ 'testdir9/tar_dir.tar.crypt', 'testdir9/tar_dir_two.tar.crypt', 'testdir9/nontar.txt.crypt' ] if not dir_exists(self.pre_tardir_path): stderr( "missing test directory for the CryptoTarArchiveTest in test_tar-archive.py test module", exit=1) if not file_exists(self.pre_tardir_file_path): stderr( "missing test file for the CryptoTarArchiveTest in the test_tar-archive.py test module", exit=1) if not dir_exists(self.pre_tardir2_path): stderr( "missing test directory for the CryptoTarArchiveTest in test_tar-archive.py test module", exit=1) if not file_exists(self.pre_tardir2_file_path): stderr( "missing test file for the CryptoTarArchiveTest in the test_tar-archive.py test module", exit=1) # cleanup files from old tests if still around if file_exists(self.post_tardir_path): os.remove(self.post_tardir_path) if file_exists(self.post_tardir2_path): os.remove(self.post_tardir2_path) if file_exists(self.post_tardir_path) or file_exists( self.post_tardir2_path): stderr( "unable to delete testfile in setup for CryptoTarArchiveTest in the test_tar-archive.py test module", exit=1) # remove previously generated encrypted files if still around for the_encypted_file in self.delete_files: if file_exists(the_encypted_file): os.remove(the_encypted_file)
def write_project_runner_key(self, project_key_path): key_data_string = "\n\n" # maintain a couple of newlines between the build specification section and the key data section if len(self.key_data) > 0: for the_key in self.key_data: key_data_string = key_data_string + the_key + ": " + self.key_data[the_key] + "\n" # recreate the YAML from the local key.yaml file to append to the project.yaml file # if there is no key data, not necessary to write any additional data to the file. when doxx key is instantiated it will handle the lack of replacement data # append the local key file ('key.yaml') key data to the project meta data to prepare for the build try: fw = FileWriter(project_key_path) fw.append(key_data_string) # append local key data to the project.yaml file except Exception as e: stderr("[!] doxx: Unable to write the temporary key file for your project build. Error: " + str(e), exit=1)
def tar_gzip_package_directory(archive_name, root_dir): try: current_dir = os.getcwd() archive_gz_name = archive_name + ".tar.gz" tar = tarfile.open(archive_gz_name, mode="w:gz", compresslevel=9) # file writes to current working directory os.chdir(root_dir) # navigate to the root directory to add the files to the archive tar.add(".") # make tar.gz archive tar.close() os.chdir(current_dir) # navigate back to user's current working directory except Exception as e: os.chdir(current_dir) # if exception was raised, make sure that user is back in their current working directory before raising system exit tar.close() stderr("[!] doxx: Unable to pack the directory '" + root_dir + "'. Error: " + str(e))
def _pull_official_repository_descriptions(): package = OfficialPackage() master_package_descriptions = package.get_master_package_description_json_url() http = HTTP(master_package_descriptions) try: if http.get_status_ok(): master_descriptions = http.res.text return master_descriptions.strip() else: stderr("[!] doxx: Unable to pull remote repository descriptions (HTTP status code: " + str(http.res.status_code) + ")", exit=1) except Exception as e: stderr("[!] doxx: Unable to pull remote repository descriptions Error: " + str(e) + ")", exit=1)
def run(self): tox_found = False for i in range(self.number_of_dir_levels): if not self._is_tox_ini_at_this_level(): os.chdir(os.pardir) else: tox_found = True self._run_tox() break if not tox_found: stderr("Unable to locate your tox.ini file. Please navigate to your project directory.", 1) else: exit_success()
def run(self, command): setuppy_found = False for i in range(6): # navigate up at most 4 directory levels to search for the setup.py file if not self._is_setup_py_at_this_level(): os.chdir(os.pardir) else: setuppy_found = True self._run_dist_command(command) break if not setuppy_found: stderr("Unable to locate the setup.py file for your project. Please confirm that you are in your project directory and try again.", 1) else: exit_success()
def generate_tar_files(directory_list): """Public function that reads a list of local directories and generates tar archives from them""" tar_file_list = [] for directory in directory_list: if dir_exists(directory): _generate_tar(directory) # create the tar archive tar_file_list.append(directory + '.tar') # append the tar archive filename to the returned tar_file_list list else: stderr("The directory '" + directory + "' does not exist and a tar archive could not be created from it.", exit=1) return tar_file_list
def run(self): py_found = False for i in range(self.number_of_dir_levels): if not self._is_testdir_at_this_level(): os.chdir(os.pardir) else: py_found = True self._run_pytests() break if not py_found: stderr("Unable to locate your testing directory", 1) else: exit_success()
def _display_location(self): if self.needle == 'main': main_path = os.path.join('<PROJECT>', 'lib', '<PROJECT>', 'app.py') print("app.py : " + main_path) exit_success() elif self.needle == "settings": settings_path = os.path.join('<PROJECT>', 'lib', '<PROJECT>','settings.py') print("settings.py : " + settings_path) exit_success() elif self.needle == "setup": setup_path = os.path.join('<PROJECT>', 'setup.py') print("setup.py : " + setup_path) exit_success() else: stderr("Unable to process the command. Use 'naked locate help' for more information.", 1)
def _pull_binaryfile(file_path, url): """executes single process binary file pulls (private function)""" # create OS dependent file path (if necessary) file_path = _make_os_dependent_path(file_path) # make directory structure if necessary for the file path if os.path.dirname(file_path) is not "": _create_dirs(file_path) # pull the file and write to local filesystem try: pull_binary_file(url, file_path) except Exception as e: stderr("[!] doxx: Unable to pull '" + file_path + "' from '" + url + "'. Error: " + str(e), exit=0) if file_exists(file_path): stdout("[+] doxx: '" + file_path + "' ...check!") else: stderr("[!] doxx: There was an error pulling '" + file_path + "'. Error: Unable to locate local file.", exit=1)
def run(self): unit_found = False for i in range(self.number_of_dir_levels): if not self._is_testdir_at_this_level(): os.chdir(os.pardir) else: unit_found = True os.chdir('tests') if file_exists(self.unittest): self._run_unittest() else: stderr("The unit test file " + self.unittest + " could not be found in the tests directory.") if not unit_found: stderr("Unable to locate your testing directory", 1) else: exit_success()
def run(self): lib_found = False for i in range(self.number_of_dir_levels): if not self._is_lib_at_this_level(): os.chdir(os.pardir) else: lib_found = True break if lib_found: os.chdir('lib') # chdir to the lib directory if it is found if file_exists('profiler.py'): # confirm that profiler.py exists os.system('python profiler.py') # run the profiler.py file exit_success() else: stderr("Unable to locate a profiler.py file in your lib directory.", 1) else: stderr("Unable to locate your profiler.py file. Please navigate to your project directory.", 1)
def run(self, command): setuppy_found = False for i in range( 6 ): # navigate up at most 4 directory levels to search for the setup.py file if not self._is_setup_py_at_this_level(): os.chdir(os.pardir) else: setuppy_found = True self._run_dist_command(command) break if not setuppy_found: stderr( "Unable to locate the setup.py file for your project. Please confirm that you are in your project directory and try again.", 1) else: exit_success()
def generate_tar_files(directory_list): """Public function that reads a list of local directories and generates tar archives from them""" tar_file_list = [] for directory in directory_list: if dir_exists(directory): _generate_tar(directory) # create the tar archive tar_file_list.append( directory + '.tar' ) # append the tar archive filename to the returned tar_file_list list else: stderr( "The directory '" + directory + "' does not exist and a tar archive could not be created from it.", exit=1) return tar_file_list
def _display_location(self): if self.needle == 'main': main_path = os.path.join('<PROJECT>', 'lib', '<PROJECT>', 'app.py') print("app.py : " + main_path) exit_success() elif self.needle == "settings": settings_path = os.path.join('<PROJECT>', 'lib', '<PROJECT>', 'settings.py') print("settings.py : " + settings_path) exit_success() elif self.needle == "setup": setup_path = os.path.join('<PROJECT>', 'setup.py') print("setup.py : " + setup_path) exit_success() else: stderr( "Unable to process the command. Use 'naked locate help' for more information.", 1)
def package_zip(archive_name, root_directory): try: # attempt to import zlib for compression, fall back to default if not installed try: import zlib compression = zipfile.ZIP_DEFLATED except ImportError: compression = zipfile.ZIP_STORED archive_zip_name = archive_name + '.zip' archive_file_list = [] current_dir = os.getcwd() # change to the target directory if explicitly requested if root_directory is not ".": os.chdir(root_directory) for root, dirs, files in os.walk(os.getcwd()): for the_file in files: archive_file_list.append((os.path.relpath(os.path.join(root, the_file)))) zipper = zipfile.ZipFile(archive_zip_name, 'w') for zip_file in archive_file_list: # do not include OS X .DS_Store files in archives if os.path.basename(zip_file) == ".DS_Store": advance_progress() # advance the progress bar and do nothing (do not save these in archive) else: advance_progress() zipper.write(zip_file, compress_type=compression) zipper.close() # change to the original working directory if the directory was changed if root_directory is not ".": shutil.move(archive_zip_name, os.path.join(current_dir, archive_zip_name)) os.chdir(current_dir) except Exception as e: user_platform = platform.system() os.chdir(current_dir) zipper.close() if user_platform == "Windows": stderr("jampack: Unable to pack the directory '" + root_directory + "'. Error: " + str(e)) else: stderr( "[\033[31m!\033[0m] jampack: Unable to pack the directory '" + root_directory + "'. Error: " + str(e))
def unpack_targz_archive_file(targz_file_path): try: tar = tarfile.open(targz_file_path, "r:*") # define root directory in the tar archive to return to calling function x = 0 root_dir = None for tarinfo in tar: if x == 0: root_dir = tarinfo.name x += 1 else: break # unpack the archive tar.extractall() tar.close() # return the root directory to calling function return root_dir except Exception as e: stderr("[!] doxx: Unable to unpack the file '" + targz_file_path + "'. Error: " + str(e))
def zip_package_directory(archive_name, path): try: current_dir = os.getcwd() archive_name = archive_name + '.zip' archive_file_list = [] os.chdir(path) for root, dirs, files in os.walk(os.getcwd()): for the_file in files: archive_file_list.append((os.path.relpath(os.path.join(root, the_file)))) zipper = zipfile.ZipFile(archive_name, 'w') for zip_file in archive_file_list: zipper.write(zip_file) zipper.close() shutil.move(archive_name, os.path.join(current_dir, archive_name)) os.chdir(current_dir) except Exception as e: os.chdir(current_dir) zipper.close() stderr("[!] doxx: Unable to pack the directory '" + path + "'. Error: " + str(e))
def package_targz(archive_name, root_directory): try: if root_directory is not ".": current_dir = os.getcwd() os.chdir(root_directory) # navigate to the root directory to add the files to the archive archive_gz_name = archive_name + ".tar.gz" tar = tarfile.open(archive_gz_name, mode="w:gz", compresslevel=9) # file writes to current working directory tar.add(".", filter=exclude_files) # make tar.gz archive tar.close() if root_directory is not ".": shutil.move(archive_gz_name, os.path.join(current_dir, archive_gz_name)) # move file to working directory os.chdir(current_dir) # navigate back to user's current working directory except Exception as e: user_platform = platform.system() os.chdir(current_dir) tar.close() if user_platform == "Windows": stderr("jampack: Unable to pack the directory '" + root_directory + "'. Error: " + str(e)) else: stderr("[\033[31m!\033[0m] jampack: Unable to pack the directory '" + root_directory + "'. Error: " + str(e))
def run(self): lib_found = False for i in range(self.number_of_dir_levels): if not self._is_lib_at_this_level(): os.chdir(os.pardir) else: lib_found = True break if lib_found: os.chdir('lib') # chdir to the lib directory if it is found if file_exists('profiler.py'): # confirm that profiler.py exists os.system('python profiler.py') # run the profiler.py file exit_success() else: stderr( "Unable to locate a profiler.py file in your lib directory.", 1) else: stderr( "Unable to locate your profiler.py file. Please navigate to your project directory.", 1)
def _run_dist_command(self, the_command): if the_command in "register": print('•naked• Running register...') shell_run(self.register) elif the_command in "sdist": print('•naked• Running sdist...') shell_run(self.sdist) elif the_command in "wheel": print('•naked• Running wheel...') shell_run(self.wheel) elif the_command in "swheel": print('•naked• Running swheel...') shell_run(self.swheel) elif the_command in "win": print('•naked• Running win...') shell_run(self.win) elif the_command in "all": print('•naked• Running all...') shell_run(self.all) else: stderr("Unrecognized command. Use 'naked dist help' to view the supported commands.", 1)
def _remove_doxt(): # check main directory cwd_doxt_list = list_filter_files_cwd(".doxt") # check for a templates directory if dir_exists('templates'): templates_dir_doxt_list = list_filter_files(".doxt", "templates") else: templates_dir_doxt_list = [] # remove template files from the working directory if len(cwd_doxt_list) > 0: for doxt_file in cwd_doxt_list: try: remove(doxt_file) stdout("[-] doxx: -- " + doxt_file + " ... removed") except Exception as e: stderr("[!] doxx: Unable to remove the file " + doxt_file + "'. Error: " + str(e), exit=0) # remove any template files from the templates directory if len(templates_dir_doxt_list) > 0: for doxt_file in templates_dir_doxt_list: new_doxt_path = make_path('templates', doxt_file) remove(new_doxt_path) stdout("[-] doxx: -- " + new_doxt_path + " ... removed") # if there are files still remaining in the templates directory, leave it # otherwise, remove the templates directory as well if dir_exists('templates'): remaining_template_file_list = list_all_files('templates') # get the remaining non-.doxt files in the directory if len(remaining_template_file_list) > 0: pass # do nothing, skip the removal of the 'templates' directory from the project because other files are present in it else: try: rmtree('templates') stdout("[-] doxx: -- templates (directory) ... removed") except Exception as e: stderr("[!] doxx: Unable to remove the 'templates' directory. Error: " + str(e), exit=1)
def post_response(self): try: the_url = prepare_url(self.url) http = HTTP(the_url) http.post() resp = http.response() # confirm that a response was returned, abort if not if resp == None and the_url.startswith('https://'): stderr("Unable to connect to the requested URL. This can happen if the secure HTTP protocol is not supported at the requested URL.") sys.exit(1) elif resp == None: stderr("Unable to connect to the requested URL. Please confirm your URL and try again.") sys.exit(1) if len(resp.history) > 0: count = len(resp.history) for i in range(count): print(str(resp.history[i].status_code) + " : " + str(resp.history[i].url)) print(str(http.res.status_code) + " : " + the_url) exit_success() except ConnectionError as ce: error_string = "Unable to connect to the URL, " + self.url stderr(error_string, 1) except Exception as e: raise e
def post_response(self): try: the_url = prepare_url(self.url) http = HTTP(the_url) http.post() resp = http.response() # confirm that a response was returned, abort if not if resp == None and the_url.startswith('https://'): stderr( "Unable to connect to the requested URL. This can happen if the secure HTTP protocol is not supported at the requested URL." ) sys.exit(1) elif resp == None: stderr( "Unable to connect to the requested URL. Please confirm your URL and try again." ) sys.exit(1) if len(resp.history) > 0: count = len(resp.history) for i in range(count): print( str(resp.history[i].status_code) + " : " + str(resp.history[i].url)) print(str(http.res.status_code) + " : " + the_url) exit_success() except ConnectionError as ce: error_string = "Unable to connect to the URL, " + self.url stderr(error_string, 1) except Exception as e: raise e
def run(self): doxxkey = DoxxKey(self.key_path) # detect single vs multiple keys in the template and execute replacements with every requested template self.set_key_data(doxxkey) # assign key data from the doxx Key try: # are there text file(s) to pull? if so, do it if doxxkey.textfile_key is True: from doxx.datatypes.remotefiles import pull_textfile_runner pull_textfile_runner(doxxkey.meta_data['textfiles']) # are there binary files to pull? if so, do it if doxxkey.binaryfile_key is True: from doxx.datatypes.remotefiles import pull_binaryfile_runner pull_binaryfile_runner(doxxkey.meta_data['binaryfiles']) # are there archive files to pull? if so, do it if doxxkey.archives_key is True: from doxx.datatypes.remotefiles import pull_archive_runner pull_archive_runner(doxxkey.meta_data['archives']) # are there Github repository(ies) to pull? if so, do it if doxxkey.github_repo_key is True: from doxx.datatypes.remotefiles import pull_github_repo_runner pull_github_repo_runner(doxxkey.meta_data['github-repos']) # process templates/archive files if doxxkey.project_key is True: # the key is set to run on a local or remote project archive self.project_archive_run(doxxkey) elif doxxkey.multi_template_key is True: # the key is set to run on multiple local or remote template files multi_process_build(doxxkey, self.key_path) elif doxxkey.single_template_key is True: self.single_template_run(doxxkey.meta_data['template']) # the key is set to run on a single local or remote template file else: pass # no default condition except Exception as e: stderr("[!] doxx: Error: " + str(e), exit=1)
def _run_dist_command(self, the_command): if the_command in "register": print('•naked• Running register...') shell_run(self.register) elif the_command in "sdist": print('•naked• Running sdist...') shell_run(self.sdist) elif the_command in "wheel": print('•naked• Running wheel...') shell_run(self.wheel) elif the_command in "swheel": print('•naked• Running swheel...') shell_run(self.swheel) elif the_command in "win": print('•naked• Running win...') shell_run(self.win) elif the_command in "all": print('•naked• Running all...') shell_run(self.all) else: stderr( "Unrecognized command. Use 'naked dist help' to view the supported commands.", 1)
def name_find(name_list): con = None try: parent_directory = os.path.split(os.path.dirname(__file__))[0] db_filepath = os.path.join(parent_directory, "glyphlist", "unicode.db") con = sqlite3.connect(db_filepath, isolation_level=None) cur = con.cursor() for needle in name_list: modified_needle = "%" + needle + "%" cur.execute("SELECT unicode, unishortname, unilongname FROM Unicodes WHERE unilongname LIKE ?", (modified_needle,)) result_list = cur.fetchall() if len(result_list) > 0: for result in result_list: stdout("'" + needle + "' ==> " + result[0] + " '" + result[2] + "'") else: stderr("[X] " + needle) except Exception as e: stderr("[font-unicode] Error: " + str(e), exit=1) finally: if con: con.close()
def unpack_zip_archive_file(zip_file_path): try: zip_archive = zipfile.ZipFile(zip_file_path, 'r') # define root directory in the tar archive to return to calling function x = 0 root_dir = None for zipinfo in zip_archive.infolist(): if x == 0: root_dir = zipinfo.filename x += 1 else: break # extract the zip archive zip_archive.extractall() zip_archive.close() # if root_dir is actually a file name, then assume root dir is the CWD if '.' in root_dir: root_dir = "." # return the root directory in the zip archive return root_dir except Exception as e: stderr("[!] doxx: Unable to unpack the file '" + zip_file_path + "'. Error: " + str(e))
def _pull_binaryfile_multiprocess(file_path, url, outputlock, iolock): # create OS dependent file path (if necessary) file_path = _make_os_dependent_path(file_path) # make directory structure if necessary for the file path if os.path.dirname(file_path) is not "": iolock.acquire() _create_dirs(file_path) iolock.release() # pull the file and write to local filesystem try: pull_binary_file(url, file_path) except Exception as e: outputlock.acquire() stderr("[!] doxx: Unable to pull '" + file_path + "' from '" + url + "'. Error: " + str(e), exit=0) outputlock.release() if file_exists(file_path): outputlock.acquire() stdout("[+] doxx: '" + file_path + "' ...check!") outputlock.release() else: outputlock.acquire() stderr("[!] doxx: There was an error pulling '" + file_path + "'. Error: Unable to locate local file", exit=0) outputlock.release()
def encrypt_file(self, inpath, force_nocompress=False, force_compress=False, armored=False, checksum=False): """public method for single file encryption with optional compression, ASCII armored formatting, and file hash digest generation""" if armored: if force_compress: command_stub = self.command_maxcompress_armored elif force_nocompress: command_stub = self.command_nocompress_armored else: if self._is_compress_filetype(inpath): command_stub = self.command_default_armored else: command_stub = self.command_nocompress_armored else: if force_compress: command_stub = self.command_maxcompress elif force_nocompress: command_stub = self.command_nocompress else: if self._is_compress_filetype(inpath): command_stub = self.command_default else: command_stub = self.command_nocompress encrypted_outpath = self._create_outfilepath(inpath) system_command = command_stub + encrypted_outpath + " --passphrase " + quote( self.passphrase) + " --symmetric " + quote(inpath) try: response = muterun(system_command) # check returned status code if response.exitcode == 0: stdout(encrypted_outpath + " was generated from " + inpath) if checksum: # add a SHA256 hash digest of the encrypted file - requested by user --hash flag in command from crypto.library import hash encrypted_file_hash = hash.generate_hash(encrypted_outpath) if len(encrypted_file_hash) == 64: stdout("SHA256 hash digest for " + encrypted_outpath + " :") stdout(encrypted_file_hash) else: stdout( "Unable to generate a SHA256 hash digest for the file " + encrypted_outpath) else: stderr(response.stderr, 0) stderr("Encryption failed") sys.exit(1) except Exception as e: stderr( "There was a problem with the execution of gpg. Encryption failed. Error: [" + str(e) + "]") sys.exit(1)
def unicode_find(needle_list): con = None try: parent_directory = os.path.split(os.path.dirname(__file__))[0] db_filepath = os.path.join(parent_directory, "glyphlist", "unicode.db") con = sqlite3.connect(db_filepath, isolation_level=None) cur = con.cursor() for needle in needle_list: cur.execute("SELECT unicode, unishortname, unilongname FROM Unicodes WHERE unicode LIKE ?", (needle,)) result = cur.fetchone() if result is not None: if len(result[1]) > 0: result_string = result[0] + "\t" + result[1] + " '" + result[2] + "'" else: result_string = result[0] + "\t'" + result[2] + "'" stdout(result_string) else: stderr(needle + "\t" + "NOT FOUND") except Exception as e: stderr("[font-unicode]: Error: " + str(e), exit=1) finally: if con: con.close()
def pull_binaryfile_runner(binary_url_dict): """pulls remote binary files to local filesystem (public function)""" file_list = list(binary_url_dict) # the local outfile names in a list number_of_files = len(file_list) # the number of files included in the list if number_of_files > 0: if number_of_files > 1: # multiple binary file pull, each in separate process processes = [] # list of spawned processes outputlock = Lock() # stdout / stderr writes lock iolock = Lock() # input/output lock # iterate through requested files and execute pull in separate process for each one for file_path in file_list: p = Process(target=_pull_binaryfile_multiprocess, args=(file_path, binary_url_dict[file_path], outputlock, iolock)) p.start() processes.append(p) for process in processes: process.join(timeout=60) else: # single text file pull file_path = file_list[0] _pull_binaryfile(file_path, binary_url_dict[file_path]) # file_path is local path for write, dictionary value is the URL else: stderr("[!] doxx: Unable to find binary files to pull in the key file", exit=0)
def main(): import sys from Naked.commandline import Command #from Naked.toolshed.state import StateObject from Naked.toolshed.system import stderr #------------------------------------------------------------------------------------------ # [ Instantiate command line object ] # used for all subsequent conditional logic in the CLI application #------------------------------------------------------------------------------------------ c = Command(sys.argv[0], sys.argv[1:]) #------------------------------------------------------------------------------ # [ Instantiate state object ] #------------------------------------------------------------------------------ #state = StateObject() #------------------------------------------------------------------------------------------ # [ Command Suite Validation ] - early validation of appropriate command syntax # Test that user entered a primary command, print usage if not #------------------------------------------------------------------------------------------ if not c.command_suite_validates(): from Naked.commands.usage import Usage Usage().print_usage() sys.exit(1) #------------------------------------------------------------------------------------------ # [ PRIMARY COMMAND LOGIC ] # Test for primary commands and handle them #------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------ # [ args ] - identify the parsed arguments for a command string (2)= help #------------------------------------------------------------------------------ if c.cmd == "args": if c.cmd2 == "help": from Naked.commands.args import help as args_help args_help() elif c.argc > 0: # there is an argument to where that is not help from Naked.commands.args import Args a = Args(c.arg_to_cmd) a.run() else: stderr( "The args command requires an example command as an argument. Use 'naked args help' for more information.", 1) #------------------------------------------------------------------------------ # [ build ] - build the C code in the Naked library (2)= help #------------------------------------------------------------------------------ elif c.cmd == "build": if c.cmd2 == "help": from Naked.commands.build import help as build_help build_help() else: from Naked.commands.build import compile_c_code import os, inspect abs_dirpath = os.path.join( os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe()))), "toolshed", "c") compile_c_code(abs_dirpath) # function calls exit status code #------------------------------------------------------------------------------ # [ classify ] - search Python application classifiers and display to user (args)-search string #------------------------------------------------------------------------------ elif c.cmd == "classify": if c.cmd2 == "help": from Naked.commands.classifier import help as classifier_help classifier_help() else: if c.second: # if search string was given search_string = c.second else: search_string = "" # absence of search string detected in Classifier, defaults to the entire list instead of search from Naked.commands.classifier import Classifier c = Classifier(search_string) c.run() #------------------------------------------------------------------------------ # [ dist ] - distribute source files to PyPI (2)=register, sdist, swheel, wheel, win, all, help #------------------------------------------------------------------------------ elif c.cmd == "dist": if c.argc > 1: from Naked.commands.dist import Dist d = Dist() if c.cmd2 == "register": # python setup.py register d.run('register') elif c.cmd2 == "sdist": # python setup.py sdist upload d.run('sdist') elif c.cmd2 == "swheel": # python setup.py sdist bdist_wheel upload d.run('swheel') elif c.cmd2 == "wheel": # python setup.py bdist_wheel upload d.run('wheel') elif c.cmd2 == "win": # python setup.py bdist_wininst upload d.run('win') elif c.cmd2 == "all": # python setup.py sdist bdist_wheel bdist_wininst upload d.run('all') elif c.cmd2 == "help": # help for command from Naked.commands.dist import help as dist_help dist_help() else: stderr( "The naked dist secondary command was not recognized. Use 'naked dist help' for more information.", 1) else: stderr("Please enter a secondary command", 1) #------------------------------------------------------------------------------ # [ locate ] - locate Naked project files (2)= main, settings, setup, help #------------------------------------------------------------------------------ elif c.cmd == "locate": from Naked.commands.locate import Locator if c.cmd2 == "help": from Naked.commands.locate import help as locate_help locate_help() elif c.cmd2 == "main": l = Locator('main') elif c.cmd2 == "settings": l = Locator('settings') elif c.cmd2 == "setup": l = Locator('setup') else: l = Locator('') #handles error report to user #------------------------------------------------------------------------------ # [ make ] - make a new Naked project (2)=help (args)=project name #------------------------------------------------------------------------------ elif c.cmd == "make": from Naked.commands.make import MakeController if c.cmd2 == "help": from Naked.commands.make import help as make_help make_help() if c.arg1: # arg1 is not help so use it as the argument to the make command m = MakeController(c.arg1) else: m = MakeController(None) m.run() #------------------------------------------------------------------------------ # [ profile ] - run the profiler.py file in the Naked project (2)=help #------------------------------------------------------------------------------ elif c.cmd == "profile": if c.cmd2 == "help": from Naked.commands.profile import help as profile_help profile_help() else: from Naked.commands.profile import Profiler p = Profiler() p.run() #------------------------------------------------------------------------------ # [ pyh ] - help for python built-in library modules, classes, methods, functions #------------------------------------------------------------------------------ elif c.cmd == "pyh": if c.cmd2 == "help": from Naked.commands.pyh import pyh_help pyh_help() else: if c.argc > 1: from Naked.commands.pyh import python_help python_help(c.arg1) else: stderr( "Please enter a query term with the pyh command. Use 'naked pyh help' for more information.", 1) #------------------------------------------------------------------------------ # [ test ] - Run unit tests on the project (2)= help,nose,pytest,tox,unittest (see help for args) #------------------------------------------------------------------------------ elif c.cmd == "test": if c.argc > 1: if c.cmd2 == "help": from Naked.commands.test import help as tox_help tox_help() elif c.cmd2 == "nose": from Naked.commands.test import NoseTester n = NoseTester() n.run() elif c.cmd2 == "pytest": from Naked.commands.test import PyTester p = PyTester() p.run() elif c.cmd2 == "tox": from Naked.commands.test import ToxTester if c.arg2: #user specified a python version to run with one of the tox version defs t = ToxTester(c.arg2) #instantiate with the python version else: t = ToxTester() t.run() elif c.cmd2 == "unittest": from Naked.commands.test import UnitTester if c.arg2: t = UnitTester(c.arg2) t.run() else: stderr( "Please include a unit test file path. Use 'naked test help' for more information.", 1) else: stderr( "The secondary command was not recognized. Use 'naked test help' for more information.", 1) else: stderr( "Please include a secondary command with the 'naked test' command. Use 'naked dist help' for more information.", 1) #------------------------------------------------------------------------------------------ # [ NAKED FRAMEWORK COMMANDS ] # Naked framework provides default help, usage, and version commands for all applications # --> settings for user messages are assigned in the lib/PROJECT/settings.py file #------------------------------------------------------------------------------------------ elif c.help( ): # User requested naked help (help.py module in commands directory) from Naked.commands.help import Help Help().print_help() elif c.usage( ): # user requested naked usage info (usage.py module in commands directory) from Naked.commands.usage import Usage Usage().print_usage() elif c.version( ): # user requested naked version (version.py module in commands directory) from Naked.commands.version import Version Version().print_version() #------------------------------------------------------------------------------------------ # [ DEFAULT MESSAGE FOR MATCH FAILURE ] # Message to provide to the user when all above conditional logic fails to meet a true condition #------------------------------------------------------------------------------------------ else: print( "Could not complete the command that you entered. Please try again." ) sys.exit(1) #exit
def main(): import sys import getpass from Naked.commandline import Command from Naked.toolshed.shell import muterun from Naked.toolshed.system import dir_exists, directory, filename, file_exists, list_all_files, make_path, stdout, stderr #------------------------------------------------------------------------------------------ # [ Instantiate command line object ] # used for all subsequent conditional logic in the CLI application #------------------------------------------------------------------------------------------ c = Command(sys.argv[0], sys.argv[1:]) #------------------------------------------------------------------------------------------ # [ VALIDATION LOGIC ] - early validation of appropriate command syntax # Test that user entered at least one argument to the executable, print usage if not #------------------------------------------------------------------------------------------ if not c.command_suite_validates(): from crypto.settings import usage as crypto_usage print(crypto_usage) sys.exit(1) #------------------------------------------------------------------------------------------ # [ HELP, VERSION, USAGE LOGIC ] # Naked framework provides default help, usage, and version commands for all applications # --> settings for user messages are assigned in the lib/crypto/settings.py file #------------------------------------------------------------------------------------------ if c.help(): # User requested crypto help information from crypto.settings import help as crypto_help print(crypto_help) sys.exit(0) elif c.usage(): # User requested crypto usage information from crypto.settings import usage as crypto_usage print(crypto_usage) sys.exit(0) elif c.version(): # User requested crypto version information from crypto.settings import app_name, major_version, minor_version, patch_version version_display_string = app_name + ' ' + major_version + '.' + minor_version + '.' + patch_version print(version_display_string) sys.exit(0) #------------------------------------------------------------------------------------------ # [ APPLICATION LOGIC ] # #------------------------------------------------------------------------------------------ elif c.argc > 1: # code for multi-file processing and commands that include options ## ASCII ARMOR SWITCH ascii_armored = False if c.option('--armor') or c.option('-a'): ascii_armored = True ## MAX COMPRESS / COMPRESS ALL SWITCH max_compress = False if c.option('--space'): max_compress = True ## NO COMPRESSION SWITCH no_compress = False if c.option('--speed'): no_compress = True ## SECURE HASH DIGEST REPORT SWITCH report_checksum = False if c.option('--hash'): report_checksum = True path_list = [] # user entered paths from command line directory_list = [ ] # directory paths included in the user entered paths from the command line file_list = [ ] # file paths included in the user entered paths from the command line (and inside directories entered) # dot and .crypt file flags for exclusion testing contained_dot_file = False contained_crypt_file = False # determine if argument is an existing file or directory for argument in c.argv: if file_exists(argument): if argument.endswith( '.crypt'): # do not include previously encrypted files contained_crypt_file = True else: file_list.append( argument ) # add appropriate file paths to the file_list elif dir_exists(argument): directory_list.append( argument ) # if it is a directory, add path to the directory_list # add all file paths from user specified directories to the file_list if len(directory_list) > 0: for directory in directory_list: directory_file_list = list_all_files(directory) for contained_file in directory_file_list: if contained_file[0] == ".": contained_dot_file = True # change the flag + is not included in file_list intentionally (no dot files) elif contained_file.endswith('.crypt'): contained_crypt_file = True # change the flag + is not included in file_list intentionally (no previously encrypted files) else: # otherwise add to the list for encryption contained_file_path = make_path( directory, contained_file) file_list.append(contained_file_path) # confirm that there are files to be encrypted, if not warn user if len(file_list) == 0: if contained_dot_file == True or contained_crypt_file == True: stderr( "There were no files identified for encryption. crypto does not encrypt dot files or previously encrypted '.crypt' files." ) sys.exit(1) else: stderr("Unable to identify files for encryption") sys.exit(1) else: # file_list should contain all filepaths from either user specified file paths or contained in top level of directory, encrypt them passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") if passphrase == passphrase_confirm: from crypto.library.cryptor import Cryptor the_cryptor = Cryptor(passphrase) # run encryption based upon any passed switches if ascii_armored: if max_compress: the_cryptor.encrypt_files(file_list, force_nocompress=False, force_compress=True, armored=True, checksum=report_checksum) elif no_compress: the_cryptor.encrypt_files(file_list, force_nocompress=True, force_compress=False, armored=True, checksum=report_checksum) else: the_cryptor.encrypt_files(file_list, force_nocompress=False, force_compress=False, armored=True, checksum=report_checksum) else: if max_compress: the_cryptor.encrypt_files(file_list, force_nocompress=False, force_compress=True, armored=False, checksum=report_checksum) elif no_compress: the_cryptor.encrypt_files(file_list, force_nocompress=True, force_compress=False, armored=False, checksum=report_checksum) else: the_cryptor.encrypt_files(file_list, force_nocompress=False, force_compress=False, armored=False, checksum=report_checksum) # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" the_cryptor.cleanup() else: # passphrases did not match, report to user and abort # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) elif c.argc == 1: # simple single file or directory processing with default settings path = c.arg0 if file_exists(path): # it is a file, encrypt the single file with default settings # confirm that it is not already encrypted, abort if so if path.endswith('.crypt'): stderr( "You are attempting to encrypt an encrypted file. Please delete the .crypt file and repeat encryption with the original file if this is your intent." ) sys.exit(1) # if passes test above, obtain passphrase from the user passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") if passphrase == passphrase_confirm: from crypto.library.cryptor import Cryptor the_cryptor = Cryptor(passphrase) the_cryptor.encrypt_file(path) the_cryptor.cleanup() else: stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) elif dir_exists(path): # it is a directory, encrypt all top level files with default settings dirty_directory_file_list = list_all_files(path) # remove dot files and previously encrypted files (with .crypt suffix) from the list of directory files clean_directory_file_list = [ x for x in dirty_directory_file_list if x[0] != "." and x.endswith(".crypt") == False ] # remove dotfiles and .crypt files # confirm that there are still files in the list after the dot files and encrypted files are removed if len(clean_directory_file_list) == 0: stderr("There are no unencrypted files in the directory.") sys.exit(1) # create relative file paths for each file in the clean_directory_file_list clean_directory_file_list_relpaths = [] for clean_file in clean_directory_file_list: new_file_path = make_path(path, clean_file) clean_directory_file_list_relpaths.append(new_file_path) #prompt for the passphrase passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") if passphrase == passphrase_confirm: from crypto.library.cryptor import Cryptor the_cryptor = Cryptor(passphrase) the_cryptor.encrypt_files( clean_directory_file_list_relpaths ) #encrypt the list of directory files the_cryptor.cleanup() else: # passphrases do not match # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) else: # error message, not a file or directory. user entry error stderr( "The path that you entered does not appear to be an existing file or directory. Please try again." ) sys.exit(1) #------------------------------------------------------------------------------------------ # [ DEFAULT MESSAGE FOR MATCH FAILURE ] # Message to provide to the user when all above conditional logic fails to meet a true condition #------------------------------------------------------------------------------------------ else: print("Could not complete your request. Please try again.") sys.exit(1)
def main(): import sys from Naked.commandline import Command user_platform = platform.system() # ------------------------------------------------------------------------------------------ # [ Instantiate Naked framework command line object ] # used for all subsequent conditional logic in the CLI application # ------------------------------------------------------------------------------------------ c = Command(sys.argv[0], sys.argv[1:]) if not c.command_suite_validates(): from jampack.settings import usage as jampack_usage print(jampack_usage) sys.exit(1) if c.help(): # User requested jampack help information from jampack.settings import help as jampack_help print(jampack_help) sys.exit(0) elif c.usage(): # User requested jampack usage information from jampack.settings import usage as jampack_usage print(jampack_usage) sys.exit(0) elif c.version(): # User requested jampack version information from jampack.settings import app_name, major_version, minor_version, patch_version version_display_string = app_name + ' ' + major_version + '.' + minor_version + '.' + patch_version print(version_display_string) sys.exit(0) if c.argc > 0: # if there is an argument to the executable try: for archive_name in c.argv: lowercase_archive_name = archive_name.lower() if lowercase_archive_name.endswith('.zip'): if zipfile.is_zipfile(archive_name): zipper = zipfile.ZipFile(archive_name, mode="r") zipper.extractall() if user_platform == "Windows": stdout("'" + archive_name + "' was unpacked.") else: stdout("[\033[32m✓\033[0m] '" + archive_name + "' was unpacked.") else: if user_platform == "Windows": stderr("'" + archive_name + "' does not appear to be a zip file") else: stderr("[\033[31m!\033[0m] '" + archive_name + "' does not appear to be a zip file") elif lowercase_archive_name.endswith( '.tar.gz') or lowercase_archive_name.endswith( '.tgz') or lowercase_archive_name.endswith( '.tar.gzip'): if tarfile.is_tarfile(archive_name): tarball = tarfile.open(archive_name, mode="r:gz") tarball.extractall() if user_platform == "Windows": stdout("'" + archive_name + "' was unpacked.") else: stdout("[\033[32m✓\033[0m] '" + archive_name + "' was unpacked.") else: if user_platform == "Windows": stderr("'" + archive_name + "' does not appear to be a tar archive") else: stderr("[\033[31m!\033[0m] '" + archive_name + "' does not appear to be a tar archive") elif lowercase_archive_name.endswith( '.tar.bz2') or lowercase_archive_name.endswith( '.tar.bzip2'): if tarfile.is_tarfile(archive_name): bzball = tarfile.open(archive_name, mode="r:bz2") bzball.extractall() if user_platform == "Windows": stdout("'" + archive_name + "' was unpacked.") else: stdout("[\033[32m✓\033[0m] '" + archive_name + "' was unpacked.") else: if user_platform == "Windows": stderr("'" + archive_name + "' does not appear to be a tar archive") else: stderr("[\033[31m!\033[0m] '" + archive_name + "' does not appear to be a tar archive") else: if user_platform == "Windows": stderr( "Unable to identify the archive type for '" + archive_name + "'. This archive was not unpacked. Please check the file extension and try again." ) else: stderr( "[\033[31m!\033[0m] Unable to identify the archive type for '" + archive_name + "'. This archive was not unpacked. Please check the file extension and try again." ) except Exception as e: if user_platform == "Windows": stderr("Unable to unpack the archive '" + archive_name + "'. Error: " + str(e)) else: stderr("[\033[31m!\033[0m] Unable to unpack the archive '" + archive_name + "'. Error: " + str(e)) # ------------------------------------------------------------------------------------------ # [ DEFAULT MESSAGE FOR MATCH FAILURE ] # Message to provide to the user when all above conditional logic fails to meet a true condition # ------------------------------------------------------------------------------------------ else: if user_platform == "Windows": print( "Could not complete the command that you entered. Please try again." ) else: print( "[\033[31mX\033[0m] Could not complete the command that you entered. Please try again." ) sys.exit(1) # exit
def main(): from Naked.commandline import Command global PROGRESS_INDICATOR user_platform = platform.system() # ------------------------------------------------------------------------------------------ # [ Instantiate Naked framework command line object ] # used for all subsequent conditional logic in the CLI application # ------------------------------------------------------------------------------------------ c = Command(sys.argv[0], sys.argv[1:]) if c.help(): # User requested jampack help information from jampack.settings import help as jampack_help print(jampack_help) sys.exit(0) elif c.usage(): # User requested jampack usage information from jampack.settings import usage as jampack_usage print(jampack_usage) sys.exit(0) elif c.version(): # User requested jampack version information from jampack.settings import app_name, major_version, minor_version, patch_version version_display_string = app_name + ' ' + major_version + '.' + minor_version + '.' + patch_version print(version_display_string) sys.exit(0) # ------------------------------------------------------------------------------------------ # [ PRIMARY COMMAND LOGIC ] # ------------------------------------------------------------------------------------------ if c.argc == 0: # tar.gz pack the current working directory directory_name = os.path.basename(os.getcwd()) directory_size = get_directory_size(".") package_targz(directory_name, ".") archive_name = directory_name + ".tar.gz" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") sys.exit(0) elif c.argc > 0: if c.arg0 == "zip": if c.argc == 1: # zip pack the current working directory directory_name = os.path.basename(os.getcwd()) directory_size = get_directory_size(".") package_zip(directory_name, ".") archive_name = directory_name + ".zip" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") # end of the progress indicator if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") sys.exit(0) else: directory_list = c.argv[1:] for a_directory in directory_list: if os.path.isdir(a_directory): PROGRESS_INDICATOR = 1 # reset the progress indicator on each new archive that is processed directory_name = os.path.basename(a_directory) directory_size = get_directory_size(a_directory) package_zip(directory_name, a_directory) archive_name = directory_name + ".zip" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") # end of the progress indicator if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") else: if user_platform == "Windows": stderr(a_directory + " is not a directory path") else: stderr("[\033[31mX\033[0m] " + a_directory + " is not a directory path") sys.exit(0) elif c.arg0 == "bz2": if c.argc == 1: # bz2 pack the current working directory directory_name = os.path.basename(os.getcwd()) directory_size = get_directory_size(".") package_bzip2(directory_name, ".") archive_name = directory_name + ".tar.bz2" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") # end of the progress indicator if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") sys.exit(0) else: # bz2 pack one or more explicitly set directory directory_list = c.argv[1:] for a_directory in directory_list: if os.path.isdir(a_directory): PROGRESS_INDICATOR = 1 # reset the progress indicator on each new archive that is processed directory_name = os.path.basename(a_directory) directory_size = get_directory_size(a_directory) package_bzip2(directory_name, a_directory) archive_name = directory_name + ".tar.bz2" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") # end of the progress indicator if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") else: if user_platform == "Windows": stderr(a_directory + " is not a directory path") else: stderr("[\033[31mX\033[0m] " + a_directory + " is not a directory path") sys.exit(0) else: # tar.gz one or more explicitly defined directories for a_directory in c.argv: if os.path.isdir(a_directory): PROGRESS_INDICATOR = 1 # reset the progress indicator on each new archive that is processed directory_name = os.path.basename(a_directory) directory_size = get_directory_size(a_directory) package_targz(directory_name, a_directory) archive_name = directory_name + ".tar.gz" percent_filesize = (100 * (get_file_size(archive_name) / float(directory_size))) display_percent = str(int(percent_filesize)) stdout(" 100%") # end of the progress indicator if user_platform == "Windows": stdout(archive_name + " created " + "[~" + display_percent + "% original]") else: stdout("[\033[32m✓\033[0m] " + archive_name + " created " + "[~" + display_percent + "% original]") else: if user_platform == "Windows": stderr(a_directory + " is not a directory path") else: stderr("[\033[31mX\033[0m] " + a_directory + " is not a directory path") sys.exit(0) # ------------------------------------------------------------------------------------------ # [ DEFAULT MESSAGE FOR MATCH FAILURE ] # Message to provide to the user when all above conditional logic fails to meet a true condition # ------------------------------------------------------------------------------------------ else: if user_platform == "Windows": stdout("Could not complete the command that you entered. Please try again.") else: stdout("[\033[31mX\033[0m] Could not complete the command that you entered. Please try again.") sys.exit(1) # exit
def main(): import os import sys from time import sleep import getpass import tarfile from Naked.commandline import Command from Naked.toolshed.shell import execute, muterun from Naked.toolshed.system import dir_exists, file_exists, list_all_files, make_path, stdout, stderr, is_dir from shellescape import quote # ------------------------------------------------------------------------------------------ # [ Instantiate command line object ] # used for all subsequent conditional logic in the CLI application # ------------------------------------------------------------------------------------------ c = Command(sys.argv[0], sys.argv[1:]) # ------------------------------------------------------------------------------------------ # [ VALIDATION LOGIC ] - early validation of appropriate command syntax # Test that user entered at least one argument to the executable, print usage if not # ------------------------------------------------------------------------------------------ if not c.command_suite_validates(): from Crypto.settings import usage as crypto_usage print(crypto_usage) sys.exit(1) # ------------------------------------------------------------------------------------------ # [ HELP, VERSION, USAGE LOGIC ] # Naked framework provides default help, usage, and version commands for all applications # --> settings for user messages are assigned in the lib/Crypto/settings.py file # ------------------------------------------------------------------------------------------ if c.help(): # User requested Crypto help information from Crypto.settings import help as crypto_help print(crypto_help) sys.exit(0) elif c.usage(): # User requested Crypto usage information from Crypto.settings import usage as crypto_usage print(crypto_usage) sys.exit(0) elif c.version(): # User requested Crypto version information from Crypto.settings import app_name, major_version, minor_version, patch_version version_display_string = app_name + ' ' + major_version + '.' + minor_version + '.' + patch_version print(version_display_string) sys.exit(0) # ------------------------------------------------------------------------------------------ # [ APPLICATION LOGIC ] # # ------------------------------------------------------------------------------------------ elif c.argc > 1: # code for multi-file processing and commands that include options use_standard_output = False # print to stdout flag use_file_overwrite = False # overwrite existing file untar_archives = True # untar decrypted tar archives, true by default # set user option flags if c.option('--stdout') or c.option('-s'): use_standard_output = True if c.option('--overwrite') or c.option('-o'): use_file_overwrite = True if c.option('--nountar'): untar_archives = False directory_list = [ ] # directory paths included in the user entered paths from the command line file_list = [ ] # file paths included in the user entered paths from the command line (and inside directories entered) for argument in c.argv: if file_exists( argument ): # user included a file, add it to the file_list for decryption if argument.endswith('.crypt'): file_list.append( argument ) # add .crypt files to the list of files for decryption elif argument.endswith('.gpg'): file_list.append(argument) elif argument.endswith('.asc'): file_list.append(argument) elif argument.endswith('.pgp'): file_list.append(argument) else: # cannot identify as an encrypted file, give it a shot anyways but warn user file_list.append(argument) stdout( "Could not confirm that '" + argument + "' is encrypted based upon the file type. Attempting decryption. Keep your fingers crossed..." ) elif dir_exists( argument ): # user included a directory, add it to the directory_list directory_list.append(argument) else: if argument[0] == "-": pass # if it is an option, do nothing else: stderr( "'" + argument + "' does not appear to be an existing file or directory. Aborting decryption attempt for this request." ) # unroll the contained directory files into the file_list IF they are encrypted file types if len(directory_list) > 0: for directory in directory_list: directory_file_list = list_all_files(directory) for contained_file in directory_file_list: if contained_file.endswith('.crypt'): file_list.append( make_path(directory, contained_file) ) # include the file with a filepath 'directory path/contained_file path' elif contained_file.endswith('.gpg'): file_list.append(make_path(directory, contained_file)) elif contained_file.endswith('asc'): file_list.append(make_path(directory, contained_file)) elif contained_file.endswith('.pgp'): file_list.append(make_path(directory, contained_file)) # confirm that there are files for decryption, if not abort if len(file_list) == 0: stderr("Could not identify files for decryption") sys.exit(1) # get passphrase used to symmetrically decrypt the file passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") if passphrase == passphrase_confirm: # begin decryption of each requested file. the directory path was already added to the file path above for encrypted_file in file_list: # create the decrypted file name decrypted_filename = "" if encrypted_file.endswith('.crypt'): decrypted_filename = encrypted_file[0:-6] elif encrypted_file.endswith( '.gpg') or encrypted_file.endswith( '.asc') or encrypted_file.endswith('.pgp'): decrypted_filename = encrypted_file[0:-4] else: decrypted_filename = encrypted_file + '.decrypt' # if it was a file without a known encrypted file type, add the .decrypt suffix # determine whether file overwrite will take place with the decrypted file skip_file = False # flag that indicates this file should not be encrypted created_tmp_files = False if not use_standard_output: # if not writing a file, no need to check for overwrite if file_exists(decrypted_filename): if use_file_overwrite: # rename the existing file to temp file which will be erased or replaced (on decryption failures) below tmp_filename = decrypted_filename + '.tmp' os.rename(decrypted_filename, tmp_filename) created_tmp_files = True else: stdout( "The file path '" + decrypted_filename + "' already exists. This file was not decrypted." ) skip_file = True # begin decryption if not skip_file: if use_standard_output: # using --quiet flag to suppress stdout messages from gpg, just want the file data in stdout stream system_command = "gpg --batch --quiet --passphrase " + quote( passphrase) + " -d " + quote(encrypted_file) successful_execution = execute( system_command ) # use naked execute function to directly push to stdout, rather than return stdout if not successful_execution: stderr( "Unable to decrypt file '" + encrypted_file + "'", 0) if created_tmp_files: # restore the moved tmp file to original if decrypt failed tmp_filename = decrypted_filename + '.tmp' if file_exists(tmp_filename): os.rename(tmp_filename, decrypted_filename) else: # decryption successful but we are in stdout flag so do not include any other output from decrypto pass else: system_command = "gpg --batch -o " + quote( decrypted_filename) + " --passphrase " + quote( passphrase) + " -d " + quote(encrypted_file) response = muterun(system_command) if response.exitcode == 0: stdout("'" + encrypted_file + "' decrypted to '" + decrypted_filename + "'") else: # failed decryption if created_tmp_files: # restore the moved tmp file to original if decrypt failed tmp_filename = decrypted_filename + '.tmp' if file_exists(tmp_filename): os.rename(tmp_filename, decrypted_filename) # report the error stderr(response.stderr) stderr("Decryption failed for " + encrypted_file) # cleanup: remove the tmp file if created_tmp_files: tmp_filename = decrypted_filename + '.tmp' if file_exists(tmp_filename): os.remove(tmp_filename) # untar/extract any detected archive file(s) if untar_archives is True: if decrypted_filename.endswith( '.tar') and tarfile.is_tarfile(decrypted_filename): untar_path_tuple = os.path.split(decrypted_filename) untar_path = untar_path_tuple[0] if use_file_overwrite: with tarfile.open(decrypted_filename) as tar: if len(untar_path) > 0: tar.extractall( path=untar_path ) # use dir path from the decrypted_filename if not CWD stdout( "'" + decrypted_filename + "' unpacked in the directory path '" + untar_path + "'") else: tar.extractall() # else use CWD stdout( "'" + decrypted_filename + "' unpacked in the current working directory" ) else: with tarfile.TarFile(decrypted_filename, 'r', errorlevel=1) as tar: for tarinfo in tar: t_file = tarinfo.name if len(untar_path) > 0: t_file_path = os.path.join( untar_path, t_file) else: t_file_path = t_file if not os.path.exists(t_file_path): try: if len(untar_path) > 0: tar.extract( t_file, path=untar_path ) # write to the appropriate dir else: tar.extract( t_file) # write to CWD except IOError as e: stderr( "Failed to unpack the file '" + t_file_path + "' [" + str(e) + "]") elif is_dir(t_file_path): pass # do nothing if it exists and is a directory, no need to warn else: # it is a file and it already exists, provide user error message stderr( "Failed to unpack the file '" + t_file_path + "'. File already exists. Use the --overwrite flag to replace existing files." ) # remove the decrypted tar archive file os.remove(decrypted_filename) # overwrite the entered passphrases after file decryption is complete for all files passphrase = "" passphrase_confirm = "" # add a short pause to hinder brute force pexpect style password attacks with decrypto sleep(0.2) # 200ms pause else: # passphrases did not match passphrase = "" passphrase_confirm = "" stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) elif c.argc == 1: # simple single file or directory processing with default settings path = c.arg0 if file_exists(path): # SINGLE FILE check_existing_file = False # check for a file with the name of new decrypted filename in the directory if path.endswith('.crypt'): decrypted_filename = path[0:-6] # remove the .crypt suffix check_existing_file = True elif path.endswith('.gpg') or path.endswith( '.pgp') or path.endswith('.asc'): decrypted_filename = path[0:-4] check_existing_file = True else: decrypted_filename = path + ".decrypt" # if there is not a standard file type, then add a .decrypt suffix to the decrypted file name stdout( "Could not confirm that the requested file is encrypted based upon the file type. Attempting decryption. Keep your fingers crossed..." ) # confirm that the decrypted path does not already exist, if so abort with warning message to user if check_existing_file is True: if file_exists(decrypted_filename): stderr( "Your file will be decrypted to '" + decrypted_filename + "' and this file path already exists. Please move the file or use the --overwrite option with your command if you intend to replace the current file." ) sys.exit(1) # get passphrase used to symmetrically decrypt the file passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") # confirm that the passphrases match if passphrase == passphrase_confirm: system_command = "gpg --batch -o " + quote( decrypted_filename) + " --passphrase " + quote( passphrase) + " -d " + quote(path) response = muterun(system_command) if response.exitcode == 0: # unpack tar archive generated from the decryption, if present if decrypted_filename.endswith( '.tar') and tarfile.is_tarfile(decrypted_filename): untar_path_tuple = os.path.split(decrypted_filename) untar_path = untar_path_tuple[0] with tarfile.TarFile(decrypted_filename, 'r', errorlevel=1) as tar: for tarinfo in tar: t_file = tarinfo.name if len(untar_path) > 0: t_file_path = os.path.join( untar_path, t_file) else: t_file_path = t_file if not os.path.exists(t_file_path): try: if len(untar_path) > 0: tar.extract( t_file, path=untar_path ) # write to the appropriate dir else: tar.extract(t_file) # write to CWD except IOError as e: stderr("Failed to unpack the file '" + t_file_path + "' [" + str(e) + "]") elif is_dir(t_file_path): pass # do nothing if it exists and is a directory, no need to warn else: # it is a file and it already exists, provide user error message stderr( "Failed to unpack the file '" + t_file_path + "'. File already exists. Use the --overwrite flag to replace existing files." ) # remove the decrypted tar archive os.remove(decrypted_filename) stdout("Decryption complete") # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" sys.exit(0) else: stderr(response.stderr) stderr("Decryption failed") # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" # add a short pause to hinder brute force pexpect style password attacks with decrypto sleep(0.2) # 200ms pause sys.exit(1) else: stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) elif dir_exists(path): # SINGLE DIRECTORY dirty_directory_file_list = list_all_files(path) directory_file_list = [ x for x in dirty_directory_file_list if (x.endswith('.crypt') or x.endswith('.gpg') or x.endswith('.pgp') or x.endswith('.asc')) ] # if there are no encrypted files found, warn and abort if len(directory_file_list) == 0: stderr("There are no encrypted files in the directory") sys.exit(1) # prompt for the passphrase passphrase = getpass.getpass("Please enter your passphrase: ") if len(passphrase) == 0: # confirm that user entered a passphrase stderr( "You did not enter a passphrase. Please repeat your command and try again." ) sys.exit(1) passphrase_confirm = getpass.getpass( "Please enter your passphrase again: ") if passphrase == passphrase_confirm: # decrypt all of the encypted files in the directory for filepath in directory_file_list: absolute_filepath = make_path( path, filepath ) # combine the directory path and file name into absolute path # remove file suffix from the decrypted file path that writes to disk if absolute_filepath.endswith('.crypt'): decrypted_filepath = absolute_filepath[ 0:-6] # remove the .crypt suffix elif absolute_filepath.endswith( '.gpg') or absolute_filepath.endswith( '.pgp') or absolute_filepath.endswith('.asc'): decrypted_filepath = absolute_filepath[0:-4] # confirm that the file does not already exist if file_exists(decrypted_filepath): stdout( "The file path '" + decrypted_filepath + "' already exists. This file was not decrypted.") else: system_command = "gpg --batch -o " + quote( decrypted_filepath) + " --passphrase " + quote( passphrase) + " -d " + quote(absolute_filepath) response = muterun(system_command) if response.exitcode == 0: stdout("'" + absolute_filepath + "' decrypted to '" + decrypted_filepath + "'") else: stderr(response.stderr) stderr("Decryption failed for " + absolute_filepath) # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" # add a short pause to hinder brute force pexpect style password attacks with decrypto sleep(0.2) # 200ms pause else: # overwrite user entered passphrases passphrase = "" passphrase_confirm = "" stderr( "The passphrases did not match. Please enter your command again." ) sys.exit(1) else: # error message, not a file or directory. user entry error stderr( "The path that you entered does not appear to be an existing file or directory. Please try again." ) sys.exit(1) # ------------------------------------------------------------------------------------------ # [ DEFAULT MESSAGE FOR MATCH FAILURE ] # Message to provide to the user when all above conditional logic fails to meet a true condition # ------------------------------------------------------------------------------------------ else: print("Could not complete your request. Please try again.") sys.exit(1)