From f172becb671bfea33e1a9eb9be140157976240d0 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Sat, 8 Oct 2022 12:10:34 -0700 Subject: [PATCH 1/5] update package --- .github/workflows/python-package.yml | 56 ++++++++++---------- MANIFEST.in | 1 + ptwit.py | 31 ++++------- requirements.txt | 3 ++ setup.py | 79 +++++++++++++++++----------- 5 files changed, 90 insertions(+), 80 deletions(-) create mode 100644 requirements.txt diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 157781f..ecced4a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,42 +5,42 @@ name: Python package on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: build: strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: ["3.7", "3.8", "3.9", "3.10"] platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - python3 setup.py install - python3 -m pip install -r requirements-dev.txt - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Lint with black - run: | - black --check mapillary_tools tests - - name: Type check with mypy - run: | - mypy ptwit.py tests.py - - name: Test with pytest - run: | - pytest tests.py + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + python3 setup.py install + python3 -m pip install -r requirements-dev.txt + - name: Lint with flake8 + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Lint with black + run: | + black --check ptwit.py + - name: Type check with mypy + run: | + mypy ptwit.py tests.py + - name: Test with pytest + run: | + pytest tests.py diff --git a/MANIFEST.in b/MANIFEST.in index a5021c6..8da04a0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include README.rst include LICENSE +include requirements.txt diff --git a/ptwit.py b/ptwit.py index 2671a1d..d9c9897 100644 --- a/ptwit.py +++ b/ptwit.py @@ -1,26 +1,24 @@ #!/usr/bin/env python3 +import configparser +import json import os +import re import sys -import errno -from functools import update_wrapper +import typing as T from datetime import datetime -from string import Formatter -import json -import re -import configparser +from functools import update_wrapper from html import unescape as html_unescape -from urllib.parse import parse_qsl -import typing as T +from string import Formatter -import twitter import click +import twitter from click_default_group import DefaultGroup from requests_oauthlib import OAuth1Session from requests_oauthlib.oauth1_session import TokenRequestDenied -__version__ = "0.3" +__VERSION__ = "0.3" MAX_COUNT = 200 @@ -161,17 +159,6 @@ def save(self, filename=None) -> "TwitterConfig": return self -# http://stackoverflow.com/a/600612/114833 -def mkdir(path: str) -> None: - try: - os.makedirs(path) - except OSError as exc: - if exc.errno == errno.EEXIST and os.path.isdir(path): - pass - else: - raise - - @click.group(cls=DefaultGroup, default="timeline", default_if_no_args=True) @click.option("--account", "-a", help="Use this account instead of the default one.") @click.option( @@ -187,7 +174,7 @@ def mkdir(path: str) -> None: @click.pass_context def ptwit(ctx: click.Context, account: T.Optional[str], format: str) -> None: config_dir = click.get_app_dir("ptwit") - mkdir(config_dir) + os.makedirs(config_dir, exist_ok=True) config = TwitterConfig(os.path.join(config_dir, "ptwit.conf")) if account is None: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..48d2084 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +python-twitter +click-default-group +click diff --git a/setup.py b/setup.py index a59f37e..06d6923 100644 --- a/setup.py +++ b/setup.py @@ -1,40 +1,59 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- -try: - from setuptools import setup -except ImportError: - from distutils.core import setup +import os +from setuptools import setup + + +here = os.path.abspath(os.path.dirname(__file__)) def readme(): - with open('README.rst') as f: + with open("README.rst") as f: return f.read() -setup(name='ptwit', - version='0.3', - description='A simple twitter command line client', - long_description=readme(), - classifiers=[ - 'Development Status :: 5 - Beta', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Environment :: Console', - 'Intended Audience :: End Users/Desktop', - 'Topic :: Utilities'], - url='https://github.com/ptpt/ptwit', - author='Tao Peng', - author_email='ptpttt+ptwit@gmail.com', - keywords='twitter, command-line, client', - license='MIT', - py_modules=['ptwit'], - install_requires=['python-twitter', 'click-default-group', 'click'], - entry_points=''' +def read_requirements(): + with open("requirements.txt") as fp: + return [row.strip() for row in fp if row.strip()] + + +about: dict = {} +with open(os.path.join(here, "ptwit.py"), "r") as f: + while True: + line = f.readline() + if not line: + break + if line.startswith("__VERSION__"): + exec(line, about) + break + + +setup( + name="ptwit", + version=about["__VERSION__"], + description="A simple twitter command line client", + long_description=readme(), + classifiers=[ + "Development Status :: 5 - Beta", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Environment :: Console", + "Intended Audience :: End Users/Desktop", + "Topic :: Utilities", + ], + url="https://github.com/ptpt/ptwit", + author="Tao Peng", + author_email="ptpttt+ptwit@gmail.com", + keywords="twitter, command-line, client", + license="MIT", + py_modules=["ptwit"], + install_requires=read_requirements(), + entry_points=""" [console_scripts] ptwit=ptwit:cli - ''', - zip_safe=False) + """, + zip_safe=False, +) From 9453c78471e0a10e6b38a2319faa5543543e6714 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Sat, 8 Oct 2022 12:18:12 -0700 Subject: [PATCH 2/5] install requests_oauthlib --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 48d2084..2c7bd3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ python-twitter click-default-group click +requests_oauthlib From b0106534da4465bceb945fabd0371bd4b69b6710 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Sat, 8 Oct 2022 12:22:31 -0700 Subject: [PATCH 3/5] fix types --- ptwit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ptwit.py b/ptwit.py index d9c9897..ee58e41 100644 --- a/ptwit.py +++ b/ptwit.py @@ -490,7 +490,7 @@ def read_text(words: T.List[str]) -> str: text = " ".join(words) click.confirm(f'Post "{text}"?', abort=True) else: - text = click.edit() + text = click.edit() or "" return text From 7539b3cce9a283ee73c270166471de8b025df141 Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Sat, 8 Oct 2022 12:38:25 -0700 Subject: [PATCH 4/5] fix tests --- tests.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests.py b/tests.py index 81512ae..d7dace9 100644 --- a/tests.py +++ b/tests.py @@ -13,15 +13,8 @@ def tearDown(self): os.remove(self.filename) def test_open(self): - filename = tempfile.mktemp() - # Create if config file does not exist - config = TwitterConfig(filename) - self.assertFalse(os.path.isfile(filename)) - # If the path is a directory? - dirname = tempfile.mkdtemp() - config = TwitterConfig(dirname) - self.assertRaises(IOError, config.save) - os.removedirs(dirname) + TwitterConfig("./hello") + self.assertFalse(os.path.exists("./hello")) def test_set(self): config = TwitterConfig(self.filename) From f523136c3ef55450aaf667e5f389a9baf98f0b8e Mon Sep 17 00:00:00 2001 From: Tao Peng Date: Sat, 8 Oct 2022 12:42:12 -0700 Subject: [PATCH 5/5] fix tests again --- tests.py | 84 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests.py b/tests.py index d7dace9..c289acb 100644 --- a/tests.py +++ b/tests.py @@ -6,63 +6,63 @@ class TestTwitterConfig(unittest.TestCase): - def setUp(self): - _, self.filename = tempfile.mkstemp() - - def tearDown(self): - os.remove(self.filename) - def test_open(self): TwitterConfig("./hello") self.assertFalse(os.path.exists("./hello")) def test_set(self): - config = TwitterConfig(self.filename) - config.set("option", "value") # Save hello=world to general section - config.set("name", "tao", account="Tao") - config.set("name", "mian", account="Mian") - self.assertEqual(config.config.items("general"), [("option", "value")]) - self.assertEqual(config.config.items("Tao"), [("name", "tao")]) - self.assertEqual(config.config.items("Mian"), [("name", "mian")]) + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + config.set("option", "value") # Save hello=world to general section + config.set("name", "tao", account="Tao") + config.set("name", "mian", account="Mian") + self.assertEqual(config.config.items("general"), [("option", "value")]) + self.assertEqual(config.config.items("Tao"), [("name", "tao")]) + self.assertEqual(config.config.items("Mian"), [("name", "mian")]) def test_get(self): - config = TwitterConfig(self.filename) - config.set("option", "value") - config.set("format", "json", account="Tao") - self.assertEqual(config.get("option"), "value") - self.assertEqual(config.get("format", account="Tao"), "json") + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + config.set("option", "value") + config.set("format", "json", account="Tao") + self.assertEqual(config.get("option"), "value") + self.assertEqual(config.get("format", account="Tao"), "json") def test_unset(self): - config = TwitterConfig(self.filename) - config.set("option", "value") - config.set("format", "json", account="Tao") - config.unset("format", account="Tao") - config.unset("option") - self.assertIsNone(config.get("format", account="Tao")) - self.assertIsNone(config.get("option")) + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + config.set("option", "value") + config.set("format", "json", account="Tao") + config.unset("format", account="Tao") + config.unset("option") + self.assertIsNone(config.get("format", account="Tao")) + self.assertIsNone(config.get("option")) def test_remove_account(self): - config = TwitterConfig(self.filename) - config.set("option", "value", account="Tao") - config.remove_account("Tao") + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + config.set("option", "value", account="Tao") + config.remove_account("Tao") def test_list_account(self): - config = TwitterConfig(self.filename) - self.assertEqual(config.list_accounts(), []) - config.set("option", "value") - config.set("option", "value", account="Tao") - self.assertEqual(config.list_accounts(), ["Tao"]) + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + self.assertEqual(config.list_accounts(), []) + config.set("option", "value") + config.set("option", "value", account="Tao") + self.assertEqual(config.list_accounts(), ["Tao"]) def test_save(self): - config = TwitterConfig(self.filename) - config.set("option", "value") - config.set("name", "Tao", account="Tao") - config.save() - with open(self.filename) as fp: - content = fp.read() - self.assertTrue(content.find("general")) - self.assertTrue(content.find("Tao")) - self.assertTrue(content.find("name")) + with tempfile.NamedTemporaryFile() as tmp: + config = TwitterConfig(tmp.name) + config.set("option", "value") + config.set("name", "Tao", account="Tao") + config.save() + with open(tmp.name) as fp: + content = fp.read() + self.assertTrue(content.find("general")) + self.assertTrue(content.find("Tao")) + self.assertTrue(content.find("name")) if __name__ == "__main__":