diff --git a/.DS_Store b/.DS_Store index c92a90d..d9def06 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/README.md b/README.md deleted file mode 100644 index ce7a09f..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -python work done in VM diff --git a/emoji-cmd/.gitignore b/emoji-cmd/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/emoji-cmd/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/emoji-cmd/LICENSE b/emoji-cmd/LICENSE new file mode 100644 index 0000000..e3b6c44 --- /dev/null +++ b/emoji-cmd/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 dtomlinson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/emoji-cmd/README.md b/emoji-cmd/README.md new file mode 100644 index 0000000..f4b871f --- /dev/null +++ b/emoji-cmd/README.md @@ -0,0 +1,106 @@ +# Emojis on the command line + + + +- [Author](#author) +- [Requires](#requires) +- [Python requirements:](#python-requirements) +- [Documentation](#documentation) +- [Installation](#installation) + * [Easy Way](#easy-way) + * [Python](#python) + + [From pip](#from-pip) + + [From local wheel](#from-local-wheel) + + [From source](#from-source) +- [Example Usage](#example-usage) + + + + +## Author + +Daniel Tomlinson + +## Requires + +`python3.7+` + +## Python requirements: + +``` +argparse 1.4.0 Python command-line parsing library +click 7.0 Composable command line interface toolkit +emojis 0.5.1 Emojis for Python +texttable 1.6.2 module for creating simple ASCII tables +``` + +## Documentation + +[Read the documentation](https://dtomlinson91.github.io/emoji-cmd/) + +## Installation + +### Easy Way + +Run `curl -LSs https://raw.githubusercontent.com/dtomlinson91/emoji-cmd/master/install.sh | bash` + +### Python + +#### From pip + +_coming soon_ + +#### From local wheel + +1. Create a local directory `mkdir python-applications` +1. Create a virtualenv `python3 -m venv emoji` +1. Activate the environment `source emoji/bin/activate` +1. Download latest `.whl` version from [releases](https://github.com/dtomlinson91/emoji-cmd/releases) and install `pip install emoji_cmd-1.0-py3-none-any.whl` +1. Link binary to PATH `ln -s $(which emoji) ~/.local/bin` +1. Deactivate virtualenv `deactivate` + +#### From source + +1. Follow steps 1-3 above +1. Download `requirements.txt` +1. Download the latest `tar.gz` from [releases](https://github.com/dtomlinson91/emoji-cmd/releases) and extract. +1. Do `pip install -r requirements.txt` +1. Go into the extracted tar folder and do `pip install -e .` +1. Link binary to PATH `ln -s $(which emoji) ~/.local/bin` +1. Deactivate virtualenv `deactivate` + +## Example Usage + +`emoji --help` + +``` +Usage: emoji [OPTIONS] + + Emojis on the command line ๐Ÿฅณ! + + Search for an emoji with --search EMOJI + +Options: + --help Show this message and exit. + --version Show the version and exit. + -s, --search TEXT Prints all emojis matching TEXT +``` + +`emoji --search cake` + +``` +I found 5 emojis for cake! ๐Ÿฅณ ++-------------+-------+ +| tag/alias | emoji | ++=============+=======+ +| :pancakes: | ๐Ÿฅž | ++-------------+-------+ +| :fish_cake: | ๐Ÿฅ | ++-------------+-------+ +| :moon_cake: | ๐Ÿฅฎ | ++-------------+-------+ +| :cake: | ๐Ÿฐ | ++-------------+-------+ +| :cupcake: | ๐Ÿง | ++-------------+-------+ +``` diff --git a/emoji-cmd/docs/_config.yml b/emoji-cmd/docs/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/emoji-cmd/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/emoji-cmd/docs/cli.html b/emoji-cmd/docs/cli.html new file mode 100644 index 0000000..b22220c --- /dev/null +++ b/emoji-cmd/docs/cli.html @@ -0,0 +1,87 @@ + + + + + + +emoji_cmd.cli API documentation + + + + + + + + + +
+
+
+

Module emoji_cmd.cli

+
+
+
+ +Expand source code + +
import emoji_cmd
+from emoji_cmd.__version__ import __version__
+import click
+import sys
+
+
+@click.command()
+@click.help_option()
+@click.version_option(version=__version__ + ', (Mon Nov 25 02:08:55 2019)')
+# @click.argument('emoji')
+@click.option(
+    '-s', '--search', 'emoji', help='Prints all emojis matching TEXT', type=str
+)
+def cli(emoji: str):
+    """Emojis on the command line ๐Ÿฅณ!
+
+    Search for an emoji with --search EMOJI
+    """
+    emoji_cmd.main(emoji)
+
+
+if getattr(sys, 'frozen', False):
+    cli(sys.argv[1:])
+
+# if __name__ == '__main__':
+#     options = '--help'
+
+#     print(f'> ' + options)
+#     cli(options.split())
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/emoji-cmd/docs/index.html b/emoji-cmd/docs/index.html new file mode 100644 index 0000000..e49168f --- /dev/null +++ b/emoji-cmd/docs/index.html @@ -0,0 +1,207 @@ + + + + + + +emoji_cmd API documentation + + + + + + + + + +
+
+
+

Module emoji_cmd

+
+
+
+ +Expand source code + +
import emojis  # type: ignore
+import argparse
+from texttable import Texttable   # type: ignore
+
+
+def main(emoji: str) -> None:
+    """returns an emoji from a string
+
+    Parameters
+    ----------
+    emoji : str
+        a string for the emoji name/tag/description
+
+    Returns
+    -------
+    None
+    """
+
+    t = Texttable()
+
+    searchOne = [y for y in [x for x in emojis.db.get_tags()] if emoji in y]
+
+    emojiResults = []
+
+    emojiResults.append((['tag/alias', 'emoji']))
+
+    for item in searchOne:
+        listOne = [x for x in emojis.db.get_emojis_by_tag(item)]
+        for i in range(0, len(listOne)):
+            emojiResults.append(
+                [(listOne[i][0][0]).strip(), (listOne[i][1]).strip()]
+            )
+
+    for alias, emojiAlias in zip(
+        emojis.db.get_emoji_aliases().keys(),
+        emojis.db.get_emoji_aliases().values(),
+    ):
+        if emoji in alias:
+            emojiResults.append([alias.strip(), emojiAlias.strip()])
+
+    t.add_rows(emojiResults)
+
+    if len(emojiResults) - 1 == 0:
+        print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿ˜ข')
+    else:
+        print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿฅณ')
+        print(t.draw())
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(
+        description="""
+    emoji lookup script to be ran on the shell
+"""
+    )
+
+    parser.add_argument(
+        'emoji',
+        type=str,
+        help=(
+            'full path to list of files. leave blank'
+            ' to run in current directory. the results will be'
+            ' placed in this folder if specified.'
+        ),
+    )
+
+    args = parser.parse_args()
+
+    emoji = vars(args)['emoji']
+
+    main(emoji)
+
+
+
+

Sub-modules

+
+
emoji_cmd.cli
+
+
+
+
+
+
+
+
+

Functions

+
+
+def main(emoji:ย str) ->ย NoneType +
+
+

returns an emoji from a string

+

Parameters

+
+
emoji : str
+
a string for the emoji name/tag/description
+
+

Returns

+
+
None
+
 
