From d54e34d47f05eb32186e4170753f93cdd715700f Mon Sep 17 00:00:00 2001 From: crocodilestick <105450872+crocodilestick@users.noreply.github.com> Date: Sat, 9 Aug 2025 16:25:35 +0200 Subject: [PATCH] Updated spdx headers to more accurately reflect the current status of the project & it's contributors --- CONTRIBUTORS | 322 ++++++++++++ check_spdx_headers.py | 97 ++++ cps.py | 21 +- cps/MyLoginManager.py | 25 +- cps/__init__.py | 24 +- cps/about.py | 25 +- cps/admin.py | 25 +- cps/audio.py | 21 +- cps/cache_buster.py | 21 +- cps/clean_html.py | 21 +- cps/cli.py | 21 +- cps/comic.py | 21 +- cps/config_sql.py | 21 +- cps/constants.py | 21 +- cps/converter.py | 21 +- cps/cover.py | 21 +- cps/cw_advocate/__init__.py | 6 + cps/cw_advocate/adapters.py | 6 + cps/cw_advocate/addrvalidator.py | 6 + cps/cw_advocate/api.py | 6 + cps/cw_advocate/connection.py | 6 + cps/cw_advocate/connectionpool.py | 6 + cps/cw_advocate/exceptions.py | 6 + cps/cw_advocate/poolmanager.py | 6 + cps/cw_babel.py | 6 + cps/cw_login/__init__.py | 6 + cps/cw_login/config.py | 6 + cps/cw_login/login_manager.py | 6 + cps/cw_login/mixins.py | 6 + cps/cw_login/signals.py | 6 + cps/cw_login/utils.py | 6 + cps/cwa_functions.py | 6 + cps/db.py | 22 +- cps/debug_info.py | 22 +- cps/dep_check.py | 6 + cps/editbooks.py | 25 +- cps/embed_helper.py | 20 +- cps/epub.py | 21 +- cps/epub_helper.py | 21 +- cps/error_handler.py | 21 +- cps/fb2.py | 21 +- cps/file_helper.py | 21 +- cps/fs.py | 21 +- cps/gdrive.py | 25 +- cps/gdriveutils.py | 21 +- cps/gevent_wsgi.py | 21 +- cps/helper.py | 22 +- cps/isoLanguages.py | 20 +- cps/iso_language_names.py | 5 + cps/jinjia.py | 25 +- cps/kobo.py | 21 +- cps/kobo_auth.py | 22 +- cps/kobo_sync_status.py | 22 +- cps/kosync.py | 5 + cps/logger.py | 21 +- cps/main.py | 21 +- cps/metadata_provider/amazon.py | 21 +- cps/metadata_provider/amazonjp.py | 20 +- cps/metadata_provider/comicvine.py | 21 +- cps/metadata_provider/douban.py | 20 +- cps/metadata_provider/google.py | 21 +- cps/metadata_provider/hardcover.py | 21 +- cps/metadata_provider/ibdb.py | 21 +- cps/metadata_provider/lubimyczytac.py | 21 +- cps/metadata_provider/scholar.py | 20 +- cps/oauth.py | 21 +- cps/oauth_bb.py | 25 +- cps/opds.py | 25 +- cps/pagination.py | 25 +- cps/redirect.py | 5 + cps/remotelogin.py | 25 +- cps/render_template.py | 21 +- cps/reverseproxy.py | 5 + cps/schedule.py | 21 +- cps/search.py | 20 +- cps/search_metadata.py | 21 +- cps/server.py | 21 +- cps/services/Metadata.py | 20 +- cps/services/SyncToken.py | 21 +- cps/services/__init__.py | 21 +- cps/services/background_scheduler.py | 21 +- cps/services/gmail.py | 21 +- cps/services/goodreads_support.py | 21 +- cps/services/hardcover.py | 21 +- cps/services/simpleldap.py | 21 +- cps/services/worker.py | 21 +- cps/shelf.py | 25 +- cps/string_helper.py | 20 +- cps/subproc_wrapper.py | 21 +- cps/tasks/__init__.py | 6 + cps/tasks/clean.py | 21 +- cps/tasks/convert.py | 691 +++++++++++++------------- cps/tasks/database.py | 21 +- cps/tasks/mail.py | 21 +- cps/tasks/metadata_backup.py | 21 +- cps/tasks/thumbnail.py | 21 +- cps/tasks/upload.py | 21 +- cps/tasks_status.py | 20 +- cps/tornado_wsgi.py | 21 +- cps/ub.py | 22 +- cps/updater.py | 21 +- cps/uploader.py | 21 +- cps/usermanagement.py | 21 +- cps/web.py | 8 +- generate_contributors.py | 219 ++++++++ generate_translation_status.py | 6 + scripts/audiobook.py | 6 + scripts/auto_library.py | 6 + scripts/auto_zip.py | 6 + scripts/convert_library.py | 6 + scripts/cover_enforcer.py | 6 + scripts/cwa_db.py | 6 + scripts/ingest_processor.py | 6 + scripts/kindle_epub_fixer.py | 6 + update_spdx_headers.py | 239 +++++++++ 115 files changed, 1797 insertions(+), 1643 deletions(-) create mode 100644 CONTRIBUTORS create mode 100644 check_spdx_headers.py create mode 100644 generate_contributors.py create mode 100644 update_spdx_headers.py diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..9355790 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,322 @@ +CONTRIBUTORS + +This file is automatically generated. DO NOT EDIT MANUALLY. +Generated on: 2025-08-09T14:14:17.221105Z + +Upstream project: https://github.com/janeczku/calibre-web +Fork project (Calibre-Web Automated, since 2024): https://github.com/crocodilestick/calibre-web-automated + +License notice: This fork retains attribution to original Calibre-Web contributors in accordance with GPL-3.0-or-later. + +Copyright (C) 2018-2025 Calibre-Web contributors +Copyright (C) 2024-2025 Calibre-Web Automated contributors +# Upstream Contributors (janeczku/calibre-web) + +- OzzieIsaacs (anon) (2717 commits) +- Ozzie Isaacs (anon) (257 commits) +- cbartondock (96 commits) +- idalin (69 commits) +- cervinko (68 commits) +- irfan-ansari-au28 (64 commits) +- jkrehm (62 commits) +- Jack Darlington (anon) (51 commits) +- hexeth (anon) (44 commits) +- shavitmichael (44 commits) +- Jan Broer (anon) (41 commits) +- blitzmann (38 commits) +- mmonkey (33 commits) +- jvoisin (30 commits) +- bodybybuddha (26 commits) +- ElQuimm (26 commits) +- janeczku (anon) (26 commits) +- xlivevil (24 commits) +- ghighi3f (23 commits) +- Virgil Grigoras (anon) (23 commits) +- Krakinou (21 commits) +- pthiben (anon) (19 commits) +- radoslawkierznowski (19 commits) +- kyos (anon) (18 commits) +- Thore Schillmann (anon) (18 commits) +- quarz12 (16 commits) +- ok11 (13 commits) +- pwr (13 commits) +- mapi68 (12 commits) +- Kyosfonica (11 commits) +- otapi (11 commits) +- andy29485 (10 commits) +- Jony (anon) (10 commits) +- leram84 (10 commits) +- nykul (10 commits) +- oskardotglobal (10 commits) +- subdiox (10 commits) +- XZVB12 (10 commits) +- celogeek (9 commits) +- GarckaMan (9 commits) +- Knepherbird (9 commits) +- Yamakuni (anon) (9 commits) +- 89jd (8 commits) +- aroberts (8 commits) +- collerek (7 commits) +- Jan B (anon) (7 commits) +- lemmsh (7 commits) +- wuqi (7 commits) +- alfred82santa (6 commits) +- Kyos (anon) (6 commits) +- limeade23 (6 commits) +- Radosław Kierznowski (anon) (6 commits) +- akhy (5 commits) +- AsherMaximum (5 commits) +- Daniel (anon) (5 commits) +- gjutras (5 commits) +- horus68 (5 commits) +- JanB (anon) (5 commits) +- Ainsley Pereira (anon) (4 commits) +- csitko (4 commits) +- Faisal Alghamdi (anon) (4 commits) +- flying-sausages (4 commits) +- garf1242 (4 commits) +- Illia-M (4 commits) +- Jan Guzej (anon) (4 commits) +- joshobrienau (4 commits) +- Oreolek (4 commits) +- Petipopotam (4 commits) +- stfrbrntyu (4 commits) +- trasba (4 commits) +- webysther (4 commits) +- wildthyme (4 commits) +- acciobugs (3 commits) +- aliceout (3 commits) +- byword77 (3 commits) +- chintogtokh (3 commits) +- dickreckard (anon) (3 commits) +- eddriesen (3 commits) +- ground7 (3 commits) +- iz7iz7iz (3 commits) +- jango (3 commits) +- JFernando122 (3 commits) +- Kennyl (3 commits) +- lorek123 (anon) (3 commits) +- OlivierMaire (3 commits) +- SiphonSquirrel (3 commits) +- Thovi98 (3 commits) +- verglor (3 commits) +- yunimoo (anon) (3 commits) +- afrimberger (2 commits) +- Andrej Kralj (anon) (2 commits) +- andrerfcsantos (2 commits) +- Angel Docampo (anon) (2 commits) +- AnonTester (2 commits) +- beedaddy (2 commits) +- bharatknv (2 commits) +- CHBMB (2 commits) +- Clément Poissonnier (anon) (2 commits) +- Cyberax (2 commits) +- daniel-edwards-iress (2 commits) +- drizuid (2 commits) +- fernando-mesquita (2 commits) +- flashlab (2 commits) +- grunjol (2 commits) +- h1f0x (2 commits) +- halkeye (2 commits) +- hitsounds (2 commits) +- issmirnov (2 commits) +- jef (2 commits) +- jfenske89 (2 commits) +- jim3ma (2 commits) +- juanfernandovillahernandez (2 commits) +- KN4CK3R (2 commits) +- marblepebble (2 commits) +- nanu-c (2 commits) +- norangebit (2 commits) +- Northguy (2 commits) +- peperunas (2 commits) +- petersonev (2 commits) +- rafarq (2 commits) +- rscmbbng (2 commits) +- rtrox (2 commits) +- shivishbrahma (2 commits) +- tader (2 commits) +- teflontoni (2 commits) +- tintinmar1995 (2 commits) +- tobiasbayer (2 commits) +- UFervor (2 commits) +- UsamaFoad (2 commits) +- victorhck (2 commits) +- vigri (2 commits) +- Wladefant (2 commits) +- Zaroz (2 commits) +- acsulli (1 commits) +- Admiral Laser Beard (anon) (1 commits) +- adocampo (1 commits) +- aexvir (1 commits) +- akushsky (1 commits) +- Allram (1 commits) +- altair (1 commits) +- anatoliifetisov (1 commits) +- andylizi (1 commits) +- antar37 (1 commits) +- Anton Konyshev (anon) (1 commits) +- apetresc (1 commits) +- aptalca (1 commits) +- archont94 (1 commits) +- aribes (1 commits) +- ariesdevil (1 commits) +- arihid (1 commits) +- auveele (1 commits) +- BeckyDTP (1 commits) +- bernizt (1 commits) +- boosh (1 commits) +- Braincoke (anon) (1 commits) +- brandoningli (1 commits) +- captainwong (1 commits) +- chadberg (1 commits) +- coelebs (1 commits) +- ConstrictM (1 commits) +- contributor (1 commits) +- cryptkiddy (1 commits) +- danielamazza (1 commits) +- databoy2k (1 commits) +- Dave Mogle (anon) (1 commits) +- decentral1se (1 commits) +- dependabot[bot] (1 commits) +- dfn-certling (1 commits) +- dgliwka (1 commits) +- dmd (1 commits) +- dmistomin (1 commits) +- dnahurnyi (1 commits) +- dotlambda (1 commits) +- ducbachvan (1 commits) +- Dunrar (1 commits) +- Efreak (1 commits) +- elelay (1 commits) +- elfcan (1 commits) +- epsilon-0 (1 commits) +- evijayan2 (1 commits) +- fabwu (1 commits) +- Feige-cn (1 commits) +- Fmstrat (1 commits) +- geekifier (1 commits) +- gonzalo (1 commits) +- gorgobacka (1 commits) +- GrmpPnda (1 commits) +- growfrow (1 commits) +- GruberMarkus (1 commits) +- gwenhael-le-moine (1 commits) +- h3xten (1 commits) +- halink0803 (1 commits) +- ImanSharaf (1 commits) +- Irishsmurf (1 commits) +- JamesMcNee (1 commits) +- jathak (1 commits) +- jayrhynas (1 commits) +- Jeroen Kroese (anon) (1 commits) +- jgillman (1 commits) +- jhellingman (1 commits) +- jianyun.zhao (anon) (1 commits) +- JOHAE96 (1 commits) +- johnnyasantoss (1 commits) +- JonathanHerrewijnen (1 commits) +- jorti (1 commits) +- joshumax (1 commits) +- Julian Naydichev (anon) (1 commits) +- jureqq (1 commits) +- jvonau (1 commits) +- JVT038 (1 commits) +- kianmeng (1 commits) +- knobunc (1 commits) +- Kreeblah (1 commits) +- L0garithmic (1 commits) +- LawssssCat (1 commits) +- leexia (1 commits) +- leyan (1 commits) +- Lorek (anon) (1 commits) +- Louis Jencka (anon) (1 commits) +- lucaparsani (anon) (1 commits) +- lucindaq (1 commits) +- lunananananananana (1 commits) +- malletfils (1 commits) +- manad777 (1 commits) +- Martreides (1 commits) +- matthazinski (1 commits) +- MeanderingCode (1 commits) +- minakmostoles (1 commits) +- mingyue-aai (1 commits) +- mingyue-gao (1 commits) +- MisLink (1 commits) +- moben (1 commits) +- nelsg2 (1 commits) +- nferrari (1 commits) +- NickWick13 (1 commits) +- oguzkilcan (1 commits) +- overhacked (1 commits) +- PhracturedBlue (1 commits) +- pjeby (1 commits) +- pkorovin (1 commits) +- Polarolouis (1 commits) +- pollitor (1 commits) +- potatoeggy (1 commits) +- qx100 (1 commits) +- Rewerson (1 commits) +- Robbinsch (1 commits) +- robochud (1 commits) +- root (anon) (1 commits) +- ruben-herold (1 commits) +- ryanlong1004 (1 commits) +- sartoshi-foot-dao (1 commits) +- skiman6010 (1 commits) +- SpaceWhite (1 commits) +- theopsall (1 commits) +- Thijxx (1 commits) +- tomjmul (1 commits) +- vagra (1 commits) +- viljasenville (1 commits) +- Vistaus (1 commits) +- vrabe (1 commits) +- W1ndst0rm (1 commits) +- wadefelix (1 commits) +- wanoo (1 commits) +- whacloud (1 commits) +- whilenot-dev (1 commits) +- Wolfenk (1 commits) +- wolviex (1 commits) +- Wouter Dijk (anon) (1 commits) +- WouterKoch (1 commits) +- wuwei-12138 (1 commits) +- xybydy (1 commits) +- yjouanique (anon) (1 commits) +- ytilis (1 commits) +- zelazna (1 commits) +- zhiyue (1 commits) +# Fork Contributors (crocodilestick/calibre-web-automated) + +- crocodilestick (436 commits) +- jmarmstrong1207 (73 commits) +- demitrix (30 commits) +- sirwolfgang (22 commits) +- alva-seal (6 commits) +- angelicadvocate (6 commits) +- smevawala (5 commits) +- Aymendje (3 commits) +- Calychas (3 commits) +- zikasak (3 commits) +- chad3814 (2 commits) +- coissac (2 commits) +- FennyFatal (2 commits) +- bcrdncola (1 commits) +- Buco7854 (1 commits) +- cascandaliato (1 commits) +- Daniel Egberts (anon) (1 commits) +- Dee76 (1 commits) +- google-labs-jules[bot] (1 commits) +- gx1400 (1 commits) +- have-a-boy (1 commits) +- Hobogrammer (anon) (1 commits) +- jack1lee1995 (anon) (1 commits) +- jspiers (1 commits) +- morpheus65535 (1 commits) +- n00b42 (1 commits) +- NotaInutilis (1 commits) +- r0b2g1t (1 commits) +- robinwo (1 commits) +- Rustymage (1 commits) +- Turmaxx (1 commits) diff --git a/check_spdx_headers.py b/check_spdx_headers.py new file mode 100644 index 0000000..6e198e9 --- /dev/null +++ b/check_spdx_headers.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + +""" +check_spdx_headers.py + +Lightweight checker to ensure each staged source file (or specified paths) contains +an SPDX identifier (GPL-3.0-or-later) and the Calibre-Web Automated attribution header. +Intended for use in a pre-commit hook. + +Usage: + python check_spdx_headers.py [files...] +If no files provided, it inspects staged git changes (added/copied/modified). + +Exit codes: + 0 = all good + 1 = problems found / errors + +Customize REQUIRED_SUBSTRINGS if needed. +""" +from __future__ import annotations + +import subprocess +import sys +import pathlib +from typing import List + +REQUIRED_SUBSTRINGS = [ + "Calibre-Web Automated", # attribution line + "SPDX-License-Identifier: GPL-3.0-or-later", +] + +VALID_EXT = {".py", ".sh", ".js", ".ts", ".css", ".html"} + +EXCLUDE_DIR = {"__pycache__", ".git", "dist", "build", "node_modules", "venv", ".venv"} + + +def staged_files() -> List[pathlib.Path]: + try: + out = subprocess.check_output([ + "git", "diff", "--cached", "--name-only", "--diff-filter=ACM" + ], text=True) + except Exception: + return [] + files = [] + for line in out.splitlines(): + p = pathlib.Path(line.strip()) + if not p.exists(): + continue + if any(part in EXCLUDE_DIR for part in p.parts): + continue + if p.suffix.lower() in VALID_EXT: + files.append(p) + return files + + +def check_file(path: pathlib.Path) -> List[str]: + try: + text = path.read_text(encoding="utf-8", errors="ignore") + except Exception as e: + return [f"{path}: unable to read ({e})"] + missing = [s for s in REQUIRED_SUBSTRINGS if s not in text] + if missing: + return [f"{path}: missing -> {', '.join(missing)}"] + return [] + + +def main(argv: List[str]) -> int: + if len(argv) > 1: + targets = [pathlib.Path(a) for a in argv[1:]] + else: + targets = staged_files() + + if not targets: + print("No files to check.") + return 0 + + problems: List[str] = [] + for f in targets: + problems.extend(check_file(f)) + + if problems: + print("SPDX / attribution header check failed:") + for p in problems: + print(" ", p) + print("Hint: run: python update_spdx_headers.py --apply") + return 1 + print("All headers OK.") + return 0 + + +if __name__ == "__main__": # pragma: no cover + raise SystemExit(main(sys.argv)) diff --git a/cps.py b/cps.py index 039c2a5..192b562 100644 --- a/cps.py +++ b/cps.py @@ -1,21 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import sys diff --git a/cps/MyLoginManager.py b/cps/MyLoginManager.py index 4490704..3219f77 100755 --- a/cps/MyLoginManager.py +++ b/cps/MyLoginManager.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler, GammaC0de, vuolter -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from .cw_login import LoginManager from flask import session diff --git a/cps/__init__.py b/cps/__init__.py index 05ab668..b7f3dd3 100755 --- a/cps/__init__.py +++ b/cps/__init__.py @@ -1,24 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 . __package__ = "cps" import sys diff --git a/cps/about.py b/cps/about.py index 548e0df..02a858f 100755 --- a/cps/about.py +++ b/cps/about.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import platform diff --git a/cps/admin.py b/cps/admin.py index ac31caa..40d3284 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler, GammaC0de, vuolter -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import re diff --git a/cps/audio.py b/cps/audio.py index b17bc7b..cfaf1f0 100755 --- a/cps/audio.py +++ b/cps/audio.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2024 Ozzieisaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os diff --git a/cps/cache_buster.py b/cps/cache_buster.py index eb6b743..e60e83d 100755 --- a/cps/cache_buster.py +++ b/cps/cache_buster.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2016-2019 jkrehm andy29485 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Inspired by https://github.com/ChrisTM/Flask-CacheBust # Uses query strings so CSS font files are found without having to resort to absolute URLs diff --git a/cps/clean_html.py b/cps/clean_html.py index c687f15..1fd3ba2 100755 --- a/cps/clean_html.py +++ b/cps/clean_html.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from . import logger from lxml.etree import ParserError diff --git a/cps/cli.py b/cps/cli.py index e832b96..50b8e34 100755 --- a/cps/cli.py +++ b/cps/cli.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import os diff --git a/cps/comic.py b/cps/comic.py index a4a4f13..e6d65e2 100755 --- a/cps/comic.py +++ b/cps/comic.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os diff --git a/cps/config_sql.py b/cps/config_sql.py index 17e30e1..39d6d4f 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 OzzieIsaacs, pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import sys diff --git a/cps/constants.py b/cps/constants.py index 187a736..2f1c932 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 OzzieIsaacs, pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import os diff --git a/cps/converter.py b/cps/converter.py index 981b390..2c90f60 100755 --- a/cps/converter.py +++ b/cps/converter.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2016-2019 Ben Bennett, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import re diff --git a/cps/cover.py b/cps/cover.py index 8111083..a28e485 100755 --- a/cps/cover.py +++ b/cps/cover.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os diff --git a/cps/cw_advocate/__init__.py b/cps/cw_advocate/__init__.py index 58407b7..f67dccd 100755 --- a/cps/cw_advocate/__init__.py +++ b/cps/cw_advocate/__init__.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/adapters.py b/cps/cw_advocate/adapters.py index b15a141..dbbf483 100755 --- a/cps/cw_advocate/adapters.py +++ b/cps/cw_advocate/adapters.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/addrvalidator.py b/cps/cw_advocate/addrvalidator.py index 0f14ce8..53f1c24 100755 --- a/cps/cw_advocate/addrvalidator.py +++ b/cps/cw_advocate/addrvalidator.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/api.py b/cps/cw_advocate/api.py index 5a5ac20..6b3dade 100755 --- a/cps/cw_advocate/api.py +++ b/cps/cw_advocate/api.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/connection.py b/cps/cw_advocate/connection.py index ce790ad..69ec919 100755 --- a/cps/cw_advocate/connection.py +++ b/cps/cw_advocate/connection.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/connectionpool.py b/cps/cw_advocate/connectionpool.py index 3bbbfac..8027b75 100755 --- a/cps/cw_advocate/connectionpool.py +++ b/cps/cw_advocate/connectionpool.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/exceptions.py b/cps/cw_advocate/exceptions.py index 5ff9852..7581e36 100755 --- a/cps/cw_advocate/exceptions.py +++ b/cps/cw_advocate/exceptions.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_advocate/poolmanager.py b/cps/cw_advocate/poolmanager.py index d912d65..613e778 100755 --- a/cps/cw_advocate/poolmanager.py +++ b/cps/cw_advocate/poolmanager.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # # Copyright 2015 Jordan Milne # diff --git a/cps/cw_babel.py b/cps/cw_babel.py index cf043d5..2e7eb7d 100755 --- a/cps/cw_babel.py +++ b/cps/cw_babel.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + from babel import negotiate_locale from flask_babel import Babel, Locale from babel.core import UnknownLocaleError diff --git a/cps/cw_login/__init__.py b/cps/cw_login/__init__.py index f2822ba..834dd1f 100755 --- a/cps/cw_login/__init__.py +++ b/cps/cw_login/__init__.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # from .__about__ import __version__ from .config import AUTH_HEADER_NAME from .config import COOKIE_DURATION diff --git a/cps/cw_login/config.py b/cps/cw_login/config.py index fe2db2c..e99a408 100755 --- a/cps/cw_login/config.py +++ b/cps/cw_login/config.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + from datetime import timedelta #: The default name of the "remember me" cookie (``remember_token``) diff --git a/cps/cw_login/login_manager.py b/cps/cw_login/login_manager.py index a3714af..47e3852 100755 --- a/cps/cw_login/login_manager.py +++ b/cps/cw_login/login_manager.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + from datetime import datetime from datetime import timezone from datetime import timedelta diff --git a/cps/cw_login/mixins.py b/cps/cw_login/mixins.py index 0b3a71b..9740fa5 100755 --- a/cps/cw_login/mixins.py +++ b/cps/cw_login/mixins.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + class UserMixin: """ This provides default implementations for the methods that Flask-Login diff --git a/cps/cw_login/signals.py b/cps/cw_login/signals.py index cf9157f..7ac63da 100755 --- a/cps/cw_login/signals.py +++ b/cps/cw_login/signals.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + from flask.signals import Namespace _signals = Namespace() diff --git a/cps/cw_login/utils.py b/cps/cw_login/utils.py index b455e15..802e764 100755 --- a/cps/cw_login/utils.py +++ b/cps/cw_login/utils.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import hmac import os from functools import wraps diff --git a/cps/cwa_functions.py b/cps/cwa_functions.py index 61765b6..583ee01 100644 --- a/cps/cwa_functions.py +++ b/cps/cwa_functions.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + from flask import Blueprint, redirect, flash, url_for, request, send_from_directory, abort, jsonify, current_app from flask_babel import gettext as _ diff --git a/cps/db.py b/cps/db.py index 1164163..1b0ec41 100644 --- a/cps/db.py +++ b/cps/db.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 mutschler, cervinko, ok11, jkrehm, nanu-c, Wineliva, -# pjeby, elelay, idalin, Ozzieisaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import re diff --git a/cps/debug_info.py b/cps/debug_info.py index 473b46d..cd9051b 100755 --- a/cps/debug_info.py +++ b/cps/debug_info.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 cervinko, idalin, SiphonSquirrel, ouzklcn, akushsky, -# OzzieIsaacs, bodybybuddha, jkrehm, matthazinski, janeczku -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import shutil import glob diff --git a/cps/dep_check.py b/cps/dep_check.py index 0575aa5..99226ba 100755 --- a/cps/dep_check.py +++ b/cps/dep_check.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import os import re import sys diff --git a/cps/editbooks.py b/cps/editbooks.py index 6efa1cd..1ad749a 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os from datetime import datetime, timezone diff --git a/cps/embed_helper.py b/cps/embed_helper.py index 2a4ce34..688fe3d 100755 --- a/cps/embed_helper.py +++ b/cps/embed_helper.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2024 OzzieIsaacs -# -# 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 . from uuid import uuid4 import os diff --git a/cps/epub.py b/cps/epub.py index 626e68e..54bfbed 100755 --- a/cps/epub.py +++ b/cps/epub.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 lemmsh, Kennyl, Kyosfonica, matthazinski -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import zipfile diff --git a/cps/epub_helper.py b/cps/epub_helper.py index 4517f2c..038e602 100755 --- a/cps/epub_helper.py +++ b/cps/epub_helper.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 lemmsh, Kennyl, Kyosfonica, matthazinski -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import zipfile from lxml import etree diff --git a/cps/error_handler.py b/cps/error_handler.py index 92d3e87..04c5768 100755 --- a/cps/error_handler.py +++ b/cps/error_handler.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2020 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import traceback diff --git a/cps/fb2.py b/cps/fb2.py index 81eae57..727432f 100755 --- a/cps/fb2.py +++ b/cps/fb2.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 lemmsh, cervinko, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from lxml import etree diff --git a/cps/file_helper.py b/cps/file_helper.py index a9708f1..7be745a 100755 --- a/cps/file_helper.py +++ b/cps/file_helper.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2023 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from tempfile import gettempdir import os diff --git a/cps/fs.py b/cps/fs.py index 996499c..ee9260b 100755 --- a/cps/fs.py +++ b/cps/fs.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 mmonkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from . import logger from .constants import CACHE_DIR diff --git a/cps/gdrive.py b/cps/gdrive.py index 07795b5..dfabce8 100755 --- a/cps/gdrive.py +++ b/cps/gdrive.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import hashlib diff --git a/cps/gdriveutils.py b/cps/gdriveutils.py index 7bff089..5fcdb7d 100755 --- a/cps/gdriveutils.py +++ b/cps/gdriveutils.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 idalin, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import json diff --git a/cps/gevent_wsgi.py b/cps/gevent_wsgi.py index ab98840..69e04b2 100755 --- a/cps/gevent_wsgi.py +++ b/cps/gevent_wsgi.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from datetime import datetime from gevent.pywsgi import WSGIHandler diff --git a/cps/helper.py b/cps/helper.py index 775c153..d30fdb9 100755 --- a/cps/helper.py +++ b/cps/helper.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 cervinko, idalin, SiphonSquirrel, ouzklcn, akushsky, -# OzzieIsaacs, bodybybuddha, jkrehm, matthazinski, janeczku -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import random diff --git a/cps/isoLanguages.py b/cps/isoLanguages.py index a34cd34..f461d91 100755 --- a/cps/isoLanguages.py +++ b/cps/isoLanguages.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 pwr -# -# 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 . import sys from .iso_language_names import LANGUAGE_NAMES as _LANGUAGE_NAMES diff --git a/cps/iso_language_names.py b/cps/iso_language_names.py index 9248443..7f0a7e7 100755 --- a/cps/iso_language_names.py +++ b/cps/iso_language_names.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) # Copyright (C) 2019 OzzieIsaacs, pwr diff --git a/cps/jinjia.py b/cps/jinjia.py index 3db3e88..dc46795 100755 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # custom jinja filters diff --git a/cps/kobo.py b/cps/kobo.py index e2e63b7..b9a8d15 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -1,21 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 shavitmichael, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import base64 from datetime import datetime, timezone diff --git a/cps/kobo_auth.py b/cps/kobo_auth.py index 416307d..0382941 100755 --- a/cps/kobo_auth.py +++ b/cps/kobo_auth.py @@ -1,22 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 shavitmichael, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. """This module is used to control authentication/authorization of Kobo sync requests. This module also includes research notes into the auth protocol used by Kobo devices. diff --git a/cps/kobo_sync_status.py b/cps/kobo_sync_status.py index 357b84e..6063df4 100755 --- a/cps/kobo_sync_status.py +++ b/cps/kobo_sync_status.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from .cw_login import current_user from . import ub diff --git a/cps/kosync.py b/cps/kosync.py index bac1edb..148dcfc 100644 --- a/cps/kosync.py +++ b/cps/kosync.py @@ -1,5 +1,10 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. """ KOReader Sync Server Implementation for Calibre-Web-Automated diff --git a/cps/logger.py b/cps/logger.py index 9aa076d..2437d54 100755 --- a/cps/logger.py +++ b/cps/logger.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import sys diff --git a/cps/main.py b/cps/main.py index ab22297..ca65c35 100644 --- a/cps/main.py +++ b/cps/main.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys diff --git a/cps/metadata_provider/amazon.py b/cps/metadata_provider/amazon.py index d3c4061..1660585 100755 --- a/cps/metadata_provider/amazon.py +++ b/cps/metadata_provider/amazon.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 quarz12 -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import concurrent.futures import requests diff --git a/cps/metadata_provider/amazonjp.py b/cps/metadata_provider/amazonjp.py index 4d31942..de8c7fb 100644 --- a/cps/metadata_provider/amazonjp.py +++ b/cps/metadata_provider/amazonjp.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2025 quarz12, Hobogrammer -# -# 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 . import cps.logger as logger import concurrent.futures import re diff --git a/cps/metadata_provider/comicvine.py b/cps/metadata_provider/comicvine.py index b4d8d34..ac8258d 100755 --- a/cps/metadata_provider/comicvine.py +++ b/cps/metadata_provider/comicvine.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # ComicVine api document: https://comicvine.gamespot.com/api/documentation from typing import Dict, List, Optional diff --git a/cps/metadata_provider/douban.py b/cps/metadata_provider/douban.py index 1dd12d8..9f5469d 100755 --- a/cps/metadata_provider/douban.py +++ b/cps/metadata_provider/douban.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 xlivevil -# -# 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 . import re from concurrent import futures from typing import List, Optional diff --git a/cps/metadata_provider/google.py b/cps/metadata_provider/google.py index df9c0dc..3bceca3 100755 --- a/cps/metadata_provider/google.py +++ b/cps/metadata_provider/google.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Google Books api document: https://developers.google.com/books/docs/v1/using from typing import Dict, List, Optional diff --git a/cps/metadata_provider/hardcover.py b/cps/metadata_provider/hardcover.py index 42152b1..12765c8 100644 --- a/cps/metadata_provider/hardcover.py +++ b/cps/metadata_provider/hardcover.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Hardcover api document: https://Hardcover.gamespot.com/api/documentation from typing import Dict, List, Optional diff --git a/cps/metadata_provider/ibdb.py b/cps/metadata_provider/ibdb.py index 1371267..a844dc0 100644 --- a/cps/metadata_provider/ibdb.py +++ b/cps/metadata_provider/ibdb.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Google Books api document: https://developers.google.com/books/docs/v1/using from typing import Dict, List, Optional diff --git a/cps/metadata_provider/lubimyczytac.py b/cps/metadata_provider/lubimyczytac.py index 9d4a99f..bc3b740 100755 --- a/cps/metadata_provider/lubimyczytac.py +++ b/cps/metadata_provider/lubimyczytac.py @@ -1,19 +1,10 @@ # -*- coding: utf-8 -*- -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import datetime import json import re diff --git a/cps/metadata_provider/scholar.py b/cps/metadata_provider/scholar.py index ad365fa..1427c4f 100755 --- a/cps/metadata_provider/scholar.py +++ b/cps/metadata_provider/scholar.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 . import itertools from typing import Dict, List, Optional from urllib.parse import quote, unquote diff --git a/cps/oauth.py b/cps/oauth.py index 0caa61e..842a18f 100755 --- a/cps/oauth.py +++ b/cps/oauth.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 jim3ma -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from flask import session diff --git a/cps/oauth_bb.py b/cps/oauth_bb.py index 7ec813b..bf43e9f 100755 --- a/cps/oauth_bb.py +++ b/cps/oauth_bb.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import json from functools import wraps diff --git a/cps/opds.py b/cps/opds.py index 485d241..a8d9b4b 100755 --- a/cps/opds.py +++ b/cps/opds.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import datetime import json diff --git a/cps/pagination.py b/cps/pagination.py index 6f19a99..b366c74 100644 --- a/cps/pagination.py +++ b/cps/pagination.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from math import ceil diff --git a/cps/redirect.py b/cps/redirect.py index 7f504b9..522e29d 100755 --- a/cps/redirect.py +++ b/cps/redirect.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Flask License # diff --git a/cps/remotelogin.py b/cps/remotelogin.py index a31a77b..7e37057 100755 --- a/cps/remotelogin.py +++ b/cps/remotelogin.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import json from datetime import datetime diff --git a/cps/render_template.py b/cps/render_template.py index f1da125..79d62d1 100644 --- a/cps/render_template.py +++ b/cps/render_template.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2020 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from flask import render_template, g, abort, request, flash from flask_babel import gettext as _ diff --git a/cps/reverseproxy.py b/cps/reverseproxy.py index 4acb8e4..219949d 100755 --- a/cps/reverseproxy.py +++ b/cps/reverseproxy.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. # Flask License # diff --git a/cps/schedule.py b/cps/schedule.py index d01aab1..99ca9c0 100755 --- a/cps/schedule.py +++ b/cps/schedule.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 mmonkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import datetime diff --git a/cps/search.py b/cps/search.py index 29dda16..d75033e 100755 --- a/cps/search.py +++ b/cps/search.py @@ -1,18 +1,8 @@ -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import json from datetime import datetime diff --git a/cps/search_metadata.py b/cps/search_metadata.py index 726e2a9..a16ebcf 100644 --- a/cps/search_metadata.py +++ b/cps/search_metadata.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import concurrent.futures import importlib diff --git a/cps/server.py b/cps/server.py index 41188ac..ad3731d 100755 --- a/cps/server.py +++ b/cps/server.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 janeczku, OzzieIsaacs, andrerfcsantos, idalin -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import os diff --git a/cps/services/Metadata.py b/cps/services/Metadata.py index d975092..2281ec4 100644 --- a/cps/services/Metadata.py +++ b/cps/services/Metadata.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 . import abc import dataclasses import os diff --git a/cps/services/SyncToken.py b/cps/services/SyncToken.py index 871d2b2..0ed3992 100755 --- a/cps/services/SyncToken.py +++ b/cps/services/SyncToken.py @@ -1,21 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 shavitmichael, OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys from base64 import b64decode, b64encode diff --git a/cps/services/__init__.py b/cps/services/__init__.py index 000a6f9..33fc860 100644 --- a/cps/services/__init__.py +++ b/cps/services/__init__.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2019 pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from .. import logger diff --git a/cps/services/background_scheduler.py b/cps/services/background_scheduler.py index 55b12df..be61493 100755 --- a/cps/services/background_scheduler.py +++ b/cps/services/background_scheduler.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 mmonkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import atexit diff --git a/cps/services/gmail.py b/cps/services/gmail.py index 5b0cdbe..8301518 100755 --- a/cps/services/gmail.py +++ b/cps/services/gmail.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2021 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os.path from google_auth_oauthlib.flow import InstalledAppFlow diff --git a/cps/services/goodreads_support.py b/cps/services/goodreads_support.py index b3b7bde..31a2f67 100755 --- a/cps/services/goodreads_support.py +++ b/cps/services/goodreads_support.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import time from functools import reduce diff --git a/cps/services/hardcover.py b/cps/services/hardcover.py index 95f801a..ac651b7 100644 --- a/cps/services/hardcover.py +++ b/cps/services/hardcover.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from datetime import datetime import requests diff --git a/cps/services/simpleldap.py b/cps/services/simpleldap.py index 3ae048b..4eaa735 100755 --- a/cps/services/simpleldap.py +++ b/cps/services/simpleldap.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import base64 diff --git a/cps/services/worker.py b/cps/services/worker.py index dce3da7..cb34b7c 100755 --- a/cps/services/worker.py +++ b/cps/services/worker.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import threading import abc diff --git a/cps/shelf.py b/cps/shelf.py index 1541745..f912d5a 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -1,24 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, -# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, -# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, -# ruben-herold, marblepebble, JackED42, SiphonSquirrel, -# apetresc, nanu-c, mutschler -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys from datetime import datetime, timezone diff --git a/cps/string_helper.py b/cps/string_helper.py index d263dd2..fbd9cac 100755 --- a/cps/string_helper.py +++ b/cps/string_helper.py @@ -1,20 +1,10 @@ # -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2024 OzzieIsaacs -# -# 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 . import re diff --git a/cps/subproc_wrapper.py b/cps/subproc_wrapper.py index 187b2cb..a2498f1 100755 --- a/cps/subproc_wrapper.py +++ b/cps/subproc_wrapper.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import os diff --git a/cps/tasks/__init__.py b/cps/tasks/__init__.py index e69de29..a158d39 100755 --- a/cps/tasks/__init__.py +++ b/cps/tasks/__init__.py @@ -0,0 +1,6 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + diff --git a/cps/tasks/clean.py b/cps/tasks/clean.py index 1a1681b..620cec8 100755 --- a/cps/tasks/clean.py +++ b/cps/tasks/clean.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2023 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import datetime diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index 08eb63c..df97a07 100755 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -1,351 +1,340 @@ -# -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 pwr -# -# 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 . - -import os -import re -import glob -from shutil import copyfile, copyfileobj -from markupsafe import escape -from time import time -from uuid import uuid4 - -from sqlalchemy.exc import SQLAlchemyError -from flask_babel import lazy_gettext as N_ - -from cps.services.worker import CalibreTask -from cps import db -from cps import logger, config -from cps.subproc_wrapper import process_open -from flask_babel import gettext as _ -from cps.kobo_sync_status import remove_synced_book -from cps.ub import init_db_thread -from cps.file_helper import get_temp_dir - -from cps.tasks.mail import TaskEmail -from cps import gdriveutils, helper -from cps.constants import SUPPORTED_CALIBRE_BINARIES -from cps.string_helper import strip_whitespaces - -log = logger.create() - -current_milli_time = lambda: int(round(time() * 1000)) - - -class TaskConvert(CalibreTask): - def __init__(self, file_path, book_id, task_message, settings, ereader_mail, user=None): - super(TaskConvert, self).__init__(task_message) - self.worker_thread = None - self.file_path = file_path - self.book_id = book_id - self.title = "" - self.settings = settings - self.ereader_mail = ereader_mail - self.user = user - - self.results = dict() - - def run(self, worker_thread): - self.worker_thread = worker_thread - if config.config_use_google_drive: - worker_db = db.CalibreDB(expire_on_commit=False, init=True) - cur_book = worker_db.get_book(self.book_id) - self.title = cur_book.title - data = worker_db.get_book_format(self.book_id, self.settings['old_book_format']) - df = gdriveutils.getFileFromEbooksFolder(cur_book.path, - data.name + "." + self.settings['old_book_format'].lower()) - df_cover = gdriveutils.getFileFromEbooksFolder(cur_book.path, "cover.jpg") - if df: - datafile_cover = None - datafile = os.path.join(config.get_book_path(), - cur_book.path, - data.name + "." + self.settings['old_book_format'].lower()) - if df_cover: - datafile_cover = os.path.join(config.get_book_path(), - cur_book.path, "cover.jpg") - if not os.path.exists(os.path.join(config.get_book_path(), cur_book.path)): - os.makedirs(os.path.join(config.get_book_path(), cur_book.path)) - df.GetContentFile(datafile) - if df_cover: - df_cover.GetContentFile(datafile_cover) - worker_db.session.close() - else: - # ToDo Include cover in error handling - error_message = _("%(format)s not found on Google Drive: %(fn)s", - format=self.settings['old_book_format'], - fn=data.name + "." + self.settings['old_book_format'].lower()) - worker_db.session.close() - return self._handleError(error_message) - - filename = self._convert_ebook_format() - if config.config_use_google_drive: - os.remove(self.file_path + '.' + self.settings['old_book_format'].lower()) - if df_cover: - os.remove(os.path.join(config.config_calibre_dir, cur_book.path, "cover.jpg")) - - if filename: - if config.config_use_google_drive: - # Upload files to gdrive - gdriveutils.updateGdriveCalibreFromLocal() - self._handleSuccess() - if self.ereader_mail: - # if we're sending to E-Reader after converting, create a one-off task and run it immediately - # todo: figure out how to incorporate this into the progress - try: - EmailText = N_(u"%(book)s send to E-Reader", book=escape(self.title)) - for email in self.ereader_mail.split(','): - email = strip_whitespaces(email) - worker_thread.add(self.user, TaskEmail(self.settings['subject'], - self.results["path"], - filename, - self.settings, - email, - EmailText, - self.settings['body'], - id=self.book_id, - internal=True) - ) - except Exception as ex: - return self._handleError(str(ex)) - - def _convert_ebook_format(self): - error_message = None - local_db = db.CalibreDB(expire_on_commit=False, init=True) - file_path = self.file_path - book_id = self.book_id - format_old_ext = '.' + self.settings['old_book_format'].lower() - format_new_ext = '.' + self.settings['new_book_format'].lower() - - # check to see if destination format already exists - or if book is in database - # if it does - mark the conversion task as complete and return a success - # this will allow to send to E-Reader workflow to continue to work - if os.path.isfile(file_path + format_new_ext) or\ - local_db.get_book_format(self.book_id, self.settings['new_book_format']): - log.info("Book id %d already converted to %s", book_id, format_new_ext) - cur_book = local_db.get_book(book_id) - self.title = cur_book.title - self.results['path'] = cur_book.path - self.results['title'] = self.title - new_format = local_db.session.query(db.Data).filter(db.Data.book == book_id)\ - .filter(db.Data.format == self.settings['new_book_format'].upper()).one_or_none() - if not new_format: - new_format = db.Data(name=os.path.basename(file_path), - book_format=self.settings['new_book_format'].upper(), - book=book_id, uncompressed_size=os.path.getsize(file_path + format_new_ext)) - try: - local_db.session.merge(new_format) - local_db.session.commit() - except SQLAlchemyError as e: - local_db.session.rollback() - log.error("Database error: %s", e) - local_db.session.close() - self._handleError(N_("Oops! Database Error: %(error)s.", error=e)) - return - self._handleSuccess() - local_db.session.close() - return os.path.basename(file_path + format_new_ext) - else: - log.info("Book id %d - target format of %s does not exist. Moving forward with convert.", - book_id, - format_new_ext) - - if config.config_kepubifypath and format_old_ext == '.epub' and format_new_ext == '.kepub': - check, error_message = self._convert_kepubify(file_path, - format_old_ext, - format_new_ext) - else: - # check if calibre converter-executable is existing - if not os.path.exists(config.config_converterpath): - self._handleError(N_("Calibre ebook-convert %(tool)s not found", tool=config.config_converterpath)) - return - has_cover = local_db.get_book(book_id).has_cover - check, error_message = self._convert_calibre(file_path, format_old_ext, format_new_ext, has_cover) - - if check == 0: - cur_book = local_db.get_book(book_id) - if os.path.isfile(file_path + format_new_ext): - new_format = local_db.session.query(db.Data).filter(db.Data.book == book_id) \ - .filter(db.Data.format == self.settings['new_book_format'].upper()).one_or_none() - if not new_format: - new_format = db.Data(name=cur_book.data[0].name, - book_format=self.settings['new_book_format'].upper(), - book=book_id, uncompressed_size=os.path.getsize(file_path + format_new_ext)) - try: - local_db.session.merge(new_format) - local_db.session.commit() - if self.settings['new_book_format'].upper() in ['KEPUB', 'EPUB', 'EPUB3']: - ub_session = init_db_thread() - remove_synced_book(book_id, True, ub_session) - ub_session.close() - except SQLAlchemyError as e: - local_db.session.rollback() - log.error("Database error: %s", e) - local_db.session.close() - self._handleError(error_message) - return - self.results['path'] = cur_book.path - self.title = cur_book.title - self.results['title'] = self.title - if not config.config_use_google_drive: - self._handleSuccess() - return os.path.basename(file_path + format_new_ext) - else: - error_message = N_('%(format)s format not found on disk', format=format_new_ext.upper()) - local_db.session.close() - log.info("ebook converter failed with error while converting book") - if not error_message: - error_message = N_('Ebook converter failed with unknown error') - else: - log.error(error_message) - self._handleError(error_message) - return - - def _convert_kepubify(self, file_path, format_old_ext, format_new_ext): - if config.config_embed_metadata and config.config_binariesdir: - tmp_dir, temp_file_name = helper.do_calibre_export(self.book_id, format_old_ext[1:]) - filename = os.path.join(tmp_dir, temp_file_name + format_old_ext) - temp_file_path = tmp_dir - else: - filename = file_path + format_old_ext - temp_file_path = os.path.dirname(file_path) - quotes = [1, 3] - command = [config.config_kepubifypath, filename, '-o', temp_file_path, '-i'] - try: - p = process_open(command, quotes) - except OSError as e: - return 1, N_("Kepubify-converter failed: %(error)s", error=e) - self.progress = 0.01 - while True: - nextline = p.stdout.readlines() - nextline = [x.strip('\n') for x in nextline if x != '\n'] - for line in nextline: - log.debug(line) - if p.poll() is not None: - break - - # process returncode - check = p.returncode - - # move file - if check == 0: - converted_file = glob.glob(glob.escape(os.path.splitext(filename)[0]) + "*.kepub.epub") - if len(converted_file) == 1: - copyfile(converted_file[0], (file_path + format_new_ext)) - os.unlink(converted_file[0]) - else: - return 1, N_("Converted file not found or more than one file in folder %(folder)s", - folder=os.path.dirname(file_path)) - return check, None - - def _convert_calibre(self, file_path, format_old_ext, format_new_ext, has_cover): - path_tmp_opf = None - try: - # path_tmp_opf = self._embed_metadata() - if config.config_embed_metadata: - quotes = [5] - tmp_dir = get_temp_dir() - calibredb_binarypath = os.path.join(config.config_binariesdir, SUPPORTED_CALIBRE_BINARIES["calibredb"]) - my_env = os.environ.copy() - if config.config_calibre_split: - my_env['CALIBRE_OVERRIDE_DATABASE_PATH'] = os.path.join(config.config_calibre_dir, "metadata.db") - library_path = config.config_calibre_split_dir - else: - library_path = config.config_calibre_dir - - opf_command = [calibredb_binarypath, 'show_metadata', '--as-opf', str(self.book_id), - '--with-library', library_path] - p = process_open(opf_command, quotes, my_env, newlines=False) - lines = list() - while p.poll() is None: - lines.append(p.stdout.readline()) - check = p.returncode - calibre_traceback = p.stderr.readlines() - if check == 0: - path_tmp_opf = os.path.join(tmp_dir, "metadata_" + str(uuid4()) + ".opf") - with open(path_tmp_opf, 'wb') as fd: - fd.write(b''.join(lines)) - else: - error_message = "" - for ele in calibre_traceback: - if not ele.startswith('Traceback') and not ele.startswith(' File'): - error_message = N_("Calibre failed with error: %(error)s", error=ele) - return check, error_message - quotes = [1, 2] - quotes_index = 3 - command = [config.config_converterpath, (file_path + format_old_ext), - (file_path + format_new_ext)] - if config.config_embed_metadata: - quotes.append(4) - quotes_index = 5 - command.extend(['--from-opf', path_tmp_opf]) - if has_cover: - quotes.append(6) - command.extend(['--cover', os.path.join(os.path.dirname(file_path), 'cover.jpg')]) - quotes_index = 7 - if config.config_calibre: - parameters = re.findall(r"(--[\w-]+)(?:(\s(?:(\".+\")|(?:.+?)))(?:\s|$))?", - config.config_calibre, re.IGNORECASE | re.UNICODE) - if parameters: - for param in parameters: - command.append(strip_whitespaces(param[0])) - quotes_index += 1 - if param[1] != "": - parsed = strip_whitespaces(param[1]).strip("\"") - command.append(parsed) - quotes.append(quotes_index) - quotes_index += 1 - p = process_open(command, quotes, newlines=False) - except OSError as e: - return 1, N_("Ebook-converter failed: %(error)s", error=e) - - while p.poll() is None: - nextline = p.stdout.readline() - if isinstance(nextline, bytes): - nextline = nextline.decode('utf-8', errors="ignore").strip('\r\n') - if nextline: - log.debug(nextline) - # parse progress string from calibre-converter - progress = re.search(r"(\d+)%\s.*", nextline) - if progress: - self.progress = int(progress.group(1)) / 100 - if config.config_use_google_drive: - self.progress *= 0.9 - - # process returncode - check = p.returncode - calibre_traceback = p.stderr.readlines() - error_message = "" - for ele in calibre_traceback: - ele = ele.decode('utf-8', errors="ignore").strip('\n') - log.debug(ele) - if not ele.startswith('Traceback') and not ele.startswith(' File'): - error_message = N_("Calibre failed with error: %(error)s", error=ele) - return check, error_message - - @property - def name(self): - return N_("Convert") - - def __str__(self): - if self.ereader_mail: - return "Convert Book {} and mail it to {}".format(self.book_id, self.ereader_mail) - else: - return "Convert Book {}".format(self.book_id) - - @property - def is_cancellable(self): - return False +# -*- coding: utf-8 -*- +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + +import os +import re +import glob +from shutil import copyfile, copyfileobj +from markupsafe import escape +from time import time +from uuid import uuid4 + +from sqlalchemy.exc import SQLAlchemyError +from flask_babel import lazy_gettext as N_ + +from cps.services.worker import CalibreTask +from cps import db +from cps import logger, config +from cps.subproc_wrapper import process_open +from flask_babel import gettext as _ +from cps.kobo_sync_status import remove_synced_book +from cps.ub import init_db_thread +from cps.file_helper import get_temp_dir + +from cps.tasks.mail import TaskEmail +from cps import gdriveutils, helper +from cps.constants import SUPPORTED_CALIBRE_BINARIES +from cps.string_helper import strip_whitespaces + +log = logger.create() + +current_milli_time = lambda: int(round(time() * 1000)) + + +class TaskConvert(CalibreTask): + def __init__(self, file_path, book_id, task_message, settings, ereader_mail, user=None): + super(TaskConvert, self).__init__(task_message) + self.worker_thread = None + self.file_path = file_path + self.book_id = book_id + self.title = "" + self.settings = settings + self.ereader_mail = ereader_mail + self.user = user + + self.results = dict() + + def run(self, worker_thread): + self.worker_thread = worker_thread + if config.config_use_google_drive: + worker_db = db.CalibreDB(expire_on_commit=False, init=True) + cur_book = worker_db.get_book(self.book_id) + self.title = cur_book.title + data = worker_db.get_book_format(self.book_id, self.settings['old_book_format']) + df = gdriveutils.getFileFromEbooksFolder(cur_book.path, + data.name + "." + self.settings['old_book_format'].lower()) + df_cover = gdriveutils.getFileFromEbooksFolder(cur_book.path, "cover.jpg") + if df: + datafile_cover = None + datafile = os.path.join(config.get_book_path(), + cur_book.path, + data.name + "." + self.settings['old_book_format'].lower()) + if df_cover: + datafile_cover = os.path.join(config.get_book_path(), + cur_book.path, "cover.jpg") + if not os.path.exists(os.path.join(config.get_book_path(), cur_book.path)): + os.makedirs(os.path.join(config.get_book_path(), cur_book.path)) + df.GetContentFile(datafile) + if df_cover: + df_cover.GetContentFile(datafile_cover) + worker_db.session.close() + else: + # ToDo Include cover in error handling + error_message = _("%(format)s not found on Google Drive: %(fn)s", + format=self.settings['old_book_format'], + fn=data.name + "." + self.settings['old_book_format'].lower()) + worker_db.session.close() + return self._handleError(error_message) + + filename = self._convert_ebook_format() + if config.config_use_google_drive: + os.remove(self.file_path + '.' + self.settings['old_book_format'].lower()) + if df_cover: + os.remove(os.path.join(config.config_calibre_dir, cur_book.path, "cover.jpg")) + + if filename: + if config.config_use_google_drive: + # Upload files to gdrive + gdriveutils.updateGdriveCalibreFromLocal() + self._handleSuccess() + if self.ereader_mail: + # if we're sending to E-Reader after converting, create a one-off task and run it immediately + # todo: figure out how to incorporate this into the progress + try: + EmailText = N_(u"%(book)s send to E-Reader", book=escape(self.title)) + for email in self.ereader_mail.split(','): + email = strip_whitespaces(email) + worker_thread.add(self.user, TaskEmail(self.settings['subject'], + self.results["path"], + filename, + self.settings, + email, + EmailText, + self.settings['body'], + id=self.book_id, + internal=True) + ) + except Exception as ex: + return self._handleError(str(ex)) + + def _convert_ebook_format(self): + error_message = None + local_db = db.CalibreDB(expire_on_commit=False, init=True) + file_path = self.file_path + book_id = self.book_id + format_old_ext = '.' + self.settings['old_book_format'].lower() + format_new_ext = '.' + self.settings['new_book_format'].lower() + + # check to see if destination format already exists - or if book is in database + # if it does - mark the conversion task as complete and return a success + # this will allow to send to E-Reader workflow to continue to work + if os.path.isfile(file_path + format_new_ext) or\ + local_db.get_book_format(self.book_id, self.settings['new_book_format']): + log.info("Book id %d already converted to %s", book_id, format_new_ext) + cur_book = local_db.get_book(book_id) + self.title = cur_book.title + self.results['path'] = cur_book.path + self.results['title'] = self.title + new_format = local_db.session.query(db.Data).filter(db.Data.book == book_id)\ + .filter(db.Data.format == self.settings['new_book_format'].upper()).one_or_none() + if not new_format: + new_format = db.Data(name=os.path.basename(file_path), + book_format=self.settings['new_book_format'].upper(), + book=book_id, uncompressed_size=os.path.getsize(file_path + format_new_ext)) + try: + local_db.session.merge(new_format) + local_db.session.commit() + except SQLAlchemyError as e: + local_db.session.rollback() + log.error("Database error: %s", e) + local_db.session.close() + self._handleError(N_("Oops! Database Error: %(error)s.", error=e)) + return + self._handleSuccess() + local_db.session.close() + return os.path.basename(file_path + format_new_ext) + else: + log.info("Book id %d - target format of %s does not exist. Moving forward with convert.", + book_id, + format_new_ext) + + if config.config_kepubifypath and format_old_ext == '.epub' and format_new_ext == '.kepub': + check, error_message = self._convert_kepubify(file_path, + format_old_ext, + format_new_ext) + else: + # check if calibre converter-executable is existing + if not os.path.exists(config.config_converterpath): + self._handleError(N_("Calibre ebook-convert %(tool)s not found", tool=config.config_converterpath)) + return + has_cover = local_db.get_book(book_id).has_cover + check, error_message = self._convert_calibre(file_path, format_old_ext, format_new_ext, has_cover) + + if check == 0: + cur_book = local_db.get_book(book_id) + if os.path.isfile(file_path + format_new_ext): + new_format = local_db.session.query(db.Data).filter(db.Data.book == book_id) \ + .filter(db.Data.format == self.settings['new_book_format'].upper()).one_or_none() + if not new_format: + new_format = db.Data(name=cur_book.data[0].name, + book_format=self.settings['new_book_format'].upper(), + book=book_id, uncompressed_size=os.path.getsize(file_path + format_new_ext)) + try: + local_db.session.merge(new_format) + local_db.session.commit() + if self.settings['new_book_format'].upper() in ['KEPUB', 'EPUB', 'EPUB3']: + ub_session = init_db_thread() + remove_synced_book(book_id, True, ub_session) + ub_session.close() + except SQLAlchemyError as e: + local_db.session.rollback() + log.error("Database error: %s", e) + local_db.session.close() + self._handleError(error_message) + return + self.results['path'] = cur_book.path + self.title = cur_book.title + self.results['title'] = self.title + if not config.config_use_google_drive: + self._handleSuccess() + return os.path.basename(file_path + format_new_ext) + else: + error_message = N_('%(format)s format not found on disk', format=format_new_ext.upper()) + local_db.session.close() + log.info("ebook converter failed with error while converting book") + if not error_message: + error_message = N_('Ebook converter failed with unknown error') + else: + log.error(error_message) + self._handleError(error_message) + return + + def _convert_kepubify(self, file_path, format_old_ext, format_new_ext): + if config.config_embed_metadata and config.config_binariesdir: + tmp_dir, temp_file_name = helper.do_calibre_export(self.book_id, format_old_ext[1:]) + filename = os.path.join(tmp_dir, temp_file_name + format_old_ext) + temp_file_path = tmp_dir + else: + filename = file_path + format_old_ext + temp_file_path = os.path.dirname(file_path) + quotes = [1, 3] + command = [config.config_kepubifypath, filename, '-o', temp_file_path, '-i'] + try: + p = process_open(command, quotes) + except OSError as e: + return 1, N_("Kepubify-converter failed: %(error)s", error=e) + self.progress = 0.01 + while True: + nextline = p.stdout.readlines() + nextline = [x.strip('\n') for x in nextline if x != '\n'] + for line in nextline: + log.debug(line) + if p.poll() is not None: + break + + # process returncode + check = p.returncode + + # move file + if check == 0: + converted_file = glob.glob(glob.escape(os.path.splitext(filename)[0]) + "*.kepub.epub") + if len(converted_file) == 1: + copyfile(converted_file[0], (file_path + format_new_ext)) + os.unlink(converted_file[0]) + else: + return 1, N_("Converted file not found or more than one file in folder %(folder)s", + folder=os.path.dirname(file_path)) + return check, None + + def _convert_calibre(self, file_path, format_old_ext, format_new_ext, has_cover): + path_tmp_opf = None + try: + # path_tmp_opf = self._embed_metadata() + if config.config_embed_metadata: + quotes = [5] + tmp_dir = get_temp_dir() + calibredb_binarypath = os.path.join(config.config_binariesdir, SUPPORTED_CALIBRE_BINARIES["calibredb"]) + my_env = os.environ.copy() + if config.config_calibre_split: + my_env['CALIBRE_OVERRIDE_DATABASE_PATH'] = os.path.join(config.config_calibre_dir, "metadata.db") + library_path = config.config_calibre_split_dir + else: + library_path = config.config_calibre_dir + + opf_command = [calibredb_binarypath, 'show_metadata', '--as-opf', str(self.book_id), + '--with-library', library_path] + p = process_open(opf_command, quotes, my_env, newlines=False) + lines = list() + while p.poll() is None: + lines.append(p.stdout.readline()) + check = p.returncode + calibre_traceback = p.stderr.readlines() + if check == 0: + path_tmp_opf = os.path.join(tmp_dir, "metadata_" + str(uuid4()) + ".opf") + with open(path_tmp_opf, 'wb') as fd: + fd.write(b''.join(lines)) + else: + error_message = "" + for ele in calibre_traceback: + if not ele.startswith('Traceback') and not ele.startswith(' File'): + error_message = N_("Calibre failed with error: %(error)s", error=ele) + return check, error_message + quotes = [1, 2] + quotes_index = 3 + command = [config.config_converterpath, (file_path + format_old_ext), + (file_path + format_new_ext)] + if config.config_embed_metadata: + quotes.append(4) + quotes_index = 5 + command.extend(['--from-opf', path_tmp_opf]) + if has_cover: + quotes.append(6) + command.extend(['--cover', os.path.join(os.path.dirname(file_path), 'cover.jpg')]) + quotes_index = 7 + if config.config_calibre: + parameters = re.findall(r"(--[\w-]+)(?:(\s(?:(\".+\")|(?:.+?)))(?:\s|$))?", + config.config_calibre, re.IGNORECASE | re.UNICODE) + if parameters: + for param in parameters: + command.append(strip_whitespaces(param[0])) + quotes_index += 1 + if param[1] != "": + parsed = strip_whitespaces(param[1]).strip("\"") + command.append(parsed) + quotes.append(quotes_index) + quotes_index += 1 + p = process_open(command, quotes, newlines=False) + except OSError as e: + return 1, N_("Ebook-converter failed: %(error)s", error=e) + + while p.poll() is None: + nextline = p.stdout.readline() + if isinstance(nextline, bytes): + nextline = nextline.decode('utf-8', errors="ignore").strip('\r\n') + if nextline: + log.debug(nextline) + # parse progress string from calibre-converter + progress = re.search(r"(\d+)%\s.*", nextline) + if progress: + self.progress = int(progress.group(1)) / 100 + if config.config_use_google_drive: + self.progress *= 0.9 + + # process returncode + check = p.returncode + calibre_traceback = p.stderr.readlines() + error_message = "" + for ele in calibre_traceback: + ele = ele.decode('utf-8', errors="ignore").strip('\n') + log.debug(ele) + if not ele.startswith('Traceback') and not ele.startswith(' File'): + error_message = N_("Calibre failed with error: %(error)s", error=ele) + return check, error_message + + @property + def name(self): + return N_("Convert") + + def __str__(self): + if self.ereader_mail: + return "Convert Book {} and mail it to {}".format(self.book_id, self.ereader_mail) + else: + return "Convert Book {}".format(self.book_id) + + @property + def is_cancellable(self): + return False diff --git a/cps/tasks/database.py b/cps/tasks/database.py index c9c30d4..d5fb545 100755 --- a/cps/tasks/database.py +++ b/cps/tasks/database.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 mmonkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from flask_babel import lazy_gettext as N_ diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py index 49cd913..58504f8 100755 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import smtplib diff --git a/cps/tasks/metadata_backup.py b/cps/tasks/metadata_backup.py index 5e0bb96..f538f0d 100755 --- a/cps/tasks/metadata_backup.py +++ b/cps/tasks/metadata_backup.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 monkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os from lxml import etree diff --git a/cps/tasks/thumbnail.py b/cps/tasks/thumbnail.py index a7658c0..240234c 100755 --- a/cps/tasks/thumbnail.py +++ b/cps/tasks/thumbnail.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 monkey -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os from shutil import copyfile, copyfileobj diff --git a/cps/tasks/upload.py b/cps/tasks/upload.py index a74fc2f..e9329bf 100755 --- a/cps/tasks/upload.py +++ b/cps/tasks/upload.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2020 pwr -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from datetime import datetime diff --git a/cps/tasks_status.py b/cps/tasks_status.py index 268200d..638089c 100755 --- a/cps/tasks_status.py +++ b/cps/tasks_status.py @@ -1,18 +1,8 @@ -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from markupsafe import escape diff --git a/cps/tornado_wsgi.py b/cps/tornado_wsgi.py index f2aae6d..525dfb5 100755 --- a/cps/tornado_wsgi.py +++ b/cps/tornado_wsgi.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2022 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from tornado.wsgi import WSGIContainer import tornado diff --git a/cps/ub.py b/cps/ub.py index 8047fe7..ede72bd 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 mutschler, jkrehm, cervinko, janeczku, OzzieIsaacs, csitko -# ok11, issmirnov, idalin -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import atexit import os diff --git a/cps/updater.py b/cps/updater.py index e33b80f..63a82e3 100755 --- a/cps/updater.py +++ b/cps/updater.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2019 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import sys import os diff --git a/cps/uploader.py b/cps/uploader.py index 79016e4..af54909 100755 --- a/cps/uploader.py +++ b/cps/uploader.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2012-2019 lemmsh cervinko Kennyl matthazinski OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. import os import hashlib diff --git a/cps/usermanagement.py b/cps/usermanagement.py index 31c37a9..e5f13a7 100755 --- a/cps/usermanagement.py +++ b/cps/usermanagement.py @@ -1,20 +1,9 @@ # -*- coding: utf-8 -*- - -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018-2020 OzzieIsaacs -# -# 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 Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. from functools import wraps diff --git a/cps/web.py b/cps/web.py index eab65ed..3c4609f 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1,4 +1,10 @@ -# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + +) # Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, # andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, # falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, diff --git a/generate_contributors.py b/generate_contributors.py new file mode 100644 index 0000000..fff4f52 --- /dev/null +++ b/generate_contributors.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + +""" +Generate (or refresh) a CONTRIBUTORS file by querying the GitHub API for: + * Upstream Calibre-Web repo (janeczku/calibre-web) + * Fork Calibre-Web Automated repo (crocodilestick/calibre-web-automated) + +Features: + * Handles pagination (per_page=100) until all contributors are fetched. + * Includes anonymous contributors (?anon=1). + * Aggregates contribution counts per displayed name. + * Separates upstream and fork sections for clarity & license attribution. + * Uses GITHUB_TOKEN if present (recommended to avoid low unauthenticated rate limits). + * Idempotent: rewrites CONTRIBUTORS file in project root. + +Usage: + export GITHUB_TOKEN=ghp_xxx # optional but recommended + python generate_contributors.py + +Optional arguments: + --upstream owner/repo (default janeczku/calibre-web) + --fork owner/repo (default crocodilestick/calibre-web-automated) + --output FILENAME (default CONTRIBUTORS) + --include-avatars (adds avatar URLs as HTML comments) + +The script purposely avoids adding emails (privacy) and does not try to +resolve real names beyond what the contributors endpoint provides. + +Requires: requests (falls back to stdlib urllib if unavailable, with reduced functionality) +""" +from __future__ import annotations + +import argparse +import datetime +import json +import os +import sys +import time +from typing import Dict, List, Tuple + +try: + import requests # type: ignore +except ImportError: # Lightweight fallback (no pagination link parsing beyond basic) + requests = None # type: ignore + import urllib.request + import urllib.error + +DEFAULT_UPSTREAM = "janeczku/calibre-web" +DEFAULT_FORK = "crocodilestick/calibre-web-automated" +START_YEAR_FORK = 2024 + +API_BASE = "https://api.github.com" +PER_PAGE = 100 + + +def parse_args() -> argparse.Namespace: + p = argparse.ArgumentParser(description="Generate CONTRIBUTORS file from GitHub API") + p.add_argument("--upstream", default=DEFAULT_UPSTREAM, help="Upstream owner/repo") + p.add_argument("--fork", default=DEFAULT_FORK, help="Fork owner/repo") + p.add_argument("--output", default="CONTRIBUTORS", help="Output filename") + p.add_argument("--include-avatars", action="store_true", help="Include avatar URLs as comments") + p.add_argument("--timeout", type=float, default=15.0, help="HTTP timeout seconds") + p.add_argument("--retries", type=int, default=3, help="Retry attempts on transient errors") + return p.parse_args() + + +def gh_headers() -> Dict[str, str]: + token = os.getenv("GITHUB_TOKEN") + h = {"Accept": "application/vnd.github+json"} + if token: + h["Authorization"] = f"Bearer {token}" + return h + + +def http_get(url: str, timeout: float) -> Tuple[int, Dict[str, str], str]: + """Returns (status_code, headers, text).""" + if requests: + resp = requests.get(url, headers=gh_headers(), timeout=timeout) + return resp.status_code, dict(resp.headers), resp.text + else: + req = urllib.request.Request(url, headers=gh_headers()) + try: + with urllib.request.urlopen(req, timeout=timeout) as r: # type: ignore + return r.status, dict(r.headers), r.read().decode() + except urllib.error.HTTPError as e: # type: ignore + return e.code, dict(e.headers), e.read().decode(errors="ignore") + + +def parse_link_header(headers: Dict[str, str]) -> Dict[str, str]: + link = headers.get("Link") or headers.get("link") + res: Dict[str, str] = {} + if not link: + return res + parts = link.split(",") + for part in parts: + segs = part.split(";") + if len(segs) < 2: + continue + url_part = segs[0].strip().lstrip("<").rstrip(">") + rel = None + for s in segs[1:]: + if "rel=" in s: + rel = s.split("=", 1)[1].strip().strip('"') + if rel: + res[rel] = url_part + return res + + +def fetch_all_contributors(repo: str, timeout: float, retries: int) -> List[Dict]: + owner_repo = repo + url = f"{API_BASE}/repos/{owner_repo}/contributors?per_page={PER_PAGE}&anon=1" + all_items: List[Dict] = [] + while url: + attempt = 0 + while attempt <= retries: + status, headers, text = http_get(url, timeout) + if status == 200: + break + attempt += 1 + if status in (403, 429) and attempt <= retries: + # simple backoff on rate limiting + time.sleep(2 * attempt) + else: + sys.stderr.write(f"Warning: failed to fetch {url} (status {status})\n") + return all_items + try: + data = json.loads(text) + if not isinstance(data, list): # Unexpected structure + sys.stderr.write(f"Warning: unexpected JSON structure for {repo}\n") + return all_items + all_items.extend(data) + except json.JSONDecodeError: + sys.stderr.write(f"Warning: JSON decode error for {repo}\n") + return all_items + links = parse_link_header(headers) + url = links.get("next") + return all_items + + +def aggregate(items: List[Dict]) -> Dict[str, Dict[str, int]]: + """Return mapping display_name -> {'contributions': int, 'anonymous': 0/1}.""" + agg: Dict[str, Dict[str, int]] = {} + for c in items: + login = c.get("login") + is_anon = 1 if (c.get("type") == "Anonymous" or login is None) else 0 + name = login or c.get("name") or "anonymous" + entry = agg.setdefault(name, {"contributions": 0, "anonymous": is_anon}) + entry["contributions"] += int(c.get("contributions", 0)) + # If any occurrence is anonymous, keep flag + entry["anonymous"] = max(entry["anonymous"], is_anon) + return agg + + +def format_section(title: str, repo: str, agg: Dict[str, Dict[str, int]], include_avatars: bool, raw_items: List[Dict]) -> str: + lines = [f"# {title} ({repo})", ""] + # Map name -> avatar (first occurrence) + avatar_map: Dict[str, str] = {} + if include_avatars: + for c in raw_items: + key = c.get("login") or c.get("name") or "anonymous" + if key not in avatar_map and c.get("avatar_url"): + avatar_map[key] = c["avatar_url"] + for name, data in sorted(agg.items(), key=lambda x: (-x[1]["contributions"], x[0].lower())): + anon_mark = " (anon)" if data["anonymous"] else "" + line = f"- {name}{anon_mark} ({data['contributions']} commits)" + if include_avatars and name in avatar_map: + line += f" " + lines.append(line) + lines.append("") + return "\n".join(lines) + + +def build_contributors(upstream: str, fork: str, include_avatars: bool, timeout: float, retries: int) -> str: + upstream_items = fetch_all_contributors(upstream, timeout, retries) + fork_items = fetch_all_contributors(fork, timeout, retries) + + upstream_agg = aggregate(upstream_items) + fork_agg = aggregate(fork_items) + + year_now = datetime.date.today().year + + header = [ + "CONTRIBUTORS", + "", # blank line + "This file is automatically generated. DO NOT EDIT MANUALLY.", + f"Generated on: {datetime.datetime.utcnow().isoformat()}Z", + "", # blank line + f"Upstream project: https://github.com/{upstream}", + f"Fork project (Calibre-Web Automated, since {START_YEAR_FORK}): https://github.com/{fork}", + "", # blank + "License notice: This fork retains attribution to original Calibre-Web contributors in accordance with GPL-3.0-or-later.", + "", # blank + f"Copyright (C) 2018-{year_now} Calibre-Web contributors", + f"Copyright (C) {START_YEAR_FORK}-{year_now} Calibre-Web Automated contributors", + "", + ] + + upstream_section = format_section("Upstream Contributors", upstream, upstream_agg, include_avatars, upstream_items) + fork_section = format_section("Fork Contributors", fork, fork_agg, include_avatars, fork_items) + + return "\n".join(header) + upstream_section + fork_section + + +def main() -> int: + args = parse_args() + content = build_contributors(args.upstream, args.fork, args.include_avatars, args.timeout, args.retries) + with open(args.output, "w", encoding="utf-8") as f: + f.write(content) + print(f"Wrote {args.output} (contributors from {args.upstream} and {args.fork})") + return 0 + + +if __name__ == "__main__": # pragma: no cover + raise SystemExit(main()) diff --git a/generate_translation_status.py b/generate_translation_status.py index 2a531b7..569bbf4 100644 --- a/generate_translation_status.py +++ b/generate_translation_status.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import polib import glob diff --git a/scripts/audiobook.py b/scripts/audiobook.py index 141a00c..390db46 100644 --- a/scripts/audiobook.py +++ b/scripts/audiobook.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + # This file is is mostly taken from audio.py from Ozzieisaacs at calibre-web import base64 diff --git a/scripts/auto_library.py b/scripts/auto_library.py index 291ce4d..508d4b6 100644 --- a/scripts/auto_library.py +++ b/scripts/auto_library.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import json import os import shutil diff --git a/scripts/auto_zip.py b/scripts/auto_zip.py index 00c7622..7d1b69e 100644 --- a/scripts/auto_zip.py +++ b/scripts/auto_zip.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import os import sys from os.path import isfile, join diff --git a/scripts/convert_library.py b/scripts/convert_library.py index 88f5c87..e94e262 100644 --- a/scripts/convert_library.py +++ b/scripts/convert_library.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import argparse import json import logging diff --git a/scripts/cover_enforcer.py b/scripts/cover_enforcer.py index 3d43130..1cd7e7d 100644 --- a/scripts/cover_enforcer.py +++ b/scripts/cover_enforcer.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import argparse import json import os diff --git a/scripts/cwa_db.py b/scripts/cwa_db.py index 3b25766..b5d1557 100644 --- a/scripts/cwa_db.py +++ b/scripts/cwa_db.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import sqlite3 import sys from sqlite3 import Error as sqlError diff --git a/scripts/ingest_processor.py b/scripts/ingest_processor.py index 4d73b7e..65561d9 100644 --- a/scripts/ingest_processor.py +++ b/scripts/ingest_processor.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import atexit import json import os diff --git a/scripts/kindle_epub_fixer.py b/scripts/kindle_epub_fixer.py index 06695fe..2962070 100644 --- a/scripts/kindle_epub_fixer.py +++ b/scripts/kindle_epub_fixer.py @@ -1,3 +1,9 @@ +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + import os import re import zipfile diff --git a/update_spdx_headers.py b/update_spdx_headers.py new file mode 100644 index 0000000..648cd3e --- /dev/null +++ b/update_spdx_headers.py @@ -0,0 +1,239 @@ +#!/usr/bin/env python3 +# Calibre-Web Automated – fork of Calibre-Web +# Copyright (C) 2018-2025 Calibre-Web contributors +# Copyright (C) 2024-2025 Calibre-Web Automated contributors +# SPDX-License-Identifier: GPL-3.0-or-later +# See CONTRIBUTORS for full list of authors. + +""" +update_spdx_headers.py + +Purpose: + Normalize / insert concise GPL license + attribution headers with SPDX into source files. + Designed for Calibre-Web Automated (fork of janeczku/calibre-web). + +Behavior: + * Scans files (default: **/*.py) excluding common vendor / build / translation dirs. + * Detects existing legacy Calibre-Web header blocks and replaces them with the new short form. + * Inserts header if none present. + * Respects existing shebang (kept as first line). + * Avoids duplicating if header already normalized. + * Updates year range dynamically (current year) and fork start year (2024). + +Resulting header (example): + # Calibre-Web Automated – fork of Calibre-Web + # Copyright (C) 2018-2025 Calibre-Web contributors + # Copyright (C) 2024-2025 Calibre-Web Automated contributors + # SPDX-License-Identifier: GPL-3.0-or-later + # See CONTRIBUTORS for full list of authors. + +CLI: + --apply Write changes (default dry-run). + --paths PATH [PATH] Limit to specific paths/files. + --ext .py,.sh Comma separated list of extensions (default .py) + --exclude PAT Extra glob-style exclude (can repeat) + --print Print updated content to stdout (only valid when single file & --apply not set) + --verbose Verbose logging + --quiet Only errors + --license-only Only add SPDX line if missing (preserve existing header text otherwise) + --force-year-start YEAR Override upstream start year (default 2018) + +Exit codes: + 0 success, 1 errors. + +NOTE: Commit the CONTRIBUTORS file separately; headers reference it. +""" +from __future__ import annotations + +import argparse +import datetime +import pathlib +import re +import sys +from typing import Iterable, List + +UPSTREAM_START_DEFAULT = 2018 +FORK_START = 2024 +CURRENT_YEAR = datetime.date.today().year + +LEGACY_PATTERNS = [ + re.compile(r"This file is part of the Calibre-Web", re.IGNORECASE), + re.compile(r"GNU General Public License", re.IGNORECASE), +] + +SPDX_RE = re.compile(r"SPDX-License-Identifier:\s*GPL-3\.0-or-later") +HEADER_ALREADY_RE = re.compile(r"Calibre-Web Automated .*?SPDX-License-Identifier: GPL-3\.0-or-later", re.DOTALL) + +SHEBANG_RE = re.compile(r"^#!.*\n") +CODING_RE = re.compile(r"^#.*coding[:=].*\n", re.IGNORECASE) + +EXCLUDE_DIRS = { + ".git", "__pycache__", "build", "dist", "venv", ".venv", "env", "node_modules", + "translations", "locale", "docs/_build", "htmlcov" +} + +DEFAULT_EXTS = [".py"] + +HEADER_TEMPLATE = ( + "# Calibre-Web Automated – fork of Calibre-Web\n" + "# Copyright (C) {upstream_start}-{year} Calibre-Web contributors\n" + "# Copyright (C) {fork_start}-{year} Calibre-Web Automated contributors\n" + "# SPDX-License-Identifier: GPL-3.0-or-later\n" + "# See CONTRIBUTORS for full list of authors.\n" + "\n" +) + + +def parse_args(): + p = argparse.ArgumentParser(description="Normalize SPDX headers") + p.add_argument("--apply", action="store_true", help="Write changes (default dry-run)") + p.add_argument("--paths", nargs="*", help="Optional list of files/dirs to process") + p.add_argument("--ext", default=",".join(DEFAULT_EXTS), help="Comma separated extensions") + p.add_argument("--exclude", action="append", default=[], help="Additional directory/file exclude (glob contains)") + p.add_argument("--print", action="store_true", help="Print updated content (only single file dry-run)") + p.add_argument("--verbose", action="store_true") + p.add_argument("--quiet", action="store_true") + p.add_argument("--license-only", action="store_true", help="Only inject SPDX if missing") + p.add_argument("--force-year-start", type=int, default=UPSTREAM_START_DEFAULT) + return p.parse_args() + + +def log(msg: str, *, verbose=False, quiet=False): + if quiet: + return + if verbose: + print(msg) + + +def collect_paths(paths: List[str] | None, exts: List[str], extra_excludes: List[str]) -> Iterable[pathlib.Path]: + if not paths: + roots = [pathlib.Path.cwd()] + else: + roots = [pathlib.Path(p).resolve() for p in paths] + for root in roots: + if root.is_file(): + if root.suffix in exts: + yield root + continue + for p in root.rglob("*"): + if p.is_dir(): + # skip excluded dirs + if p.name in EXCLUDE_DIRS: + continue + if any(x for x in extra_excludes if x and x in str(p)): + continue + continue + if p.suffix not in exts: + continue + if any(x for x in extra_excludes if x and x in str(p)): + continue + yield p + + +def has_legacy(text: str) -> bool: + return any(p.search(text[:1000]) for p in LEGACY_PATTERNS) + + +def already_normalized(text: str) -> bool: + return HEADER_ALREADY_RE.search(text[:400]) is not None + + +def build_header(upstream_start: int) -> str: + return HEADER_TEMPLATE.format(upstream_start=upstream_start, fork_start=FORK_START, year=CURRENT_YEAR) + + +def extract_preamble(text: str): + shebang = "" + coding = "" + rest = text + m = SHEBANG_RE.match(rest) + if m: + shebang = m.group(0) + rest = rest[len(shebang):] + m2 = CODING_RE.match(rest) + if m2: + coding = m2.group(0) + rest = rest[len(coding):] + return shebang, coding, rest + + +LEGACY_BLOCK_RE = re.compile( + r"^(?:#.*Calibre-Web.*\n)(?:#.*\n){0,40}#.*http.*gnu.*licenses.*\n", re.IGNORECASE | re.MULTILINE +) + + +def normalize(text: str, upstream_start: int, license_only: bool) -> str: + if license_only: + if SPDX_RE.search(text): + return text # nothing + # append SPDX at top after any shebang/coding line + shebang, coding, rest = extract_preamble(text) + header = f"{shebang}{coding}# SPDX-License-Identifier: GPL-3.0-or-later\n" + return header + rest + + if already_normalized(text): + # Maybe year change? Replace years if outdated + def repl_years(match: re.Match): + return build_header(upstream_start) + # Replace only first occurrence of our template block start + return re.sub(r"^# Calibre-Web Automated .*?\n\n", repl_years, text, count=1, flags=re.DOTALL) + + shebang, coding, rest = extract_preamble(text) + + # Remove legacy if present + new_rest = LEGACY_BLOCK_RE.sub("", rest, count=1) if has_legacy(rest) else rest + + new_header = build_header(upstream_start) + return f"{shebang}{coding}{new_header}{new_rest.lstrip()}" + + +def process_file(path: pathlib.Path, upstream_start: int, license_only: bool, apply: bool, verbose: bool, quiet: bool) -> bool: + try: + original = path.read_text(encoding="utf-8") + except Exception as e: + if not quiet: + print(f"ERROR: Cannot read {path}: {e}", file=sys.stderr) + return False + updated = normalize(original, upstream_start, license_only) + changed = updated != original + if changed and apply: + try: + path.write_text(updated, encoding="utf-8") + except Exception as e: + if not quiet: + print(f"ERROR: Cannot write {path}: {e}", file=sys.stderr) + return False + if changed: + log(f"Updated: {path}", verbose=verbose, quiet=quiet) + return True + + +def main() -> int: + args = parse_args() + exts = [e if e.startswith('.') else f'.{e}' for e in args.ext.split(',') if e.strip()] + + targets = list(collect_paths(args.paths, exts, args.exclude)) + if not targets: + print("No matching files.") + return 0 + + ok = True + for p in targets: + if not process_file(p, args.force_year_start, args.license_only, args.apply, args.verbose, args.quiet): + ok = False + + # Optional print (single file, dry run) + if args.print and not args.apply and len(targets) == 1: + path = targets[0] + text = path.read_text(encoding='utf-8') + print(normalize(text, args.force_year_start, args.license_only)) + + if not ok: + return 1 + if not args.apply: + print("(dry-run) Use --apply to write changes.") + return 0 + + +if __name__ == "__main__": # pragma: no cover + raise SystemExit(main())