From 81a5e66b60d2584cab6223ce6606aee59a4ccf31 Mon Sep 17 00:00:00 2001 From: emdee Date: Thu, 17 Nov 2022 08:07:23 +0000 Subject: [PATCH] added setup.cfg --- __init__.py | 0 appveyor.yml | 22 ++++++++ phantompy/__init__.py | 3 ++ __main__.py => phantompy/__main__.py | 9 ++-- lookupdns.py => phantompy/lookupdns.py | 0 phantompy.py => phantompy/phantompy.py | 30 +++++------ .../qasync_phantompy.py | 28 ++++++---- .../support_phantompy.py | 9 ++-- setup.cfg | 52 +++++++++++++++++++ setup.py | 8 +-- tests/conftest.py | 28 ++++++++++ 11 files changed, 153 insertions(+), 36 deletions(-) delete mode 100644 __init__.py create mode 100644 appveyor.yml create mode 100644 phantompy/__init__.py rename __main__.py => phantompy/__main__.py (69%) rename lookupdns.py => phantompy/lookupdns.py (100%) rename phantompy.py => phantompy/phantompy.py (93%) rename qasync_phantompy.py => phantompy/qasync_phantompy.py (90%) rename support_phantompy.py => phantompy/support_phantompy.py (98%) create mode 100644 setup.cfg create mode 100644 tests/conftest.py diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..8241a6d --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,22 @@ +environment: + matrix: + - PYTHON: "C:\\Python36" + - PYTHON: "C:\\Python37" + - PYTHON: "C:\\Python38" + - PYTHON: "C:\\Python39" + +init: + - set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% + +install: + - pip install pipenv + - pipenv install --dev + - pipenv run pip install PyQt5 PySide2 + # FIX: colorama not installed by pipenv + - pipenv run pip install colorama + +build: off + +test_script: + - set QT_API=PyQt5&& pipenv run py.test -v + - set QT_API=PySide2&& pipenv run py.test -v diff --git a/phantompy/__init__.py b/phantompy/__init__.py new file mode 100644 index 0000000..b8cbc42 --- /dev/null +++ b/phantompy/__init__.py @@ -0,0 +1,3 @@ +# -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 2; coding: utf-8 -*- + +__version__ = "0.1.0" diff --git a/__main__.py b/phantompy/__main__.py similarity index 69% rename from __main__.py rename to phantompy/__main__.py index 6b975db..bbc9d62 100644 --- a/__main__.py +++ b/phantompy/__main__.py @@ -1,10 +1,13 @@ #!/usr/local/bin/python3.sh # -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -* -from qasync_phantompy import iMain +from __future__ import absolute_import +import sys + +from .qasync_phantompy import iMain try: - from support_phantompy import vsetup_logging + from .support_phantompy import vsetup_logging d = int(os.environ.get('DEBUG', 0)) if d > 0: vsetup_logging(10, stream=sys.stderr) @@ -14,4 +17,4 @@ try: except: pass if __name__ == '__main__': - iMain(sys.argv[1:], bgui=False) + iMain(sys.argv[1:]) diff --git a/lookupdns.py b/phantompy/lookupdns.py similarity index 100% rename from lookupdns.py rename to phantompy/lookupdns.py diff --git a/phantompy.py b/phantompy/phantompy.py similarity index 93% rename from phantompy.py rename to phantompy/phantompy.py index a2bff2d..e8da790 100644 --- a/phantompy.py +++ b/phantompy/phantompy.py @@ -118,21 +118,20 @@ 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. """ -import sys +import importlib import os -import traceback -import atexit -import time +import sys # noqa -from PyQt5.QtCore import QUrl -from PyQt5.QtCore import QTimer -from PyQt5.QtWidgets import QApplication -from PyQt5.QtPrintSupport import QPrinter -from PyQt5.QtWebEngineWidgets import QWebEnginePage +from qasync import QtModuleName +from qasync.QtCore import QUrl + +QPrinter = importlib.import_module(QtModuleName + ".QtPrintSupport.QPrinter", package=QtModuleName) +QWebEnginePage = importlib.import_module(QtModuleName + ".QtWebEngineWidgets.QWebEnginePage", package=QtModuleName) global LOG import logging import warnings + warnings.filterwarnings('ignore') LOG = logging.getLogger() @@ -181,19 +180,19 @@ class Render(QWebEnginePage): self.htmlfile = htmlfile self.pdffile = pdffile self.outfile = pdffile or htmlfile - LOG.debug(f"phantom.py: URL={url} OUTFILE={outfile} JSFILE={jsfile}") + LOG.debug(f"phantom.py: URL={url} htmlfile={htmlfile} pdffile={pdffile} JSFILE={jsfile}") qurl = QUrl.fromUserInput(url) # The PDF generation only happens when the special string __PHANTOM_PY_DONE__ # is sent to console.log(). The following JS string will be executed by # default, when no external JavaScript file is specified. - self.js_contents = "setTimeout(function() { console.log('__PHANTOM_PY_DONE__') }, 5000);"; + self.js_contents = "setTimeout(function() { console.log('__PHANTOM_PY_DONE__') }, 5000);" if jsfile: try: with open(self.jsfile, 'rt') as f: self.js_contents = f.read() - except Exception as e: + except Exception as e: # noqa LOG.exception(f"error reading jsfile {self.jsfile}") self.loadFinished.connect(self._loadFinished) @@ -239,7 +238,7 @@ class Render(QWebEnginePage): """print(self, QPrinter, Callable[[bool], None])""" if type(args[0]) is str: self._save(args[0]) - self._onConsoleMessage(0, "__PHANTOM_PY_SAVED__", 0 , '') + self._onConsoleMessage(0, "__PHANTOM_PY_SAVED__", 0, '') def _save(self, html): sfile = self.htmlfile @@ -254,7 +253,7 @@ class Render(QWebEnginePage): i = 1 else: i = 0 - self._onConsoleMessage(i, "__PHANTOM_PY_PRINTED__", 0 , '') + self._onConsoleMessage(i, "__PHANTOM_PY_PRINTED__", 0, '') def _print(self): sfile = self.pdffile @@ -262,7 +261,7 @@ class Render(QWebEnginePage): printer.setPageMargins(10, 10, 10, 10, QPrinter.Millimeter) printer.setPaperSize(QPrinter.A4) printer.setCreator("phantom.py by Michael Karl Franzl") - printer.setOutputFormat(QPrinter.PdfFormat); + printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(sfile) self.print(printer, self._printer_callback) LOG.debug("phantom.py: Printed") @@ -272,4 +271,3 @@ class Render(QWebEnginePage): LOG.debug(f"phantom.py: Exiting with val {val}") # threadsafe? self._app.ldone.append(self.uri) - diff --git a/qasync_phantompy.py b/phantompy/qasync_phantompy.py similarity index 90% rename from qasync_phantompy.py rename to phantompy/qasync_phantompy.py index 99927ba..5a01d65 100644 --- a/qasync_phantompy.py +++ b/phantompy/qasync_phantompy.py @@ -1,26 +1,30 @@ #!/usr/local/bin/python3.sh # -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -* -import sys -import os import asyncio -import time -import random +import os +import sys # let qasync figure out what Qt we are using - we dont care -from qasync import QApplication, QtWidgets, QEventLoop +from qasync import QApplication, QEventLoop, QtWidgets from phantompy import Render # if you want an example of looking for things in downloaded HTML: # from lookupdns import LookFor as Render -from support_phantompy import vsetup_logging, omain_argparser +from support_phantompy import omain_argparser, vsetup_logging global LOG import logging import warnings + warnings.filterwarnings('ignore') LOG = logging.getLogger() +try: + import shtab +except: + shtab = None + class Widget(QtWidgets.QWidget): def __init__(self): QtWidgets.QWidget.__init__(self) @@ -38,13 +42,17 @@ class Widget(QtWidgets.QWidget): self.progress.setValue(int(text)) class ContextManager: + def __init__(self) -> None: self._seconds = 0 + async def __aenter__(self): LOG.debug("ContextManager enter") return self + async def __aexit__(self, *args): LOG.debug("ContextManager exit") + async def tick(self): await asyncio.sleep(1) self._seconds += 1 @@ -65,13 +73,15 @@ async def main(widget, app, ilen): # raise asyncio.CancelledError return LOG.debug(f"{app.ldone} {seconds}") - except asyncio.CancelledError as ex: + except asyncio.CancelledError as ex: # noqa LOG.debug("Task cancelled") def iMain(largs): parser = omain_argparser() + if shtab: + shtab.add_argument_to(parser, ["-s", "--print-completion"]) # magic! oargs = parser.parse_args(largs) - bgui=oargs.show_gui + bgui = oargs.show_gui try: d = int(os.environ.get('DEBUG', 0)) @@ -115,6 +125,4 @@ def iMain(largs): loop.run_until_complete(asyncio.gather(*tasks)) if __name__ == '__main__': - iMain(sys.argv[1:]) - diff --git a/support_phantompy.py b/phantompy/support_phantompy.py similarity index 98% rename from support_phantompy.py rename to phantompy/support_phantompy.py index 1c81f3f..4b957b4 100644 --- a/support_phantompy.py +++ b/phantompy/support_phantompy.py @@ -1,21 +1,22 @@ #!/usr/local/bin/python3.sh # -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -* -import sys -import os import argparse +import os +import sys try: if 'COLOREDLOGS_LEVEL_STYLES' not in os.environ: os.environ['COLOREDLOGS_LEVEL_STYLES'] = 'spam=22;debug=28;verbose=34;notice=220;warning=202;success=118,bold;error=124;critical=background=red' # https://pypi.org/project/coloredlogs/ import coloredlogs -except ImportError as e: +except ImportError: coloredlogs = False global LOG import logging import warnings + warnings.filterwarnings('ignore') LOG = logging.getLogger() @@ -24,7 +25,7 @@ def vsetup_logging(log_level, logfile='', stream=sys.stdout): add = True # stem fucks up logging - from stem.util import log + # from stem.util import log logging.getLogger('stem').setLevel(30) logging._defaultFormatter = logging.Formatter(datefmt='%m-%d %H:%M:%S') diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..8b5b3d5 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,52 @@ +[metadata] +classifiers = + License :: OSI Approved + License :: OSI Approved :: BSD 1-clause + Intended Audience :: Web Developers + Operating System :: Microsoft :: Windows + Operating System :: POSIX :: BSD :: FreeBSD + Operating System :: POSIX :: Linux + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: Implementation :: CPython + Framework :: AsyncIO + +[options] +zip_safe = false +python_requires = ~=3.6 +packages = find: +include_package_data = false +install_requires = + qasync + attrs + typing-extensions ; python_version < '3.8' + +[options.entry_points] +console_scripts = + phantompy = phantompy.__main__:iMain + +[easy_install] +zip_ok = false + +[flake8] +jobs = 1 +max-line-length = 88 +ignore = + E111 + E114 + E225 + E261 + E302 + E305 + E402 + E501 + E502 + E541 + E701 + E722 + E741 + F541 + diff --git a/setup.py b/setup.py index bdf9f6e..b3aceb4 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,10 @@ # -*-mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -* +import re from setuptools import setup -__version__ = "0.1.0" +with open("qasync/__init__.py") as f: + version = re.search(r'__version__\s+=\s+"(.*)"', f.read()).group(1) long_description = "\n\n".join([ open("README.md").read(), @@ -20,9 +22,9 @@ if __name__ == '__main__': packages=['phantompy'], # url="", # download_url="https://", - keywords=['JavaScript', 'phantomjs'], + keywords=['JavaScript', 'phantomjs', 'asyncio'], # maybe less - nothing fancy - python_requires=">=3.6", + python_requires="~=3.6", # probably works on PyQt6 and PySide2 but untested # https://github.com/CabbageDevelopment/qasync/ install_requires=['qasync', 'PyQt5'], diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..3e04987 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,28 @@ +# © 2018 Gerard Marull-Paretas +# © 2014 Mark Harviston +# © 2014 Arve Knudsen +# BSD License + +# phantompy test - just test qasync for now + +import os +import logging +from pytest import fixture + + +logging.basicConfig( + level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(name)s - %(message)s" +) + + +if os.name == "nt": + collect_ignore = ["qasync/_unix.py"] +else: + collect_ignore = ["qasync/_windows.py"] + + +@fixture(scope="session") +def application(): + from phantompy.qasync_phantompy import QApplication + + return QApplication([])