From d755878bd28f7b658426bf1df2e9a3eb6c52ae2e Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 7 Sep 2024 19:59:02 +0200 Subject: [PATCH] Migrate to pyproject.toml build --- MANIFEST.in | 2 + cps/constants.py | 4 +- cps/web.py | 4 ++ pyproject.toml | 123 +++++++++++++++++++++++++++++++++++++++++++++++ setup.cfg | 110 ------------------------------------------ setup.py | 43 ----------------- 6 files changed, 130 insertions(+), 156 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in index b667159c..f07c4d83 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,3 @@ graft src/calibreweb +global-exclude __pycache__ +global-exclude *.pyc diff --git a/cps/constants.py b/cps/constants.py index 3d1f0dfe..36bbe749 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -19,9 +19,6 @@ import sys import os from collections import namedtuple -from sqlalchemy import __version__ as sql_version - -sqlalchemy_version2 = ([int(x) for x in sql_version.split('.')] >= [2, 0, 0]) # APP_MODE - production, development, or test APP_MODE = os.environ.get('APP_MODE', 'production') @@ -176,6 +173,7 @@ BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, d # python build process likes to have x.y.zbw -> b for beta and w a counting number STABLE_VERSION = {'version': '0.6.24b'} +_version = STABLE_VERSION['version'] NIGHTLY_VERSION = dict() NIGHTLY_VERSION[0] = '$Format:%H$' diff --git a/cps/web.py b/cps/web.py index 8277a763..afc4669a 100644 --- a/cps/web.py +++ b/cps/web.py @@ -36,6 +36,7 @@ from sqlalchemy.exc import IntegrityError, InvalidRequestError, OperationalError from sqlalchemy.sql.expression import text, func, false, not_, and_, or_ from sqlalchemy.orm.attributes import flag_modified from sqlalchemy.sql.functions import coalesce +from sqlalchemy import __version__ as sql_version from werkzeug.datastructures import Headers from werkzeug.security import generate_password_hash, check_password_hash @@ -86,6 +87,9 @@ except ImportError: sort = sorted # Just use regular sort then, may cause issues with badly named pages in cbz/cbr files +sqlalchemy_version2 = ([int(x) for x in sql_version.split('.')] >= [2, 0, 0]) + + @app.after_request def add_security_headers(resp): default_src = ([host.strip() for host in config.config_trustedhosts.split(',') if host] + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..54d07cab --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,123 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "calibreweb" +description = "Web app for browsing, reading and downloading eBooks stored in a Calibre database." +authors = [{name = "@OzzieIsaacs", email = "Ozzie.Fernandez.Isaacs@googlemail.com"}] +maintainers = [{name = "@OzzieIsaacs"}] +license = {text = "GPLv3+"} +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: GNU Affero General Public License v3", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", +] +keywords = [ + "calibre", + "calibre-web", + "library", +] +requires-python = ">=3.6" +dependencies = [ + "APScheduler>=3.6.3,<3.11.0", + "Babel>=1.3,<3.0", + "Flask-Babel>=0.11.1,<4.1.0", + "Flask-Principal>=0.3.2,<0.5.1", + "Flask>=1.0.2,<3.1.0", + "iso-639>=0.4.5,<0.5.0", + "PyPDF>=3.15.6,<4.3.0", + "pytz>=2016.10", + "requests>=2.28.0,<2.32.0", + "SQLAlchemy>=1.3.0,<2.1.0", + "tornado>=6.3,<6.5", + "Wand>=0.4.4,<0.7.0", + "unidecode>=0.04.19,<1.4.0", + "lxml>=4.9.1,<5.3.0", + "flask-wtf>=0.14.2,<1.3.0", + "chardet>=3.0.0,<5.3.0", + "advocate>=1.0.0,<1.1.0", + "Flask-Limiter>=2.3.0,<3.9.0", + "regex>=2022.3.2,<2024.6.25", + "bleach>=6.0.0,<6.2.0", + "python-magic>=0.4.27,<0.5.0", + "flask-httpAuth>=4.4.0,<5.0.0", +] +dynamic = ["version"] + +[project.urls] +Homepage = "https://github.com/janeczku/calibre-web" +"Bug Tracker" = "https://github.com/janeczku/calibre-web/issues" +"Release Management" = "https://github.com/janeczku/calibre-web/releases" +Documentation = "https://github.com/janeczku/calibre-web/wiki" +"Source Code" = "https://github.com/janeczku/calibre-web" + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[project.optional-dependencies] +gdrive = [ + "google-api-python-client>=1.7.11,<2.200.0", + "gevent>20.6.0,<24.3.0", + "greenlet>=0.4.17,<3.1.0", + "httplib2>=0.9.2,<0.23.0", + "oauth2client>=4.0.0,<4.1.4", + "uritemplate>=3.0.0,<4.2.0", + "pyasn1-modules>=0.0.8,<0.5.0", + "pyasn1>=0.1.9,<0.7.0", + "PyDrive2>=1.3.1,<1.20.0", + "PyYAML>=3.12,<6.1", + "rsa>=3.4.2,<4.10.0", +] +gmail = [ + "google-auth-oauthlib>=0.4.3,<1.3.0", + "google-api-python-client>=1.7.11,<2.200.0", +] +goodreads = [ + "goodreads>=0.3.2,<0.4.0", + "python-Levenshtein>=0.12.0,<0.26.0", +] +ldap = [ + "python-ldap>=3.0.0,<3.5.0", + "Flask-SimpleLDAP>=1.4.0,<2.1.0", +] +oauth = [ + "Flask-Dance>=2.0.0,<7.1.0", + "SQLAlchemy-Utils>=0.33.5,<0.42.0", +] +metadata = [ + "rarfile>=3.2,<5.0", + "scholarly>=1.2.0,<1.8", + "markdown2>=2.0.0,<2.5.0", + "html2text>=2020.1.16,<2024.2.26", + "python-dateutil>=2.1,<2.10.0", + "beautifulsoup4>=4.0.1,<4.13.0", + "faust-cchardet>=2.1.18,<2.1.20", + "py7zr>=0.15.0,<0.21.0", + "mutagen>=1.40.0,<1.50.0", + "pycountry>=20.0.0,<25.0.0", +] +comics = [ + "natsort>=2.2.0,<8.5.0", + "comicapi>=2.2.0,<3.3.0", +] +kobo = ["jsonschema>=3.2.0,<4.24.0"] + +[project.scripts] +cps = "calibreweb:main" + +[tool.setuptools] +include-package-data = true +license-files = ["LICENSE"] + +[tool.setuptools.dynamic] +version = {attr = "calibreweb.cps.constants._version"} + diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ee1c63c5..00000000 --- a/setup.cfg +++ /dev/null @@ -1,110 +0,0 @@ -[metadata] -name = calibreweb -url = https://github.com/janeczku/calibre-web -project_urls = - Bug Tracker = https://github.com/janeczku/calibre-web/issues - Release Management = https://github.com/janeczku/calibre-web/releases - Documentation = https://github.com/janeczku/calibre-web/wiki - Source Code = https://github.com/janeczku/calibre-web -description = Web app for browsing, reading and downloading eBooks stored in a Calibre database. -long_description = file: README.md -long_description_content_type = text/markdown -author = @OzzieIsaacs -author_email = Ozzie.Fernandez.Isaacs@googlemail.com -maintainer = @OzzieIsaacs -license = GPLv3+ -license_files = LICENSE -classifiers = - Development Status :: 5 - Production/Stable - License :: OSI Approved :: GNU Affero General Public License v3 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Operating System :: OS Independent -keywords = - calibre - calibre-web - library -python_requires = >=3.5 - -[options.entry_points] -console_scripts = - cps = calibreweb:main - -[options] -include_package_data = True -install_requires = - APScheduler>=3.6.3,<3.11.0 - Babel>=1.3,<3.0 - Flask-Babel>=0.11.1,<4.1.0 - Flask-Principal>=0.3.2,<0.5.1 - Flask>=1.0.2,<3.1.0 - iso-639>=0.4.5,<0.5.0 - PyPDF>=3.15.6,<4.3.0 - pytz>=2016.10 - requests>=2.28.0,<2.32.0 - SQLAlchemy>=1.3.0,<2.1.0 - tornado>=6.3,<6.5 - Wand>=0.4.4,<0.7.0 - unidecode>=0.04.19,<1.4.0 - lxml>=4.9.1,<5.3.0 - flask-wtf>=0.14.2,<1.3.0 - chardet>=3.0.0,<5.3.0 - advocate>=1.0.0,<1.1.0 - Flask-Limiter>=2.3.0,<3.9.0 - regex>=2022.3.2,<2024.6.25 - bleach>=6.0.0,<6.2.0 - python-magic>=0.4.27,<0.5.0 - flask-httpAuth>=4.4.0,<5.0.0 - - -[options.packages.find] -where = src -include = cps/services* - -[options.extras_require] -gdrive = - google-api-python-client>=1.7.11,<2.200.0 - gevent>20.6.0,<24.3.0 - greenlet>=0.4.17,<3.1.0 - httplib2>=0.9.2,<0.23.0 - oauth2client>=4.0.0,<4.1.4 - uritemplate>=3.0.0,<4.2.0 - pyasn1-modules>=0.0.8,<0.5.0 - pyasn1>=0.1.9,<0.7.0 - PyDrive2>=1.3.1,<1.20.0 - PyYAML>=3.12,<6.1 - rsa>=3.4.2,<4.10.0 -gmail = - google-auth-oauthlib>=0.4.3,<1.3.0 - google-api-python-client>=1.7.11,<2.200.0 -goodreads = - goodreads>=0.3.2,<0.4.0 - python-Levenshtein>=0.12.0,<0.26.0 -ldap = - python-ldap>=3.0.0,<3.5.0 - Flask-SimpleLDAP>=1.4.0,<2.1.0 -oauth = - Flask-Dance>=2.0.0,<7.1.0 - SQLAlchemy-Utils>=0.33.5,<0.42.0 -metadata = - rarfile>=3.2,<5.0 - scholarly>=1.2.0,<1.8 - markdown2>=2.0.0,<2.5.0 - html2text>=2020.1.16,<2024.2.26 - python-dateutil>=2.1,<2.10.0 - beautifulsoup4>=4.0.1,<4.13.0 - faust-cchardet>=2.1.18,<2.1.20 - py7zr>=0.15.0,<0.21.0 - mutagen>=1.40.0,<1.50.0 - pycountry>=20.0.0,<25.0.0 -comics = - natsort>=2.2.0,<8.5.0 - comicapi>=2.2.0,<3.3.0 -kobo = - jsonschema>=3.2.0,<4.24.0 - diff --git a/setup.py b/setup.py deleted file mode 100644 index 8dcbee25..00000000 --- a/setup.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 decentral1se -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# """Calibre-web distribution package setuptools installer.""" - -from setuptools import setup -import os -import re -import codecs - -here = os.path.abspath(os.path.dirname(__file__)) - -def read(*parts): - with codecs.open(os.path.join(here, *parts), 'r') as fp: - return fp.read() - -def find_version(*file_paths): - version_file = read(*file_paths) - version_match = re.search(r"^STABLE_VERSION\s+=\s+{['\"]version['\"]:\s*['\"](.*)['\"]}", - version_file, re.M) - if version_match: - return version_match.group(1) - raise RuntimeError("Unable to find version string.") - -setup( - version=find_version("src", "calibreweb", "cps", "constants.py") -)