From 374d676cd489a03e16a7e3b6ad28e8f86f7b2858 Mon Sep 17 00:00:00 2001 From: Mike Hendricks Date: Thu, 4 Aug 2022 22:38:14 -0700 Subject: [PATCH] Fix formatting issues by running black, flake8 and pre-commit --- casement/cli.py | 26 ++--- casement/shortcut.py | 146 ++++++++++++------------ docs/Makefile | 2 +- docs/source/_templates/breadcrumbs.html | 2 +- docs/source/conf.py | 75 ++++++------ docs/source/index.rst | 2 +- 6 files changed, 124 insertions(+), 129 deletions(-) diff --git a/casement/cli.py b/casement/cli.py index 7fdd1c3..4e738da 100644 --- a/casement/cli.py +++ b/casement/cli.py @@ -6,9 +6,9 @@ class CasementParser(object): ''' - To implement a cli for casement, create a submodule with the name of your cli command. - For example to add a ``casement test echo`` command, you would create casement\test.py - with the following code:: + To implement a cli for casement, create a submodule with the name of your + cli command. For example to add a ``casement test echo`` command, you would + create casement\test.py with the following code:: import argparse from argparse import ArgumentParser @@ -25,25 +25,25 @@ def __init__(self, args): getattr(self, args.command)() def echo(self): - """ Creates a ArgumentParser to handle the echo command as self.parser """ + """Creates a ArgumentParser to handle the echo command as self.parser""" self.parser = ArgumentParser( usage='casement shortcut test [-h] [-v] text', ) self.parser.add_argument('text', nargs=argparse.REMAINDER) def run(self, args): - """ Do something with the arguments parsed from self.parser """ + """Do something with the arguments parsed from self.parser""" if args.command == 'echo': print('ECHO: {}'.format(' '.join(args.text))) ''' + def __init__(self): self.target_cli = None self._base_parser = ArgumentParser( description='Windows management tool', usage="casement []\n\n" - "Valid commands are:\n" - " shortcut or sc: Manage windows shortcuts." - + "Valid commands are:\n" + " shortcut or sc: Manage windows shortcuts.", ) self._base_parser.add_argument('command', help='Command to run') args = self._base_parser.parse_args(sys.argv[1:2]) @@ -71,14 +71,11 @@ def __init__(self): break else: self.target_cli.parser.add_argument( - '-v', - '--verbose', - action='store_true', - help='Give more output.' + '-v', '--verbose', action='store_true', help='Give more output.' ) def parse_args(self): - """ Parse sub-command arguments adding global options. """ + """Parse sub-command arguments adding global options.""" args = self.target_cli.parser.parse_args(self.args_list) # Add command to the args from the target_cli try: @@ -92,8 +89,7 @@ def main(): casement = CasementParser() args = casement.parse_args() logging.basicConfig( - format='%(message)s', - level=logging.DEBUG if args.verbose else logging.INFO + format='%(message)s', level=logging.DEBUG if args.verbose else logging.INFO ) casement.target_cli.run(args) diff --git a/casement/shortcut.py b/casement/shortcut.py index 761f726..07eb1b9 100644 --- a/casement/shortcut.py +++ b/casement/shortcut.py @@ -1,4 +1,4 @@ -""" A interface for manipulating Windows shortcut files including pinned. +r"""A interface for manipulating Windows shortcut files including pinned. Pinning shortcuts to the start menu and task bar in windows is extremely complicated. You can find and edit shortcuts in the User Pinned directory for for all users, but @@ -41,19 +41,20 @@ **Command line interface** -The features of this class can be used from the command line using ``casement shortcut -[command] [arguments]``. +The features of this class can be used from the command line using ``casement +shortcut [command] [arguments]``. To find shortcuts in common places with a given name:: C:\\blur\dev\\casement>casement shortcut list "VLC media player.lnk" - c:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\VideoLAN\\VLC media player.lnk + c:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\VideoLAN\\ + VLC media player.lnk c:\\Users\\Public\\Desktop\\VLC media player.lnk Pinning/unpinning a shortcut to the taskbar :: - C:\\blur\\dev\\casement>casement shortcut pin "C:\\Users\\Public\\Desktop\\My Shortcut.lnk" -t - C:\\blur\\dev\\casement>casement shortcut unpin "C:\\Users\\Public\\Desktop\\My Shortcut.lnk" -t + C:\>casement shortcut pin "C:\\Users\\Public\\Desktop\\My Shortcut.lnk" -t + C:\>casement shortcut unpin "C:\\Users\\Public\\Desktop\\My Shortcut.lnk" -t """ import os @@ -69,11 +70,11 @@ class Shortcut(object): default_paths = ( - r'{mount}\Users\*\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar', - r'{mount}\Users\*\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu', - r'{mount}\Users\*\AppData\Roaming\Microsoft\Windows\Start Menu\Programs', - r'{mount}\ProgramData\Microsoft\Windows\Start Menu\Programs\*', - r'{mount}\Users\*\Desktop', + '{mount}\\Users\\*\\AppData\\Roaming\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar', # noqa: B950 + '{mount}\\Users\\*\\AppData\\Roaming\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\StartMenu', # noqa: B950 + '{mount}\\Users\\*\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs', + '{mount}\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\*', + '{mount}\\Users\\*\\Desktop', ) """ Paths the find_shortcuts classmethod searches by default. """ @@ -87,8 +88,7 @@ def __init__(self, filename): self._exists() def __enter__(self): - """ If a shortcut can't be pinned, copy it locally while inside this context - """ + """If a shortcut can't be pinned, copy it locally while inside this context""" self._dirname_backup = None try: start_menu, taskbar = self.is_pinned() @@ -105,8 +105,7 @@ def __enter__(self): return self def __exit__(self, type, value, traceback): - """ Remove the tempfile and restore the dirname - """ + """Remove the tempfile and restore the dirname""" if self._dirname_backup is not None: # If we copied the shortcut locally cleanup the temp files and reset shutil.rmtree(self.dirname) @@ -114,31 +113,30 @@ def __exit__(self, type, value, traceback): self._dirname_backup = None def _exists(self): - """ Raises a WindowsError if self.filename does not exist. - """ + """Raises a WindowsError if self.filename does not exist.""" if not os.path.isfile(self.filename): # We can't get the verb of a file that does not exist on disk. msg = 'No such file' raise WindowsError(errno.ENOENT, msg, self.filename) - def _run_verb(self, verbName): - """ Run the verb with this name. + def _run_verb(self, verb_name): + """Run the verb with this name. Args: - verbName (str): The exact name of the verb, including & symbols. + verb_name (str): The exact name of the verb, including & symbols. For example `Pin to Start Men&u`. Returns: bool: If the verb was found and run. """ for verb in self.file_verbs(): - if verb.Name == verbName: + if verb.Name == verb_name: verb.DoIt() return True return False def copy(self, target): - """ Copy this shortcut to/over the target. + """Copy this shortcut to/over the target. If target is a pinned shortcut for the current user, this will unpin the existing pinned shortcut if it exists, then pin ``self.filename`` to the @@ -182,13 +180,13 @@ def copy(self, target): @property def filename(self): - """ The source shortcut filename this class uses as its source. """ + """The source shortcut filename this class uses as its source.""" return os.path.join(self.dirname, self.basename) def file_verbs(self): - """ Iterator of the verbs windows exposes for filename. """ - objShell = win32com.client.Dispatch('Shell.Application') - folder = objShell.Namespace(self.dirname) + """Iterator of the verbs windows exposes for filename.""" + obj_shell = win32com.client.Dispatch('Shell.Application') + folder = obj_shell.Namespace(self.dirname) item = folder.ParseName(self.basename) # It's possible that the file was removed. self._exists() @@ -201,9 +199,9 @@ def find_shortcuts( link_name, mount='C:', paths=default_paths, - ignored_paths=default_ignored_paths + ignored_paths=default_ignored_paths, ): - """ Find shortcuts with a given name in known locations. + """Find shortcuts with a given name in known locations. Each path in paths and ignored_paths will have ``{mount=mount}`` str.formatted into it before checking for files. Mount can be used to search @@ -235,7 +233,7 @@ def find_shortcuts( return links, ignored def is_pinned(self): - """ Returns if the shortcut is currently pinned to the start_menu or taskbar + """Returns if the shortcut is currently pinned to the start_menu or taskbar for the current user. Returns: @@ -243,8 +241,8 @@ def is_pinned(self): taskbar (bool): If the shortcut is pinned to the taskbar. Raises: - WindowsError: If no pinning verbs were found for ``self.filename``, this error - is raised as ``errno.EPERM``. + WindowsError: If no pinning verbs were found for ``self.filename``, + this error is raised as ``errno.EPERM``. """ start_menu = None taskbar = None @@ -268,7 +266,7 @@ def is_pinned(self): return start_menu, taskbar def move(self, target): - """ Move this shortcut to/over the target. + """Move this shortcut to/over the target. If target is a pinned shortcut for the current user, this will unpin the existing pinned shortcut if it exists, then pin ``self.filename`` to the @@ -313,7 +311,7 @@ def move(self, target): @classmethod def path_in_pin_dir(cls, path, current_user=True): - """ Check if the provided path is in a pinned directory. + """Check if the provided path is in a pinned directory. Args: path (str): The file to check. @@ -327,6 +325,7 @@ def path_in_pin_dir(cls, path, current_user=True): only be modified for the current user. This can be suppressed by passing ``False`` to the current_user argument. """ + def normalize(path): return os.path.normcase(os.path.normpath(path)) @@ -337,10 +336,12 @@ def normalize(path): 'User Pinned', ) app_data = normalize(os.path.expandvars('%APPDATA%')) - pin_dir = normalize(os.path.join( - app_data, - pin_structure, - )) + pin_dir = normalize( + os.path.join( + app_data, + pin_structure, + ) + ) # path could be a filename or a dirname norm_dir = normalize(path) if norm_dir.endswith('.lnk'): @@ -355,7 +356,7 @@ def normalize(path): return is_start_menu, is_taskbar def pin_to_start_menu(self): - """ Pin to the start menu. If already pinned, nothing is done. + """Pin to the start menu. If already pinned, nothing is done. Returns: bool: If the pin verb was found and run. @@ -364,7 +365,7 @@ def pin_to_start_menu(self): return self._run_verb('Pin to Start Men&u') def pin_to_taskbar(self): - """ Pin to the taskbar. If already pinned, nothing is done. + """Pin to the taskbar. If already pinned, nothing is done. Returns: bool: If the pin verb was found and run. @@ -373,7 +374,7 @@ def pin_to_taskbar(self): return self._run_verb('Pin to Tas&kbar') def unpin_from_start_menu(self): - """ Un-Pin from the start menu. + """Un-Pin from the start menu. Returns: bool: If the pin verb was found and run. @@ -382,7 +383,7 @@ def unpin_from_start_menu(self): return self._run_verb('Unpin from Start Men&u') def unpin_from_taskbar(self): - """ Un-Pin from the taskbar. + """Un-Pin from the taskbar. Returns: bool: If the pin verb was found and run. @@ -397,13 +398,14 @@ def __init__(self, args=None): self._base_parser = ArgumentParser( description='Pretends to be git', usage="casement shortcut []\n\n" - "Valid commands are:\n" - " copy: Copy a shortcut to a new location.\n" - " list: Find all shortcuts in expected locations with a given name.\n" - " move: Rename a shortcut to a given file name and path.\n" - " pin: Pin the shortcut to the current user's start menu and taskbar\n" - " unpin: Un-Pin the shortcut to the current user's start menu and taskbar" - ) + "Valid commands are:\n" + " copy: Copy a shortcut to a new location.\n" + " list: Find all shortcuts in expected locations with a given name.\n" + " move: Rename a shortcut to a given file name and path.\n" + " pin: Pin the shortcut to the current user's start menu and taskbar\n" + " unpin: Un-Pin the shortcut to the current user's start menu and " + "taskbar", + ) self._base_parser.add_argument('command', help='Command to run') args = self._base_parser.parse_args(args) @@ -416,24 +418,20 @@ def __init__(self, args=None): getattr(self, args.command)() def copy(self): - """ Parse copy command line arguments """ + """Parse copy command line arguments""" self.parser = ArgumentParser( description='Copy the the shortcut to the given target. Removes the target ' 'if it already exists and is a file. If target is a pinned shortcut ' 'location, then target is un-pinned if needed and re-pinned.', usage='casement shortcut copy [-h] [-v] source target', ) + self.parser.add_argument('source', help='Full path of the shortcut to copy.') self.parser.add_argument( - 'source', - help='Full path of the shortcut to copy.' - ) - self.parser.add_argument( - 'target', - help='Directory or filename to copy source to.' + 'target', help='Directory or filename to copy source to.' ) def list(self): - """ Parse list command line arguments """ + """Parse list command line arguments""" self.parser = ArgumentParser( description='Find icons for the given icon name.', usage='casement shortcut list [-h] [-v] name', @@ -443,18 +441,18 @@ def list(self): 'name', help="A list of shortcuts with that name " "in known paths will be printed in this case. The --mount argument can " - "be used to find shortcuts on other file systems." + "be used to find shortcuts on other file systems.", ) self.parser.add_argument( '-m', '--mount', default='c:', help='Search all paths relative to this drive letter. Lets you specify a ' - 'remote share. Defaults to C:' + 'remote share. Defaults to C:', ) def move(self): - """ Parse move command line arguments """ + """Parse move command line arguments""" self.parser = ArgumentParser( description='Rename the shortcut to the given target. Removes the target ' 'if it already exists and is a file. If target is a pinned shortcut ' @@ -462,43 +460,39 @@ def move(self): 'command for details.', usage='casement shortcut move [-h] [-v] source target', ) + self.parser.add_argument('source', help='Full path of the shortcut to move.') self.parser.add_argument( - 'source', - help='Full path of the shortcut to move.' - ) - self.parser.add_argument( - 'target', - help='Directory or filename to move source to.' + 'target', help='Directory or filename to move source to.' ) def pin(self): - """ Parse pin command line arguments """ + """Parse pin command line arguments""" self.parser = ArgumentParser( - description="Pin or re-pin link to the current user's start menu or taskbar. " - "Re-pinning does not preserver order. The current pinned status is printed if " - "-s and -t are not passed.", + description="Pin or re-pin link to the current user's start menu or " + "taskbar. Re-pinning does not preserver order. The current pinned " + "status is printed if -s and -t are not passed.", usage='casement shortcut pin [-s] [-t] [-h] [-v] source', ) self.parser.add_argument( 'source', help="The full path to the shortcut. " - "For example C:\Users\Public\Desktop\Treegrunt.lnk." + "For example C:\\Users\\Public\\Desktop\\Treegrunt.lnk.", ) self.parser.add_argument( '-s', '--start-menu', action='store_true', - help="Update the current user's start menu." + help="Update the current user's start menu.", ) self.parser.add_argument( '-t', '--taskbar', action='store_true', - help="Update the current user's taskbar." + help="Update the current user's taskbar.", ) def unpin(self): - """ Parse unpin command line arguments """ + """Parse unpin command line arguments""" self.parser = ArgumentParser( description="Un-pin link from the current user's start menu.", usage='casement shortcut unpin [-h] [-v] source target', @@ -506,19 +500,19 @@ def unpin(self): self.parser.add_argument( 'source', help="The full path to the shortcut. " - "For example C:\Users\Public\Desktop\Treegrunt.lnk." + "For example C:\\Users\\Public\\Desktop\\Treegrunt.lnk.", ) self.parser.add_argument( '-s', '--start-menu', action='store_true', - help="Update the current user's start menu." + help="Update the current user's start menu.", ) self.parser.add_argument( '-t', '--taskbar', action='store_true', - help="Update the current user's taskbar." + help="Update the current user's taskbar.", ) def run(self, args): diff --git a/docs/Makefile b/docs/Makefile index 69fe55e..ba501f6 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -16,4 +16,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/_templates/breadcrumbs.html b/docs/source/_templates/breadcrumbs.html index 014f70d..f684e20 100644 --- a/docs/source/_templates/breadcrumbs.html +++ b/docs/source/_templates/breadcrumbs.html @@ -80,4 +80,4 @@ {% endif %}
- \ No newline at end of file + diff --git a/docs/source/conf.py b/docs/source/conf.py index b98d4e3..3bb9a69 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,10 +18,10 @@ # import os import sys -import re -sys.path.insert(0, os.path.abspath('../..')) +import distutils.core +from setuptools_scm import get_version -from codecs import open +sys.path.insert(0, os.path.abspath('../..')) # -- General configuration ------------------------------------------------ @@ -32,9 +32,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.mathjax', - 'sphinx.ext.napoleon'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.mathjax', 'sphinx.ext.napoleon'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -56,18 +54,28 @@ # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -# -# The short X.Y version. - -version_file = os.path.join(os.path.abspath('../..'), 'casement', '__init__.py') -with open(version_file, encoding='utf-8') as f: - txt = f.read() - __version__ = re.findall('__version__ = ("[\d.\w]+")', txt)[0] -version = __version__ +# Get the version information from distutils +setup_file = os.path.abspath('../../setup.py') +# To allow setuptools_scm to build properly by changing the working directory +# to the repo root. +cwd = os.getcwd() +try: + os.chdir(os.path.dirname(setup_file)) + + package = distutils.core.run_setup(setup_file, script_args=['--dry-run']) +finally: + # Restore the working directory to the original value. + os.chdir(cwd) + +# The short version +__version__ = get_version( + root=os.path.abspath("../.."), version_scheme="release-branch-semver" +) # The full version, including alpha/beta/rc tags. release = __version__ + # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # @@ -93,7 +101,8 @@ # a list of builtin themes. # -import sphinx_rtd_theme +import sphinx_rtd_theme # noqa: E402 + html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] @@ -125,11 +134,11 @@ # ] # } html_sidebars = { - '**': [ - 'localtoc.html', - 'relations.html', - 'searchbox.html', - ] + '**': [ + 'localtoc.html', + 'relations.html', + 'searchbox.html', + ] } @@ -145,15 +154,12 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # 'preamble': '', - # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -163,8 +169,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'casement.tex', u'casement Documentation', - u'Blur Studio', 'manual'), + (master_doc, 'casement.tex', u'casement Documentation', u'Blur Studio', 'manual'), ] @@ -172,10 +177,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'casement', u'casement Documentation', - [author], 1) -] +man_pages = [(master_doc, 'casement', u'casement Documentation', [author], 1)] # -- Options for Texinfo output ------------------------------------------- @@ -184,10 +186,13 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'casement', u'casement Documentation', - author, 'casement', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + 'casement', + u'casement Documentation', + author, + 'casement', + 'One line description of project.', + 'Miscellaneous', + ), ] - - - diff --git a/docs/source/index.rst b/docs/source/index.rst index 9cfae05..0e766c1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -11,4 +11,4 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` \ No newline at end of file +* :ref:`search`