+
+
+ +Expand source code + +
def main(emoji: str) -> None:
+    """returns an emoji from a string
+
+    Parameters
+    ----------
+    emoji : str
+        a string for the emoji name/tag/description
+
+    Returns
+    -------
+    None
+    """
+
+    t = Texttable()
+
+    searchOne = [y for y in [x for x in emojis.db.get_tags()] if emoji in y]
+
+    emojiResults = []
+
+    emojiResults.append((['tag/alias', 'emoji']))
+
+    for item in searchOne:
+        listOne = [x for x in emojis.db.get_emojis_by_tag(item)]
+        for i in range(0, len(listOne)):
+            emojiResults.append(
+                [(listOne[i][0][0]).strip(), (listOne[i][1]).strip()]
+            )
+
+    for alias, emojiAlias in zip(
+        emojis.db.get_emoji_aliases().keys(),
+        emojis.db.get_emoji_aliases().values(),
+    ):
+        if emoji in alias:
+            emojiResults.append([alias.strip(), emojiAlias.strip()])
+
+    t.add_rows(emojiResults)
+
+    if len(emojiResults) - 1 == 0:
+        print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿ˜ข')
+    else:
+        print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿฅณ')
+        print(t.draw())
+
+
+
+
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/emoji-cmd/install.sh b/emoji-cmd/install.sh new file mode 100755 index 0000000..fdf42e6 --- /dev/null +++ b/emoji-cmd/install.sh @@ -0,0 +1,3 @@ +curl -LOemoji https://github.com/dtomlinson91/emoji-cmd/releases/download/1.0/emoji +chmod +x emoji +mv ./emoji ~/.local/bin diff --git a/emoji-cmd/poetry.lock b/emoji-cmd/poetry.lock new file mode 100644 index 0000000..f18f045 --- /dev/null +++ b/emoji-cmd/poetry.lock @@ -0,0 +1,242 @@ +[[package]] +category = "main" +description = "Python command-line parsing library" +name = "argparse" +optional = false +python-versions = "*" +version = "1.4.0" + +[[package]] +category = "dev" +description = "Atomic file writes." +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[[package]] +category = "main" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.4.1" + +[[package]] +category = "main" +description = "Emojis for Python" +name = "emojis" +optional = false +python-versions = "*" +version = "0.5.1" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" +optional = false +python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3" +version = "0.23" + +[package.dependencies] +zipp = ">=0.5" + +[[package]] +category = "dev" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +name = "mako" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.1.0" + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[[package]] +category = "dev" +description = "Python implementation of Markdown." +name = "markdown" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +version = "3.1.1" + +[package.dependencies] +setuptools = ">=36" + +[[package]] +category = "dev" +description = "Safely add untrusted strings to HTML/XML markup." +name = "markupsafe" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.1.1" + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.4" +version = "7.2.0" + +[[package]] +category = "dev" +description = "Optional static typing for Python" +name = "mypy" +optional = false +python-versions = ">=3.5" +version = "0.740" + +[package.dependencies] +mypy-extensions = ">=0.4.0,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" + +[[package]] +category = "dev" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +name = "mypy-extensions" +optional = false +python-versions = "*" +version = "0.4.3" + +[[package]] +category = "dev" +description = "Auto-generate API documentation for Python projects." +name = "pdoc3" +optional = false +python-versions = ">= 3.5" +version = "0.7.2" + +[package.dependencies] +mako = "*" +markdown = ">=3.0" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" + +[package.dependencies] +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.0" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.10.1" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +pluggy = ">=0.7" +py = ">=1.5.0" +setuptools = "*" +six = ">=1.10.0" + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.13.0" + +[[package]] +category = "main" +description = "module for creating simple ASCII tables" +name = "texttable" +optional = false +python-versions = "*" +version = "1.6.2" + +[[package]] +category = "dev" +description = "a fork of Python 2 and 3 ast modules with type comment support" +name = "typed-ast" +optional = false +python-versions = "*" +version = "1.4.0" + +[[package]] +category = "dev" +description = "Backported and Experimental Type Hints for Python 3.5+" +name = "typing-extensions" +optional = false +python-versions = "*" +version = "3.7.4.1" + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" +optional = false +python-versions = ">=2.7" +version = "0.6.0" + +[package.dependencies] +more-itertools = "*" + +[metadata] +content-hash = "758849be8630c5c4d89297bfc1315cd1d95e6f8d922e65fd03cf9e90e2b6aaf2" +python-versions = "^3.7" + +[metadata.hashes] +argparse = ["62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", "c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"] +atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] +click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] +colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] +emojis = ["30d0b317fc9ab70b6acdc752a1ed481b2d278f7ca7c68aef222e4cd833e5de7f", "a719391df2de34689ce47d78bb302b0f0dc24656b4f83f501725de7b0ee621ee"] +importlib-metadata = ["aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", "d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"] +mako = ["a36919599a9b7dc5d86a7a8988f23a9a3a3d083070023bab23d64f7f1d1e0a4b"] +markdown = ["2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", "56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c"] +markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] +more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] +mypy = ["1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f", "31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00", "3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae", "48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d", "540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9", "672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391", "6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f", "9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9", "ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990", "b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7", "d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb", "d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453", "dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b", "f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb"] +mypy-extensions = ["090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", "2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"] +pdoc3 = ["df43a7f1a139a5a61e778f424f167719acc33ed71bf13b6c34c7ebd139866eb7"] +pluggy = ["15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"] +py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] +pytest = ["3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec", "e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"] +six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] +texttable = ["eff3703781fbc7750125f50e10f001195174f13825a92a45e9403037d539b4f4"] +typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"] +typing-extensions = ["091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2", "910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d", "cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"] +zipp = ["3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", "f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"] diff --git a/emoji-cmd/pyproject.toml b/emoji-cmd/pyproject.toml new file mode 100644 index 0000000..0f1c1f5 --- /dev/null +++ b/emoji-cmd/pyproject.toml @@ -0,0 +1,24 @@ +[tool.poetry] +name = "emoji-cmd" +version = "1.0" +description = "" +authors = ["dtomlinson "] + +[tool.poetry.dependencies] +python = "^3.7" +emojis = "^0.5.1" +argparse = "^1.4" +texttable = "^1.6" +click = "^7.0" + +[tool.poetry.dev-dependencies] +pytest = "^3.0" +mypy = "^0.740.0" +pdoc3 = "^0.7.2" + +[tool.poetry.plugins."console_scripts"] +"emoji" = "emoji_cmd.cli:cli" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/emoji-cmd/requirements.txt b/emoji-cmd/requirements.txt new file mode 100644 index 0000000..afd9061 --- /dev/null +++ b/emoji-cmd/requirements.txt @@ -0,0 +1,11 @@ +argparse==1.4.0 \ + --hash=sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4 \ + --hash=sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314 +click==7.0 \ + --hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \ + --hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7 +emojis==0.5.1 \ + --hash=sha256:30d0b317fc9ab70b6acdc752a1ed481b2d278f7ca7c68aef222e4cd833e5de7f \ + --hash=sha256:a719391df2de34689ce47d78bb302b0f0dc24656b4f83f501725de7b0ee621ee +texttable==1.6.2 \ + --hash=sha256:eff3703781fbc7750125f50e10f001195174f13825a92a45e9403037d539b4f4 diff --git a/emoji-cmd/src/emoji_cmd/__init__.py b/emoji-cmd/src/emoji_cmd/__init__.py new file mode 100644 index 0000000..6990950 --- /dev/null +++ b/emoji-cmd/src/emoji_cmd/__init__.py @@ -0,0 +1,71 @@ +import emojis # type: ignore +import argparse +from texttable import Texttable # type: ignore + + +def main(emoji: str) -> None: + """returns an emoji from a string + + Parameters + ---------- + emoji : str + a string for the emoji name/tag/description + + Returns + ------- + None + """ + + t = Texttable() + + searchOne = [y for y in [x for x in emojis.db.get_tags()] if emoji in y] + + emojiResults = [] + + emojiResults.append((['tag/alias', 'emoji'])) + + for item in searchOne: + listOne = [x for x in emojis.db.get_emojis_by_tag(item)] + for i in range(0, len(listOne)): + emojiResults.append( + [(listOne[i][0][0]).strip(), (listOne[i][1]).strip()] + ) + + for alias, emojiAlias in zip( + emojis.db.get_emoji_aliases().keys(), + emojis.db.get_emoji_aliases().values(), + ): + if emoji in alias: + emojiResults.append([alias.strip(), emojiAlias.strip()]) + + t.add_rows(emojiResults) + + if len(emojiResults) - 1 == 0: + print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿ˜ข') + else: + print(f'I found {len(emojiResults)-1} emojis for {emoji}! ๐Ÿฅณ') + print(t.draw()) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=""" + emoji lookup script to be ran on the shell +""" + ) + + parser.add_argument( + 'emoji', + type=str, + help=( + 'full path to list of files. leave blank' + ' to run in current directory. the results will be' + ' placed in this folder if specified.' + ), + ) + + args = parser.parse_args() + + emoji = vars(args)['emoji'] + + main(emoji) diff --git a/emoji-cmd/src/emoji_cmd/__version__.py b/emoji-cmd/src/emoji_cmd/__version__.py new file mode 100644 index 0000000..7e49527 --- /dev/null +++ b/emoji-cmd/src/emoji_cmd/__version__.py @@ -0,0 +1 @@ +__version__ = '1.0' diff --git a/emoji-cmd/src/emoji_cmd/cli.py b/emoji-cmd/src/emoji_cmd/cli.py new file mode 100644 index 0000000..23bb876 --- /dev/null +++ b/emoji-cmd/src/emoji_cmd/cli.py @@ -0,0 +1,29 @@ +import emoji_cmd +from emoji_cmd.__version__ import __version__ +import click +import sys + + +@click.command() +@click.help_option() +@click.version_option(version=__version__ + ', (Mon Nov 25 02:08:55 2019)') +# @click.argument('emoji') +@click.option( + '-s', '--search', 'emoji', help='Prints all emojis matching TEXT', type=str +) +def cli(emoji: str): + """Emojis on the command line ๐Ÿฅณ! + + Search for an emoji with --search EMOJI + """ + emoji_cmd.main(emoji) + + +if getattr(sys, 'frozen', False): + cli(sys.argv[1:]) + +# if __name__ == '__main__': +# options = '--help' + +# print(f'> ' + options) +# cli(options.split()) diff --git a/test-env/tests/__init__.py b/emoji-cmd/tests/__init__.py similarity index 100% rename from test-env/tests/__init__.py rename to emoji-cmd/tests/__init__.py diff --git a/emoji-cmd/tests/test_emoji_cmd.py b/emoji-cmd/tests/test_emoji_cmd.py new file mode 100644 index 0000000..50c8ce1 --- /dev/null +++ b/emoji-cmd/tests/test_emoji_cmd.py @@ -0,0 +1 @@ +import emoji_cmd diff --git a/playground/hearts.py b/playground/hearts.py new file mode 100644 index 0000000..b2c54f7 --- /dev/null +++ b/playground/hearts.py @@ -0,0 +1,231 @@ +# hearts.py + +from collections import Counter +import random +import sys +from typing import Any, Dict, List, Optional, Sequence, Tuple, Union +from typing import overload + + +class Card: + SUITS = "โ™  โ™ก โ™ข โ™ฃ".split() + RANKS = "2 3 4 5 6 7 8 9 10 J Q K A".split() + + def __init__(self, suit: str, rank: str) -> None: + self.suit = suit + self.rank = rank + + @property + def value(self) -> int: + """The value of a card is rank as a number""" + return self.RANKS.index(self.rank) + + @property + def points(self) -> int: + """Points this card is worth""" + if self.suit == "โ™ " and self.rank == "Q": + return 13 + if self.suit == "โ™ก": + return 1 + return 0 + + def __eq__(self, other: Any) -> Any: + return self.suit == other.suit and self.rank == other.rank + + def __lt__(self, other: Any) -> Any: + return self.value < other.value + + def __repr__(self) -> str: + return f"{self.suit}{self.rank}" + + +class Deck(Sequence[Card]): + def __init__(self, cards: List[Card]) -> None: + self.cards = cards + + @classmethod + def create(cls, shuffle: bool = False) -> "Deck": + """Create a new deck of 52 cards""" + cards = [Card(s, r) for r in Card.RANKS for s in Card.SUITS] + if shuffle: + random.shuffle(cards) + return cls(cards) + + def play(self, card: Card) -> None: + """Play one card by removing it from the deck""" + self.cards.remove(card) + + def deal(self, num_hands: int) -> Tuple["Deck", ...]: + """Deal the cards in the deck into a number of hands""" + return tuple(self[i::num_hands] for i in range(num_hands)) + + def add_cards(self, cards: List[Card]) -> None: + """Add a list of cards to the deck""" + self.cards += cards + + def __len__(self) -> int: + return len(self.cards) + + @overload + def __getitem__(self, key: int) -> Card: + ... + + @overload + def __getitem__(self, key: slice) -> "Deck": # noqa + ... + + def __getitem__( # noqa + self, key: Union[int, slice] + ) -> Union[Card, "Deck"]: + if isinstance(key, int): + return self.cards[key] + elif isinstance(key, slice): + cls = self.__class__ + return cls(self.cards[key]) + else: + raise TypeError("Indices must be integers or slices") + + def __repr__(self) -> str: + return " ".join(repr(c) for c in self.cards) + + +class Player: + def __init__(self, name: str, hand: Optional[Deck] = None) -> None: + self.name = name + self.hand = Deck([]) if hand is None else hand + + def playable_cards(self, played: List[Card], hearts_broken: bool) -> Deck: + """List which cards in hand are playable this round""" + if Card("โ™ฃ", "2") in self.hand: + return Deck([Card("โ™ฃ", "2")]) + + lead = played[0].suit if played else None + playable = Deck([c for c in self.hand if c.suit == lead]) or self.hand + if lead is None and not hearts_broken: + playable = Deck([c for c in playable if c.suit != "โ™ก"]) + return playable or Deck(self.hand.cards) + + def non_winning_cards(self, played: List[Card], playable: Deck) -> Deck: + """List playable cards that are guaranteed to not win the trick""" + if not played: + return Deck([]) + + lead = played[0].suit + best_card = max(c for c in played if c.suit == lead) + return Deck([c for c in playable if c < best_card or c.suit != lead]) + + def play_card(self, played: List[Card], hearts_broken: bool) -> Card: + """Play a card from a cpu player's hand""" + playable = self.playable_cards(played, hearts_broken) + non_winning = self.non_winning_cards(played, playable) + + # Strategy + if non_winning: + # Highest card not winning the trick, prefer points + card = max(non_winning, key=lambda c: (c.points, c.value)) + elif len(played) < 3: + # Lowest card maybe winning, avoid points + card = min(playable, key=lambda c: (c.points, c.value)) + else: + # Highest card guaranteed winning, avoid points + card = max(playable, key=lambda c: (-c.points, c.value)) + self.hand.cards.remove(card) + print(f"{self.name} -> {card}") + return card + + def has_card(self, card: Card) -> bool: + return card in self.hand + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.name!r}, {self.hand})" + + +class HumanPlayer(Player): + def play_card(self, played: List[Card], hearts_broken: bool) -> Card: + """Play a card from a human player's hand""" + playable = sorted(self.playable_cards(played, hearts_broken)) + p_str = " ".join(f"{n}: {c}" for n, c in enumerate(playable)) + np_str = " ".join(repr(c) for c in self.hand if c not in playable) + print(f" {p_str} (Rest: {np_str})") + while True: + try: + card_num = int(input(f" {self.name}, choose card: ")) + card = playable[card_num] + except (ValueError, IndexError): + pass + else: + break + self.hand.play(card) + print(f"{self.name} => {card}") + return card + + +class HeartsGame: + def __init__(self, *names: str) -> None: + self.names = (list(names) + "P1 P2 P3 P4".split())[:4] + self.players = [Player(n) for n in self.names[1:]] + self.players.append(HumanPlayer(self.names[0])) + + def play(self) -> None: + """Play a game of Hearts until one player go bust""" + score = Counter({n: 0 for n in self.names}) + while all(s < 100 for s in score.values()): + print("\nStarting new round:") + round_score = self.play_round() + score.update(Counter(round_score)) + print("Scores:") + for name, total_score in score.most_common(4): + print(f"{name:<15} {round_score[name]:>3} {total_score:>3}") + + winners = [n for n in self.names if score[n] == min(score.values())] + print(f"\n{' and '.join(winners)} won the game") + + def play_round(self) -> Dict[str, int]: + """Play a round of the Hearts card game""" + deck = Deck.create(shuffle=True) + for player, hand in zip(self.players, deck.deal(4)): + player.hand.add_cards(hand.cards) + start_player = next( + p for p in self.players if p.has_card(Card("โ™ฃ", "2")) + ) + tricks = {p.name: Deck([]) for p in self.players} + hearts = False + + # Play cards from each player's hand until empty + while start_player.hand: + played: List[Card] = [] + turn_order = self.player_order(start=start_player) + for player in turn_order: + card = player.play_card(played, hearts_broken=hearts) + played.append(card) + start_player = self.trick_winner(played, turn_order) + tricks[start_player.name].add_cards(played) + print(f"{start_player.name} wins the trick\n") + hearts = hearts or any(c.suit == "โ™ก" for c in played) + return self.count_points(tricks) + + def player_order(self, start: Optional[Player] = None) -> List[Player]: + """Rotate player order so that start goes first""" + if start is None: + start = random.choice(self.players) + start_idx = self.players.index(start) + return self.players[start_idx:] + self.players[:start_idx] + + @staticmethod + def trick_winner(trick: List[Card], players: List[Player]) -> Player: + lead = trick[0].suit + valid = [ + (c.value, p) for c, p in zip(trick, players) if c.suit == lead + ] + return max(valid)[1] + + @staticmethod + def count_points(tricks: Dict[str, Deck]) -> Dict[str, int]: + return {n: sum(c.points for c in cards) for n, cards in tricks.items()} + + +if __name__ == "__main__": + # Read player names from the command line + player_names = sys.argv[1:] + game = HeartsGame(*player_names) + game.play() diff --git a/tmp/jsonTest.py b/playground/jsonTest.py similarity index 100% rename from tmp/jsonTest.py rename to playground/jsonTest.py diff --git a/playground/kite.py b/playground/kite.py new file mode 100644 index 0000000..ab25274 --- /dev/null +++ b/playground/kite.py @@ -0,0 +1,7 @@ +import emojis +import datetime +import praw + +print(emojis.__file__) +print(datetime.__file__) +print(praw.__file__) diff --git a/tmp/markdown.md b/playground/markdown.md similarity index 100% rename from tmp/markdown.md rename to playground/markdown.md diff --git a/tmp/python-debugging.py b/playground/python-debugging.py similarity index 100% rename from tmp/python-debugging.py rename to playground/python-debugging.py diff --git a/plex-posters/.gitignore b/plex-posters/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/plex-posters/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/plex-posters/.pytype/.ninja_deps b/plex-posters/.pytype/.ninja_deps new file mode 100644 index 0000000..e5675ec Binary files /dev/null and b/plex-posters/.pytype/.ninja_deps differ diff --git a/plex-posters/.pytype/.ninja_log b/plex-posters/.pytype/.ninja_log new file mode 100644 index 0000000..1fc148d --- /dev/null +++ b/plex-posters/.pytype/.ninja_log @@ -0,0 +1 @@ +# ninja log v5 diff --git a/plex-posters/.pytype/build.ninja b/plex-posters/.pytype/build.ninja new file mode 100644 index 0000000..9c9e399 --- /dev/null +++ b/plex-posters/.pytype/build.ninja @@ -0,0 +1,15 @@ +rule infer + command = pytype-single --imports_info $imports --module-name $module -V 3.8 -o $out --no-report-errors --nofail --quick $in + description = infer $module +rule check + command = pytype-single --imports_info $imports --module-name $module -V 3.8 -o $out --analyze-annotated --nofail --quick $in + description = check $module +build /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/__version__.pyi: check /Users/dtomlinson/git-repos/projects/plex-posters/src/plex_posters/__version__.py + imports = /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/imports/plex_posters.__version__.imports + module = plex_posters.__version__ +build /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/lib/__init__.pyi: check /Users/dtomlinson/git-repos/projects/plex-posters/src/plex_posters/lib/__init__.py + imports = /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/imports/plex_posters.lib.__init__.imports + module = plex_posters.lib.__init__ +build /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/__init__.pyi: check /Users/dtomlinson/git-repos/projects/plex-posters/src/plex_posters/__init__.py | /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/__version__.pyi /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/lib/__init__.pyi + imports = /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/imports/plex_posters.__init__.imports + module = plex_posters.__init__ diff --git a/plex-posters/.pytype/imports/default.pyi b/plex-posters/.pytype/imports/default.pyi new file mode 100644 index 0000000..7bb11b4 --- /dev/null +++ b/plex-posters/.pytype/imports/default.pyi @@ -0,0 +1,3 @@ + +from typing import Any +def __getattr__(name) -> Any: ... diff --git a/plex-posters/.pytype/imports/plex_posters.__init__.imports b/plex-posters/.pytype/imports/plex_posters.__init__.imports new file mode 100644 index 0000000..5fce283 --- /dev/null +++ b/plex-posters/.pytype/imports/plex_posters.__init__.imports @@ -0,0 +1,3 @@ +plex_posters/__version__ /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/__version__.pyi +plex_posters/lib/__init__ /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/pyi/plex_posters/lib/__init__.pyi +praw/__init__ /Users/dtomlinson/git-repos/projects/plex-posters/.pytype/imports/default.pyi diff --git a/test-env/README.rst b/plex-posters/.pytype/imports/plex_posters.__version__.imports similarity index 100% rename from test-env/README.rst rename to plex-posters/.pytype/imports/plex_posters.__version__.imports diff --git a/plex-posters/.pytype/imports/plex_posters.lib.__init__.imports b/plex-posters/.pytype/imports/plex_posters.lib.__init__.imports new file mode 100644 index 0000000..e69de29 diff --git a/plex-posters/dist/.DS_Store b/plex-posters/dist/.DS_Store deleted file mode 100644 index 2488d99..0000000 Binary files a/plex-posters/dist/.DS_Store and /dev/null differ diff --git a/plex-posters/dist/plex-posters-0.1.0.tar.gz b/plex-posters/dist/plex-posters-0.1.0.tar.gz deleted file mode 100644 index 0edb381..0000000 Binary files a/plex-posters/dist/plex-posters-0.1.0.tar.gz and /dev/null differ diff --git a/plex-posters/dist/plex_posters-0.1.0-py3-none-any.whl b/plex-posters/dist/plex_posters-0.1.0-py3-none-any.whl deleted file mode 100644 index a3f7c96..0000000 Binary files a/plex-posters/dist/plex_posters-0.1.0-py3-none-any.whl and /dev/null differ diff --git a/plex-posters/dist/praw.ini b/plex-posters/dist/praw.ini deleted file mode 100644 index 247d243..0000000 --- a/plex-posters/dist/praw.ini +++ /dev/null @@ -1,20 +0,0 @@ -[DEFAULT] -# A boolean to indicate whether or not to check for package updates. -check_for_updates=True - -# Object to kind mappings -comment_kind=t1 -message_kind=t4 -redditor_kind=t2 -submission_kind=t3 -subreddit_kind=t5 -trophy_kind=t6 - -# The URL prefix for OAuth-related requests. -oauth_url=https://oauth.reddit.com - -# The URL prefix for regular requests. -reddit_url=https://www.reddit.com - -# The URL prefix for short URLs. -short_url=https://redd.it diff --git a/plex-posters/dist/test_plex_posters b/plex-posters/dist/test_plex_posters deleted file mode 100755 index 460a793..0000000 Binary files a/plex-posters/dist/test_plex_posters and /dev/null differ diff --git a/plex-posters/poetry.lock b/plex-posters/poetry.lock index 3c5eaf3..e281f75 100644 --- a/plex-posters/poetry.lock +++ b/plex-posters/poetry.lock @@ -55,13 +55,34 @@ optional = false python-versions = ">=3.4" version = "7.2.0" +[[package]] +category = "dev" +description = "Optional static typing for Python" +name = "mypy" +optional = false +python-versions = ">=3.5" +version = "0.740" + +[package.dependencies] +mypy-extensions = ">=0.4.0,<0.5.0" +typed-ast = ">=1.4.0,<1.5.0" +typing-extensions = ">=3.7.4" + +[[package]] +category = "dev" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +name = "mypy-extensions" +optional = false +python-versions = "*" +version = "0.4.3" + [[package]] category = "dev" description = "plugin and hook calling mechanisms for python" name = "pluggy" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.0" +version = "0.13.1" [[package]] category = "main" @@ -87,6 +108,18 @@ version = "1.0.1" [package.dependencies] requests = ">=2.6.0,<3.0" +[[package]] +category = "dev" +description = "A full-screen, console-based Python debugger" +name = "pudb" +optional = false +python-versions = "*" +version = "2019.2" + +[package.dependencies] +pygments = ">=1.0" +urwid = ">=1.1.1" + [[package]] category = "dev" description = "library with cross-python path, ini-parsing, io, code, log facilities" @@ -95,6 +128,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.8.0" +[[package]] +category = "dev" +description = "Pygments is a syntax highlighting package written in Python." +name = "pygments" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.4.2" + [[package]] category = "dev" description = "pytest: simple powerful testing with Python" @@ -135,6 +176,22 @@ optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" version = "1.13.0" +[[package]] +category = "dev" +description = "a fork of Python 2 and 3 ast modules with type comment support" +name = "typed-ast" +optional = false +python-versions = "*" +version = "1.4.0" + +[[package]] +category = "dev" +description = "Backported and Experimental Type Hints for Python 3.5+" +name = "typing-extensions" +optional = false +python-versions = "*" +version = "3.7.4.1" + [[package]] category = "main" description = "A python module that will check for package updates." @@ -154,6 +211,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" version = "1.25.7" +[[package]] +category = "dev" +description = "A full-featured console (xterm et al.) user interface library" +name = "urwid" +optional = false +python-versions = "*" +version = "2.1.0" + [[package]] category = "main" description = "WebSocket client for Python. hybi13 is supported." @@ -166,7 +231,7 @@ version = "0.56.0" six = "*" [metadata] -content-hash = "3b87e030e8047911ca71f9edde0e547018b1282a3122c53430c0d966bb3d4ffd" +content-hash = "3fb939a7e78632a796efbfa0c358369ccd78a148d5649cd2894380f6e82d5409" python-versions = "^3.8" [metadata.hashes] @@ -177,13 +242,20 @@ chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", " colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] -pluggy = ["0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", "fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"] +mypy = ["1521c186a3d200c399bd5573c828ea2db1362af7209b2adb1bb8532cea2fb36f", "31a046ab040a84a0fc38bc93694876398e62bc9f35eca8ccbf6418b7297f4c00", "3b1a411909c84b2ae9b8283b58b48541654b918e8513c20a400bb946aa9111ae", "48c8bc99380575deb39f5d3400ebb6a8a1cb5cc669bbba4d3bb30f904e0a0e7d", "540c9caa57a22d0d5d3c69047cc9dd0094d49782603eb03069821b41f9e970e9", "672e418425d957e276c291930a3921b4a6413204f53fe7c37cad7bc57b9a3391", "6ed3b9b3fdc7193ea7aca6f3c20549b377a56f28769783a8f27191903a54170f", "9371290aa2cad5ad133e4cdc43892778efd13293406f7340b9ffe99d5ec7c1d9", "ace6ac1d0f87d4072f05b5468a084a45b4eda970e4d26704f201e06d47ab2990", "b428f883d2b3fe1d052c630642cc6afddd07d5cd7873da948644508be3b9d4a7", "d5bf0e6ec8ba346a2cf35cb55bf4adfddbc6b6576fcc9e10863daa523e418dbb", "d7574e283f83c08501607586b3167728c58e8442947e027d2d4c7dcd6d82f453", "dc889c84241a857c263a2b1cd1121507db7d5b5f5e87e77147097230f374d10b", "f4748697b349f373002656bf32fede706a0e713d67bfdcf04edf39b1f61d46eb"] +mypy-extensions = ["090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", "2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"] +pluggy = ["15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"] praw = ["2e5c98e49fe60e5308255ed147b670d350f98281f84f582df30f87de727b6de2", "cb8f85541ad4c6b10214ef9639acccfb5fed7ffee977be169b85357d2d2ea6d9"] prawcore = ["25dd14bf121bc0ad2ffc78e2322d9a01a516017105a5596cc21bb1e9a928b40c", "ab5558efb438aa73fc66c4178bfc809194dea3ce2addf4dec873de7e2fd2824e"] +pudb = ["e8f0ea01b134d802872184b05bffc82af29a1eb2f9374a277434b932d68f58dc"] py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] +pygments = ["71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", "881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"] pytest = ["3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec", "e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"] requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] +typed-ast = ["1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", "18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", "262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", "2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", "354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", "48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", "4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", "630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", "66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", "71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", "7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", "838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", "95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", "bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", "cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", "d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", "d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", "d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", "fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", "ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12"] +typing-extensions = ["091ecc894d5e908ac75209f10d5b4f118fbdb2eb1ede6a63544054bb1edb41f2", "910f4656f54de5993ad9304959ce9bb903f90aadc7c67a0bef07e678014e892d", "cf8b63fedea4d89bab840ecbb93e75578af28f76f66c35889bd7065f5af88575"] update-checker = ["59cfad7f9a0ee99f95f1dfc60f55bf184937bcab46a7270341c2c33695572453", "70e39446fccf77b21192cf7a8214051fa93a636dc3b5c8b602b589d100a168b8"] urllib3 = ["a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", "f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"] +urwid = ["0896f36060beb6bf3801cb554303fef336a79661401797551ba106d23ab4cd86"] websocket-client = ["1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", "1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a"] diff --git a/plex-posters/poetry.lock.bak b/plex-posters/poetry.lock.bak new file mode 100644 index 0000000..3c5eaf3 --- /dev/null +++ b/plex-posters/poetry.lock.bak @@ -0,0 +1,189 @@ +[[package]] +category = "dev" +description = "Atomic file writes." +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2019.9.11" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.4.1" + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.8" + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.4" +version = "7.2.0" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.0" + +[[package]] +category = "main" +description = "PRAW, an acronym for `Python Reddit API Wrapper`, is a python package that allows for simple access to reddit's API." +name = "praw" +optional = false +python-versions = ">=3.4" +version = "6.4.0" + +[package.dependencies] +prawcore = ">=1.0.1,<2.0" +update-checker = ">=0.16" +websocket-client = ">=0.54.0" + +[[package]] +category = "main" +description = "Low-level communication layer for PRAW 4+." +name = "prawcore" +optional = false +python-versions = "*" +version = "1.0.1" + +[package.dependencies] +requests = ">=2.6.0,<3.0" + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.0" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.10.1" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +pluggy = ">=0.7" +py = ">=1.5.0" +setuptools = "*" +six = ">=1.10.0" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.22.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<3.1.0" +idna = ">=2.5,<2.9" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[[package]] +category = "main" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.13.0" + +[[package]] +category = "main" +description = "A python module that will check for package updates." +name = "update-checker" +optional = false +python-versions = "*" +version = "0.16" + +[package.dependencies] +requests = ">=2.3.0" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" +version = "1.25.7" + +[[package]] +category = "main" +description = "WebSocket client for Python. hybi13 is supported." +name = "websocket-client" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.56.0" + +[package.dependencies] +six = "*" + +[metadata] +content-hash = "3b87e030e8047911ca71f9edde0e547018b1282a3122c53430c0d966bb3d4ffd" +python-versions = "^3.8" + +[metadata.hashes] +atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] +certifi = ["e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", "fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] +idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] +pluggy = ["0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", "fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"] +praw = ["2e5c98e49fe60e5308255ed147b670d350f98281f84f582df30f87de727b6de2", "cb8f85541ad4c6b10214ef9639acccfb5fed7ffee977be169b85357d2d2ea6d9"] +prawcore = ["25dd14bf121bc0ad2ffc78e2322d9a01a516017105a5596cc21bb1e9a928b40c", "ab5558efb438aa73fc66c4178bfc809194dea3ce2addf4dec873de7e2fd2824e"] +py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] +pytest = ["3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec", "e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"] +requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] +six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] +update-checker = ["59cfad7f9a0ee99f95f1dfc60f55bf184937bcab46a7270341c2c33695572453", "70e39446fccf77b21192cf7a8214051fa93a636dc3b5c8b602b589d100a168b8"] +urllib3 = ["a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", "f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"] +websocket-client = ["1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", "1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a"] diff --git a/plex-posters/pyproject.toml b/plex-posters/pyproject.toml index 7c7a3e4..b03194f 100644 --- a/plex-posters/pyproject.toml +++ b/plex-posters/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "plex-posters" -version = "0.1.0" +version = "0.1.4" description = "" authors = ["dtomlinson "] @@ -10,6 +10,8 @@ praw = "^6.4" [tool.poetry.dev-dependencies] pytest = "^3.0" +mypy = "^0.740.0" +pudb = "^2019.2" [build-system] requires = ["poetry>=0.12"] diff --git a/plex-posters/src/plex_posters/__init__.py b/plex-posters/src/plex_posters/__init__.py index 95d699d..df3ac86 100644 --- a/plex-posters/src/plex_posters/__init__.py +++ b/plex-posters/src/plex_posters/__init__.py @@ -1,11 +1,12 @@ from __future__ import annotations -from .__version__ import __version__ +from .__version__ import __version__ # noqa from .lib import export -from typing import Type, TypeVar -import praw +from typing import Type, TypeVar, List, Dict +import praw # type: ignore import requests -__all__ = [] +__all__ = [] # type: List + T_movie_poster_porn_scraper = TypeVar( 'T_movie_poster_porn_scraper', bound="movie_poster_porn_scraper" @@ -16,13 +17,12 @@ T_movie_poster_porn_scraper = TypeVar( class movie_poster_porn_scraper(object): """Poster scraper - Attributes ---------- reddit_instance : praw.Reddit A praw instance connected to Reddit """ - + def __init__(self, instance: praw.Reddit) -> None: """ Parameters @@ -35,13 +35,12 @@ class movie_poster_porn_scraper(object): @classmethod def create_instance( - cls: Type(T_movie_poster_porn_scraper), + cls: Type[T_movie_poster_porn_scraper], client_id: str, client_secret: str, user_agent: str, ) -> T_movie_poster_porn_scraper: """Connect to reddit - Parameters ---------- client_id : str @@ -64,7 +63,7 @@ class movie_poster_porn_scraper(object): ) -> T_movie_poster_porn_scraper: """ """ - self._poster_urls = {} + self._poster_urls: Dict = {} for post in self.reddit_instance.subreddit('MoviePosterPorn').hot( limit=10 ): @@ -78,7 +77,6 @@ class movie_poster_porn_scraper(object): def get_posters(self: T_movie_poster_porn_scraper): """download the posters - Returns ------- self diff --git a/plex-posters/src/plex_posters/__pycache__/__init__.cpython-38.pyc b/plex-posters/src/plex_posters/__pycache__/__init__.cpython-38.pyc index 4dbd3b2..67026d3 100644 Binary files a/plex-posters/src/plex_posters/__pycache__/__init__.cpython-38.pyc and b/plex-posters/src/plex_posters/__pycache__/__init__.cpython-38.pyc differ diff --git a/plex-posters/src/plex_posters/__pycache__/__version__.cpython-38.pyc b/plex-posters/src/plex_posters/__pycache__/__version__.cpython-38.pyc index b879815..8b88cc6 100644 Binary files a/plex-posters/src/plex_posters/__pycache__/__version__.cpython-38.pyc and b/plex-posters/src/plex_posters/__pycache__/__version__.cpython-38.pyc differ diff --git a/plex-posters/src/plex_posters/lib/__pycache__/__init__.cpython-38.pyc b/plex-posters/src/plex_posters/lib/__pycache__/__init__.cpython-38.pyc index 95a0648..d290bc8 100644 Binary files a/plex-posters/src/plex_posters/lib/__pycache__/__init__.cpython-38.pyc and b/plex-posters/src/plex_posters/lib/__pycache__/__init__.cpython-38.pyc differ diff --git a/plex-posters/tests/.DS_Store b/plex-posters/tests/.DS_Store index 9fb2a5a..fa87695 100644 Binary files a/plex-posters/tests/.DS_Store and b/plex-posters/tests/.DS_Store differ diff --git a/plex-posters/tests/testimport/.DS_Store b/plex-posters/tests/testimport/.DS_Store index b34ef0c..b31b79c 100644 Binary files a/plex-posters/tests/testimport/.DS_Store and b/plex-posters/tests/testimport/.DS_Store differ diff --git a/plex-posters/tests/testimport/.gitignore b/plex-posters/tests/testimport/.gitignore new file mode 100644 index 0000000..542c501 --- /dev/null +++ b/plex-posters/tests/testimport/.gitignore @@ -0,0 +1 @@ +posters/* diff --git a/test-env/dist/test-env-0.1.0.tar.gz b/test-env/dist/test-env-0.1.0.tar.gz deleted file mode 100644 index 2c0762e..0000000 Binary files a/test-env/dist/test-env-0.1.0.tar.gz and /dev/null differ diff --git a/test-env/dist/test_env-0.1.0-py3-none-any.whl b/test-env/dist/test_env-0.1.0-py3-none-any.whl deleted file mode 100644 index bd0c79b..0000000 Binary files a/test-env/dist/test_env-0.1.0-py3-none-any.whl and /dev/null differ diff --git a/test-env/poetry.lock b/test-env/poetry.lock deleted file mode 100644 index dc9fccc..0000000 --- a/test-env/poetry.lock +++ /dev/null @@ -1,137 +0,0 @@ -[[package]] -category = "main" -description = "Atomic file writes." -name = "atomicwrites" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.3.0" - -[[package]] -category = "main" -description = "Classes Without Boilerplate" -name = "attrs" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.3.0" - -[[package]] -category = "main" -description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" -name = "colorama" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.4.1" - -[[package]] -category = "main" -description = "More routines for operating on iterables, beyond itertools" -name = "more-itertools" -optional = false -python-versions = ">=3.4" -version = "7.2.0" - -[[package]] -category = "main" -description = "NumPy is the fundamental package for array computing with Python." -name = "numpy" -optional = false -python-versions = ">=3.5" -version = "1.17.4" - -[[package]] -category = "main" -description = "Core utilities for Python packages" -name = "packaging" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.2" - -[package.dependencies] -pyparsing = ">=2.0.2" -six = "*" - -[[package]] -category = "dev" -description = "Display source code in Sublime Text 2 while debugging with pdb." -name = "pdbsublimetextsupport" -optional = false -python-versions = "*" -version = "0.2" - -[[package]] -category = "main" -description = "plugin and hook calling mechanisms for python" -name = "pluggy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.0" - -[[package]] -category = "main" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -name = "py" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.8.0" - -[[package]] -category = "main" -description = "Python parsing module" -name = "pyparsing" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -version = "2.4.5" - -[[package]] -category = "main" -description = "pytest: simple powerful testing with Python" -name = "pytest" -optional = false -python-versions = ">=3.5" -version = "5.2.4" - -[package.dependencies] -atomicwrites = ">=1.0" -attrs = ">=17.4.0" -colorama = "*" -more-itertools = ">=4.0.0" -packaging = "*" -pluggy = ">=0.12,<1.0" -py = ">=1.5.0" -wcwidth = "*" - -[[package]] -category = "main" -description = "Python 2 and 3 compatibility utilities" -name = "six" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*" -version = "1.13.0" - -[[package]] -category = "main" -description = "Measures number of Terminal column cells of wide-character codes" -name = "wcwidth" -optional = false -python-versions = "*" -version = "0.1.7" - -[metadata] -content-hash = "60c975933e2116ddeb037fd648696be98a96e198798e29a2e32e25b1b754901c" -python-versions = "^3.8" - -[metadata.hashes] -atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"] -attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] -colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] -more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] -numpy = ["0a7a1dd123aecc9f0076934288ceed7fd9a81ba3919f11a855a7887cbe82a02f", "0c0763787133dfeec19904c22c7e358b231c87ba3206b211652f8cbe1241deb6", "3d52298d0be333583739f1aec9026f3b09fdfe3ddf7c7028cb16d9d2af1cca7e", "43bb4b70585f1c2d153e45323a886839f98af8bfa810f7014b20be714c37c447", "475963c5b9e116c38ad7347e154e5651d05a2286d86455671f5b1eebba5feb76", "64874913367f18eb3013b16123c9fed113962e75d809fca5b78ebfbb73ed93ba", "683828e50c339fc9e68720396f2de14253992c495fdddef77a1e17de55f1decc", "6ca4000c4a6f95a78c33c7dadbb9495c10880be9c89316aa536eac359ab820ae", "75fd817b7061f6378e4659dd792c84c0b60533e867f83e0d1e52d5d8e53df88c", "7d81d784bdbed30137aca242ab307f3e65c8d93f4c7b7d8f322110b2e90177f9", "8d0af8d3664f142414fd5b15cabfd3b6cc3ef242a3c7a7493257025be5a6955f", "9679831005fb16c6df3dd35d17aa31dc0d4d7573d84f0b44cc481490a65c7725", "a8f67ebfae9f575d85fa859b54d3bdecaeece74e3274b0b5c5f804d7ca789fe1", "acbf5c52db4adb366c064d0b7c7899e3e778d89db585feadd23b06b587d64761", "ada4805ed51f5bcaa3a06d3dd94939351869c095e30a2b54264f5a5004b52170", "c7354e8f0eca5c110b7e978034cd86ed98a7a5ffcf69ca97535445a595e07b8e", "e2e9d8c87120ba2c591f60e32736b82b67f72c37ba88a4c23c81b5b8fa49c018", "e467c57121fe1b78a8f68dd9255fbb3bb3f4f7547c6b9e109f31d14569f490c3", "ede47b98de79565fcd7f2decb475e2dcc85ee4097743e551fe26cfc7eb3ff143", "f58913e9227400f1395c7b800503ebfdb0772f1c33ff8cb4d6451c06cabdf316", "fe39f5fd4103ec4ca3cb8600b19216cd1ff316b4990f4c0b6057ad982c0a34d5"] -packaging = ["28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", "d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"] -pdbsublimetextsupport = ["52d159240ca3bfc95df5d87969a7d312e08eb62bf080cc6d36a7047d23352d73"] -pluggy = ["0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6", "fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"] -py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] -pyparsing = ["20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f", "4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a"] -pytest = ["8e256fe71eb74e14a4d20a5987bb5e1488f0511ee800680aaedc62b9358714e8", "ff0090819f669aaa0284d0f4aad1a6d9d67a6efdc6dd4eb4ac56b704f890a0d6"] -six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] -wcwidth = ["3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", "f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"] diff --git a/test-env/test_env.egg-info/PKG-INFO b/test-env/test_env.egg-info/PKG-INFO deleted file mode 100644 index 9f677bd..0000000 --- a/test-env/test_env.egg-info/PKG-INFO +++ /dev/null @@ -1,11 +0,0 @@ -Metadata-Version: 1.2 -Name: test-env -Version: 0.1.0 -Summary: UNKNOWN -Home-page: UNKNOWN -Author: Your Name -Author-email: you@example.com -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN -Requires-Python: >=3.8,<4.0 diff --git a/test-env/test_env.egg-info/SOURCES.txt b/test-env/test_env.egg-info/SOURCES.txt deleted file mode 100644 index b0264e9..0000000 --- a/test-env/test_env.egg-info/SOURCES.txt +++ /dev/null @@ -1,7 +0,0 @@ -README.rst -setup.py -test_env/__init__.py -test_env.egg-info/PKG-INFO -test_env.egg-info/SOURCES.txt -test_env.egg-info/dependency_links.txt -test_env.egg-info/top_level.txt \ No newline at end of file diff --git a/test-env/test_env.egg-info/dependency_links.txt b/test-env/test_env.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/test-env/test_env.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test-env/test_env.egg-info/top_level.txt b/test-env/test_env.egg-info/top_level.txt deleted file mode 100644 index 52629c6..0000000 --- a/test-env/test_env.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -test_env diff --git a/test-env/test_env/__pycache__/__init__.cpython-38.pyc b/test-env/test_env/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 1c2ec9d..0000000 Binary files a/test-env/test_env/__pycache__/__init__.cpython-38.pyc and /dev/null differ diff --git a/test-env/tests/test_test_env.py b/test-env/tests/test_test_env.py deleted file mode 100644 index 6594859..0000000 --- a/test-env/tests/test_test_env.py +++ /dev/null @@ -1,5 +0,0 @@ -from test_env import __version__ - - -def test_version(): - assert __version__ == '0.1.0' diff --git a/weather-cli/.gitignore b/weather-cli/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/weather-cli/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/weather-cli/README.rst b/weather-cli/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/weather-cli/__dev/complex/README b/weather-cli/__dev/complex/README new file mode 100644 index 0000000..7eaac90 --- /dev/null +++ b/weather-cli/__dev/complex/README @@ -0,0 +1,16 @@ +$ complex_ + + complex is an example of building very complex cli + applications that load subcommands dynamically from + a plugin folder and other things. + + All the commands are implemented as plugins in the + `complex.commands` package. If a python module is + placed named "cmd_foo" it will show up as "foo" + command and the `cli` object within it will be + loaded as nested Click command. + +Usage: + + $ pip install --editable . + $ complex --help diff --git a/weather-cli/__dev/complex/complex/__init__.py b/weather-cli/__dev/complex/complex/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/weather-cli/__dev/complex/complex/cli.py b/weather-cli/__dev/complex/complex/cli.py new file mode 100644 index 0000000..1324788 --- /dev/null +++ b/weather-cli/__dev/complex/complex/cli.py @@ -0,0 +1,68 @@ +import os +import sys +import click + +CONTEXT_SETTINGS = dict(auto_envvar_prefix='COMPLEX') + + +class Environment(object): + + def __init__(self): + self.verbose = False + self.home = os.getcwd() + + def log(self, msg, *args): + """Logs a message to stderr.""" + if args: + msg %= args + click.echo(msg, file=sys.stderr) + + def vlog(self, msg, *args): + """Logs a message to stderr only if verbose is enabled.""" + if self.verbose: + self.log(msg, *args) + + +pass_environment = click.make_pass_decorator(Environment, ensure=True) +cmd_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), + 'commands')) + + +class ComplexCLI(click.MultiCommand): + + def list_commands(self, ctx): + rv = [] + for filename in os.listdir(cmd_folder): + if filename.endswith('.py') and \ + filename.startswith('cmd_'): + rv.append(filename[4:-3]) + rv.sort() + return rv + + def get_command(self, ctx, name): + try: + if sys.version_info[0] == 2: + name = name.encode('ascii', 'replace') + mod = __import__('complex.commands.cmd_' + name, + None, None, ['cli']) + except ImportError: + return + return mod.cli + + +@click.command(cls=ComplexCLI, context_settings=CONTEXT_SETTINGS) +@click.option('--home', type=click.Path(exists=True, file_okay=False, + resolve_path=True), + help='Changes the folder to operate on.') +@click.option('-v', '--verbose', is_flag=True, + help='Enables verbose mode.') +@pass_environment +def cli(ctx, verbose, home): + """A complex command line interface.""" + ctx.verbose = verbose + if home is not None: + ctx.home = home + + +if __name__ == '__main__': + cli() diff --git a/weather-cli/__dev/complex/complex/commands/__init__.py b/weather-cli/__dev/complex/complex/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/weather-cli/__dev/complex/complex/commands/cmd_init.py b/weather-cli/__dev/complex/complex/commands/cmd_init.py new file mode 100644 index 0000000..6a21d0f --- /dev/null +++ b/weather-cli/__dev/complex/complex/commands/cmd_init.py @@ -0,0 +1,15 @@ +import click +from complex.cli import pass_environment + + +@click.command('init', short_help='Initializes a repo.') +@click.argument('path', required=False, type=click.Path(resolve_path=True)) +@pass_environment +def cli(ctx, path): + """Initializes a repository.""" + print(f'{ctx=}') + print(f'{dir(ctx)=}') + if path is None: + path = ctx.home + ctx.log('Initialized the repository in %s', + click.format_filename(path)) diff --git a/weather-cli/__dev/complex/complex/commands/cmd_status.py b/weather-cli/__dev/complex/complex/commands/cmd_status.py new file mode 100644 index 0000000..12229c4 --- /dev/null +++ b/weather-cli/__dev/complex/complex/commands/cmd_status.py @@ -0,0 +1,10 @@ +import click +from complex.cli import pass_environment + + +@click.command('status', short_help='Shows file changes.') +@pass_environment +def cli(ctx): + """Shows file changes in the current working directory.""" + ctx.log('Changed files: none') + ctx.vlog('bla bla bla, debug info') diff --git a/weather-cli/__dev/complex/complex/text b/weather-cli/__dev/complex/complex/text new file mode 100644 index 0000000..9930b21 --- /dev/null +++ b/weather-cli/__dev/complex/complex/text @@ -0,0 +1,16 @@ +. +โ”œโ”€โ”€ __init__.py +โ”œโ”€โ”€ __pycache__ +โ”‚ โ”œโ”€โ”€ __init__.cpython-38.pyc +โ”‚ โ””โ”€โ”€ cli.cpython-38.pyc +โ”œโ”€โ”€ cli.py +โ”œโ”€โ”€ commands +โ”‚ โ”œโ”€โ”€ __init__.py +โ”‚ โ”œโ”€โ”€ __pycache__ +โ”‚ โ”‚ โ”œโ”€โ”€ __init__.cpython-38.pyc +โ”‚ โ”‚ โ”œโ”€โ”€ cmd_init.cpython-38.pyc +โ”‚ โ”‚ โ””โ”€โ”€ cmd_status.cpython-38.pyc +โ”‚ โ”œโ”€โ”€ cmd_init.py +โ”‚ โ”œโ”€โ”€ cmd_status.py +โ”‚ โ””โ”€โ”€ test +โ””โ”€โ”€ text diff --git a/weather-cli/__dev/complex/setup.py b/weather-cli/__dev/complex/setup.py new file mode 100644 index 0000000..dee002c --- /dev/null +++ b/weather-cli/__dev/complex/setup.py @@ -0,0 +1,15 @@ +from setuptools import setup + +setup( + name='click-example-complex', + version='1.0', + packages=['complex', 'complex.commands'], + include_package_data=True, + install_requires=[ + 'click', + ], + entry_points=''' + [console_scripts] + complex=complex.cli:cli + ''', +) diff --git a/weather-cli/__dev/documentation_todo b/weather-cli/__dev/documentation_todo new file mode 100644 index 0000000..5ffe843 --- /dev/null +++ b/weather-cli/__dev/documentation_todo @@ -0,0 +1,81 @@ + +https://click.palletsprojects.com/en/7.x/#documentation +https://dbader.org/blog/mastering-click-advanced-python-command-line-apps + +Use click but with the poetry cleo style of importing and structuring the commands + +@click.command() - creates a command out of the function + +@click.argument('name') - creates an argument for the command +(e.g poetry install, install is the argument) + +@click.option - creates options for the command +pass the option flags as strings, '--option', '-o' +pass a help string , help='help string' +specify to use an os env , envvar="API_KEY" + + + +https://click.palletsprojects.com/en/5.x/options/ + +- use / in an option to set a flag as true of false + +setting arguments: https://click.palletsprojects.com/en/5.x/arguments/#arguments + + +https://github.com/pallets/click/tree/master/examples/complex/complex +for a good example on structure using click in a module + + +Callbacks and eager options to implement flags such as a version +https://click.palletsprojects.com/en/5.x/options/#callbacks-and-eager-options + +Can use +@click.version_option(version=version) +to implement a version + + + +Make pass decorator explained: +https://stackoverflow.com/questions/49511933/better-usage-of-make-pass-decorator-in-python-click + +Show how to run command line programs from within a script from the example above ^^ + + +For complex example: + +We use the class Environment to store any base arguments passed (e.g a path) +This is optional, but is useful if we need an argument initially and want to do something to use it later in another subcommand. + +This gets passed as a decorator to each command we create + +We can then use this class to retrieve the inputs in each command in each module + +We use this class to also handle logging, using click.echo() to print things if needed. + +We avoid using the group functionality in click, by using a custom class that inherits from click.MultiCommand. + +We can use this class to override the list_commands() and get_command() methods to list and do the commands we write. + +Each one of those commands can go in their own folder, be decorated with the Environment class and have their commands passed + +ctx refers to the instance of the class we passed in with the decorator when using click.make_pass_decorator() + +when using this decorator, the first argument to the function will refer to the instanced class we passed in + + +we can also import defaults which we can store in a class + +say we have a class that reads default values from a config file locally. it also sets default values without a config file. we store all of this in a class using properties. + +when creating an option we can use this class to fall back on if the option isnt passed to the command. to do this we create a subclass of click.Option, and use 2 closures. + +2 closures are needed because we pass in 2 things: the settings instance class and the value of the option itself. + +this allows to use the class attributes when creating options, and also allows us access to attributes when writing the commands, without needing two seperate instances + +we could avoid doing this, by following the complex example. here there is one class which is passed in, but the default aren't set in click. instead the defauts are set in a class and passed in with the decorator. + +we can have a class for each command that needs it, and we set the defaults by putting a if option is None in the command/subcommand itself, and setting the value to the class value if it's not provided. + +if we do it this way, we would need a class for each command that needs it, and pass it in. or we could have one class, and use the method above to do it. diff --git a/weather-cli/__dev/testingclass.py b/weather-cli/__dev/testingclass.py new file mode 100644 index 0000000..db1787e --- /dev/null +++ b/weather-cli/__dev/testingclass.py @@ -0,0 +1,87 @@ +import click +import sys +import time + + +def build_settings_option_class(settings_instance): + def set_default(default_name): + class Cls(click.Option): + def __init__(self, *args, **kwargs): + kwargs['default'] = getattr(settings_instance, default_name) + super(Cls, self).__init__(*args, **kwargs) + + def handle_parse_result(self, ctx, opts, args): + obj = ctx.find_object(type(settings_instance)) + if obj is None: + ctx.obj = settings_instance + + return super(Cls, self).handle_parse_result(ctx, opts, args) + + return Cls + + return set_default + + +class Settings(object): + def __init__(self): + self.instance_disk_size = 100 + self.instance_disk_type = 'pd-ssd' + + +# import pudb; pudb.set_trace() +settings = Settings() +settings_option_cls = build_settings_option_class(settings) +pass_settings = click.make_pass_decorator(Settings) + + +@click.command() +@click.help_option('-h', '--help') +@click.option( + '-s', + '--disk-size', + cls=settings_option_cls('instance_disk_size'), + help="Disk size", + show_default=True, + type=int, +) +@click.option( + '-t', + '--disk-type', + cls=settings_option_cls('instance_disk_type'), + help="Disk type", + show_default=True, + type=click.Choice(['pd-standard', 'pd-ssd']), +) +@pass_settings +def create(settings_test, disk_size, disk_type): + print(f'{settings_test.instance_disk_type=}') + # print(f'{dir(settings_test)=}') + print(disk_size) + print(disk_type) + + +if __name__ == "__main__": + commands = ( + '-t pd-standard -s 200', + '-t pd-standard', + '-s 200', + '', + '--help', + ) + + time.sleep(1) + print('Click Version: {}'.format(click.__version__)) + print('Python Version: {}'.format(sys.version)) + for cmd in commands: + try: + time.sleep(0.1) + print('-----------') + print('> ' + cmd) + time.sleep(0.1) + create(cmd.split()) + + except BaseException as exc: + if str(exc) != '0' and not isinstance( + exc, (click.ClickException, SystemExit) + ): + raise diff --git a/weather-cli/poetry.lock b/weather-cli/poetry.lock new file mode 100644 index 0000000..4791724 --- /dev/null +++ b/weather-cli/poetry.lock @@ -0,0 +1,179 @@ +[[package]] +category = "dev" +description = "Atomic file writes." +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.3.0" + +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2019.9.11" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "main" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "7.0" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.4.1" + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.8" + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.4" +version = "7.2.0" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" + +[[package]] +category = "dev" +description = "A full-screen, console-based Python debugger" +name = "pudb" +optional = false +python-versions = "*" +version = "2019.2" + +[package.dependencies] +pygments = ">=1.0" +urwid = ">=1.1.1" + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.0" + +[[package]] +category = "dev" +description = "Pygments is a syntax highlighting package written in Python." +name = "pygments" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.4.2" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.10.1" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +pluggy = ">=0.7" +py = ">=1.5.0" +setuptools = "*" +six = ">=1.10.0" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.22.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<3.1.0" +idna = ">=2.5,<2.9" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.13.0" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" +version = "1.25.7" + +[[package]] +category = "dev" +description = "A full-featured console (xterm et al.) user interface library" +name = "urwid" +optional = false +python-versions = "*" +version = "2.1.0" + +[metadata] +content-hash = "a616bd3aec3b75e8103ccaa821e9b7029caa70647f38a2cf7e492f651aa3772c" +python-versions = "^3.8" + +[metadata.hashes] +atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"] +attrs = ["08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", "f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"] +certifi = ["e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", "fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +click = ["2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"] +colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] +idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] +pluggy = ["15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", "966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"] +pudb = ["e8f0ea01b134d802872184b05bffc82af29a1eb2f9374a277434b932d68f58dc"] +py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] +pygments = ["71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", "881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"] +pytest = ["3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec", "e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"] +requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] +six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"] +urllib3 = ["a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", "f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"] +urwid = ["0896f36060beb6bf3801cb554303fef336a79661401797551ba106d23ab4cd86"] diff --git a/test-env/pyproject.toml b/weather-cli/pyproject.toml similarity index 59% rename from test-env/pyproject.toml rename to weather-cli/pyproject.toml index 8a74a3e..4c54526 100644 --- a/test-env/pyproject.toml +++ b/weather-cli/pyproject.toml @@ -1,16 +1,17 @@ [tool.poetry] -name = "test-env" +name = "weather-cli" version = "0.1.0" description = "" -authors = ["Your Name "] +authors = ["dtomlinson "] [tool.poetry.dependencies] python = "^3.8" -numpy = "^1.17" -pytest = "^5.2" +requests = "^2.22" +click = "^7.0" [tool.poetry.dev-dependencies] -PdbSublimeTextSupport = "^0.2.0" +pytest = "^3.0" +pudb = "^2019.2" [build-system] requires = ["poetry>=0.12"] diff --git a/weather-cli/src/weather_cli/__init__.py b/weather-cli/src/weather_cli/__init__.py new file mode 100644 index 0000000..09b07be --- /dev/null +++ b/weather-cli/src/weather_cli/__init__.py @@ -0,0 +1,13 @@ +from .__version__ import __version__ # noqa +import requests + + +def current_weather(location, api_key): + url = 'https://api.openweathermap.org/data/2.5/weather' + + query_params = { + 'q': location, + 'appid': api_key, + } + response = requests.get(url, params=query_params) + return response.json()['weather'][0]['description'] diff --git a/test-env/test_env/__init__.py b/weather-cli/src/weather_cli/__version__.py similarity index 100% rename from test-env/test_env/__init__.py rename to weather-cli/src/weather_cli/__version__.py diff --git a/weather-cli/src/weather_cli/console/__init__.py b/weather-cli/src/weather_cli/console/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/weather-cli/src/weather_cli/console/console.py b/weather-cli/src/weather_cli/console/console.py new file mode 100644 index 0000000..892b916 --- /dev/null +++ b/weather-cli/src/weather_cli/console/console.py @@ -0,0 +1,27 @@ +import weather_cli +import click + + +@click.group() +@click.version_option(version=weather_cli.__version__) +def main(version): + pass + + +@main.command() +@click.argument('location') +@click.option( + '--api-key', '-a', help='your API key for the OpenWeatherMap API' +) +def current(location: str, api_key: str): + """Query the openWeather API for the current weather conditions + """ + # import pudb; pudb.set_trace() + if api_key is None: + api_key = weather_cli.SAMPLE_API_KEY + weather = weather_cli.current_weather(location=location, api_key=api_key) + print(f'The weather in {location} is {weather}') + + +if __name__ == "__main__": + main() diff --git a/weather-cli/tests/test_weather_cli.py b/weather-cli/tests/test_weather_cli.py new file mode 100644 index 0000000..1e91582 --- /dev/null +++ b/weather-cli/tests/test_weather_cli.py @@ -0,0 +1,7 @@ +import weather_cli + +london = weather_cli.current_weather( + 'Leeds', 'ed0172b84ddf4e63a2860957644f91fb' +) + +print(london)