Merge branch 'develop' into talker_settings_generator
# Conflicts: # comictaggerlib/settingswindow.py # comictalker/talkers/comicvine.py
This commit is contained in:
commit
33ea8da5bc
43
.github/workflows/contributions.yaml
vendored
Normal file
43
.github/workflows/contributions.yaml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: Contributions
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'develop'
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
contrib-readme-job:
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CI_COMMIT_AUTHOR: github-actions[bot]
|
||||
CI_COMMIT_EMAIL: <41898282+github-actions[bot]@users.noreply.github.com>
|
||||
CI_COMMIT_MESSAGE: Update AUTHORS
|
||||
name: A job to automate contrib in readme
|
||||
steps:
|
||||
- name: Contribute List
|
||||
uses: akhilmhdh/contributors-readme-action@v2.3.6
|
||||
with:
|
||||
use_username: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Update AUTHORS
|
||||
run: |
|
||||
git config --global log.mailmap true
|
||||
git log --reverse '--format=%aN <%aE>' | cat -n | sort -uk2 | sort -n | cut -f2- >AUTHORS
|
||||
|
||||
- name: Commit and push AUTHORS
|
||||
run: |
|
||||
if ! git diff --exit-code; then
|
||||
git pull
|
||||
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
|
||||
git config --global user.email "${{ env.CI_COMMIT_EMAIL }}"
|
||||
git commit -a -m "${{ env.CI_COMMIT_MESSAGE }}"
|
||||
git push
|
||||
fi
|
9
.mailmap
Normal file
9
.mailmap
Normal file
@ -0,0 +1,9 @@
|
||||
Andrew W. Buchanan <buchanan@difference.com>
|
||||
Davide Romanini <d.romanini@cineca.it> <davide.romanini@gmail.com>
|
||||
Davide Romanini <d.romanini@cineca.it> <user159033@92-63-141-211.rdns.melbourne.co.uk>
|
||||
Michael Fitzurka <MichaelFitzurka@users.noreply.github.com> <MichaelFitzurka@github.com>
|
||||
Timmy Welch <timmy@narnian.us>
|
||||
beville <beville@users.noreply.github.com> <(no author)@6c5673fe-1810-88d6-992b-cd32ca31540c>
|
||||
beville <beville@users.noreply.github.com> <beville@6c5673fe-1810-88d6-992b-cd32ca31540c>
|
||||
beville <beville@users.noreply.github.com> <beville@gmail.com@6c5673fe-1810-88d6-992b-cd32ca31540c>
|
||||
beville <beville@users.noreply.github.com> <beville@users.noreply.github.com>
|
15
AUTHORS
Normal file
15
AUTHORS
Normal file
@ -0,0 +1,15 @@
|
||||
beville <beville@users.noreply.github.com>
|
||||
Davide Romanini <d.romanini@cineca.it>
|
||||
fcanc <f.canc@icloud.com>
|
||||
Alban Seurat <alkpone@alkpone.com>
|
||||
tlc <tlc@users.noreply.github.com>
|
||||
Marek Pawlak <francuz14@gmail.com>
|
||||
Timmy Welch <timmy@narnian.us>
|
||||
J.P. Cranford <philipcranford4@gmail.com>
|
||||
thFrgttn <39759781+thFrgttn@users.noreply.github.com>
|
||||
Andrew W. Buchanan <buchanan@difference.com>
|
||||
Michael Fitzurka <MichaelFitzurka@users.noreply.github.com>
|
||||
Richard Haussmann <richard.haussmann@gmail.com>
|
||||
Mizaki <jinxybob@hotmail.com>
|
||||
Xavier Jouvenot <x.jouvenot@gmail.com>
|
||||
github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
109
README.md
109
README.md
@ -61,3 +61,112 @@ choco install comictagger
|
||||
2. Clone this repository `git clone https://github.com/comictagger/comictagger.git`
|
||||
3. `pip3 install -r requirements_dev.txt`
|
||||
7. `pip3 install .` or `pip3 install .[GUI]`
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
<!-- readme: beville,davide-romanini,collaborators,contributors -start -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/beville">
|
||||
<img src="https://avatars.githubusercontent.com/u/7294848?v=4" width="100;" alt="beville"/>
|
||||
<br />
|
||||
<sub><b>beville</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/davide-romanini">
|
||||
<img src="https://avatars.githubusercontent.com/u/731199?v=4" width="100;" alt="davide-romanini"/>
|
||||
<br />
|
||||
<sub><b>davide-romanini</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/mizaki">
|
||||
<img src="https://avatars.githubusercontent.com/u/1141189?v=4" width="100;" alt="mizaki"/>
|
||||
<br />
|
||||
<sub><b>mizaki</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/lordwelch">
|
||||
<img src="https://avatars.githubusercontent.com/u/7547075?v=4" width="100;" alt="lordwelch"/>
|
||||
<br />
|
||||
<sub><b>lordwelch</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MichaelFitzurka">
|
||||
<img src="https://avatars.githubusercontent.com/u/27830765?v=4" width="100;" alt="MichaelFitzurka"/>
|
||||
<br />
|
||||
<sub><b>MichaelFitzurka</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/fcanc">
|
||||
<img src="https://avatars.githubusercontent.com/u/4999486?v=4" width="100;" alt="fcanc"/>
|
||||
<br />
|
||||
<sub><b>fcanc</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/abuchanan920">
|
||||
<img src="https://avatars.githubusercontent.com/u/368793?v=4" width="100;" alt="abuchanan920"/>
|
||||
<br />
|
||||
<sub><b>abuchanan920</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AlbanSeurat">
|
||||
<img src="https://avatars.githubusercontent.com/u/500180?v=4" width="100;" alt="AlbanSeurat"/>
|
||||
<br />
|
||||
<sub><b>AlbanSeurat</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/rhaussmann">
|
||||
<img src="https://avatars.githubusercontent.com/u/7084007?v=4" width="100;" alt="rhaussmann"/>
|
||||
<br />
|
||||
<sub><b>rhaussmann</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jpcranford">
|
||||
<img src="https://avatars.githubusercontent.com/u/21347202?v=4" width="100;" alt="jpcranford"/>
|
||||
<br />
|
||||
<sub><b>jpcranford</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/PawlakMarek">
|
||||
<img src="https://avatars.githubusercontent.com/u/26022173?v=4" width="100;" alt="PawlakMarek"/>
|
||||
<br />
|
||||
<sub><b>PawlakMarek</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Xav83">
|
||||
<img src="https://avatars.githubusercontent.com/u/6787157?v=4" width="100;" alt="Xav83"/>
|
||||
<br />
|
||||
<sub><b>Xav83</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/thFrgttn">
|
||||
<img src="https://avatars.githubusercontent.com/u/39759781?v=4" width="100;" alt="thFrgttn"/>
|
||||
<br />
|
||||
<sub><b>thFrgttn</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/tlc">
|
||||
<img src="https://avatars.githubusercontent.com/u/19436?v=4" width="100;" alt="tlc"/>
|
||||
<br />
|
||||
<sub><b>tlc</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!-- readme: beville,davide-romanini,collaborators,contributors -end -->
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A class to encapsulate CoMet data"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""A class to represent a single comic, be it file or folder of images"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""A class to encapsulate the ComicBookInfo data"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""A class to encapsulate ComicRack's ComicInfo.xml data"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
This should probably be re-written, but, well, it mostly works!
|
||||
"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -5,7 +5,7 @@ tagging schemes and databases, such as ComicVine or GCD. This makes conversion
|
||||
possible, however lossy it might be
|
||||
|
||||
"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -4,7 +4,7 @@ Class for handling the odd permutations of an 'issue number' that the
|
||||
comics industry throws at us.
|
||||
e.g.: "12", "12.1", "0", "-1", "5AU", "100-2"
|
||||
"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""Some generic utilities"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from PyInstaller.utils.hooks import collect_data_files
|
||||
from PyInstaller.utils.hooks import collect_data_files, collect_entry_point
|
||||
|
||||
datas = []
|
||||
datas, hiddenimports = collect_entry_point("comictagger.talker")
|
||||
datas += collect_data_files("comictaggerlib.ui")
|
||||
datas += collect_data_files("comictaggerlib.graphics")
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to select from automated issue matches"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to show ID log and progress"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to confirm and set config for auto-tag"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A class to manage modifying metadata specifically for CBL/CBI"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
"""ComicTagger CLI functions"""
|
||||
#
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -4,7 +4,7 @@ Display cover images from either a local archive, or from Comic Vine.
|
||||
TODO: This should be re-factored using subclasses!
|
||||
"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to edit credits"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""CLI settings for ComicTagger"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -236,7 +236,7 @@ def register_commands(parser: settngs.Manager) -> None:
|
||||
|
||||
def register_commandline_settings(parser: settngs.Manager) -> None:
|
||||
parser.add_group("commands", register_commands, True)
|
||||
parser.add_group("runtime", register_settings)
|
||||
parser.add_persistent_group("runtime", register_settings)
|
||||
|
||||
|
||||
def validate_commandline_settings(
|
||||
|
@ -12,23 +12,39 @@ logger = logging.getLogger("comictagger")
|
||||
|
||||
|
||||
def archiver(manager: settngs.Manager) -> None:
|
||||
exe_registered: set[str] = set()
|
||||
for archiver in comicapi.comicarchive.archivers:
|
||||
if archiver.exe and archiver.exe not in exe_registered:
|
||||
if archiver.exe:
|
||||
# add_setting will overwrite anything with the same name.
|
||||
# So we only end up with one option even if multiple archivers use the same exe.
|
||||
manager.add_setting(
|
||||
f"--{archiver.exe.replace(' ', '-').replace('_', '-').strip().strip('-')}",
|
||||
f"--{settngs.sanitize_name(archiver.exe)}",
|
||||
default=archiver.exe,
|
||||
help="Path to the %(default)s executable\n\n",
|
||||
)
|
||||
exe_registered.add(archiver.exe)
|
||||
|
||||
|
||||
def register_talker_settings(manager: settngs.Manager) -> None:
|
||||
for talker_name, talker in comictaggerlib.ctsettings.talkers.items():
|
||||
for talker_id, talker in comictaggerlib.ctsettings.talkers.items():
|
||||
|
||||
def api_options(manager: settngs.Manager) -> None:
|
||||
manager.add_setting(
|
||||
f"--{talker_id}-key",
|
||||
default="",
|
||||
display_name="API Key",
|
||||
help=f"API Key for {talker.name} (default: {talker.default_api_key})",
|
||||
)
|
||||
manager.add_setting(
|
||||
f"--{talker_id}-url",
|
||||
default="",
|
||||
display_name="URL",
|
||||
help=f"URL for {talker.name} (default: {talker.default_api_url})",
|
||||
)
|
||||
|
||||
try:
|
||||
manager.add_persistent_group("talker_" + talker_name, talker.register_settings, False)
|
||||
manager.add_persistent_group("talker_" + talker_id, api_options, False)
|
||||
manager.add_persistent_group("talker_" + talker_id, talker.register_settings, False)
|
||||
except Exception:
|
||||
logger.exception("Failed to register settings for %s", talker_name)
|
||||
logger.exception("Failed to register settings for %s", talker_id)
|
||||
|
||||
|
||||
def validate_archive_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
@ -37,11 +53,7 @@ def validate_archive_settings(config: settngs.Config[settngs.Namespace]) -> sett
|
||||
cfg = settngs.normalize_config(config, file=True, cmdline=True, defaults=False)
|
||||
for archiver in comicapi.comicarchive.archivers:
|
||||
exe_name = settngs.sanitize_name(archiver.exe)
|
||||
if (
|
||||
exe_name in cfg[0]["archiver"]
|
||||
and cfg[0]["archiver"][exe_name]
|
||||
and cfg[0]["archiver"][exe_name] != archiver.exe
|
||||
):
|
||||
if exe_name in cfg[0]["archiver"] and cfg[0]["archiver"][exe_name]:
|
||||
if os.path.basename(cfg[0]["archiver"][exe_name]) == archiver.exe:
|
||||
comicapi.utils.add_to_path(os.path.dirname(cfg[0]["archiver"][exe_name]))
|
||||
else:
|
||||
@ -53,15 +65,15 @@ def validate_archive_settings(config: settngs.Config[settngs.Namespace]) -> sett
|
||||
def validate_talker_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
# Apply talker settings from config file
|
||||
cfg = settngs.normalize_config(config, True, True)
|
||||
for talker_name, talker in list(comictaggerlib.ctsettings.talkers.items()):
|
||||
for talker_id, talker in list(comictaggerlib.ctsettings.talkers.items()):
|
||||
try:
|
||||
talker.parse_settings(cfg[0]["talker_" + talker_name])
|
||||
cfg[0]["talker_" + talker_id] = talker.parse_settings(cfg[0]["talker_" + talker_id])
|
||||
except Exception as e:
|
||||
# Remove talker as we failed to apply the settings
|
||||
del comictaggerlib.ctsettings.talkers[talker_name]
|
||||
del comictaggerlib.ctsettings.talkers[talker_id]
|
||||
logger.exception("Failed to initialize talker settings: %s", e)
|
||||
|
||||
return config
|
||||
return settngs.get_namespace(cfg)
|
||||
|
||||
|
||||
def validate_plugin_settings(config: settngs.Config[settngs.Namespace]) -> settngs.Config[settngs.Namespace]:
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to confirm and set options for export to zip"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Functions for renaming files based on metadata"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQt5 widget for managing list of comic archive files"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A class to manage fetching and caching of images by URL"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A class to manage creating image content hashes, and calculate hamming distances"""
|
||||
#
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 widget to display a popup image"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A class to automatically identify a comic archive"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to select specific issue from list"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to a text file or log"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A python app to (automatically) tag comic archives"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -119,6 +119,15 @@ class App:
|
||||
# config already loaded
|
||||
error = None
|
||||
|
||||
talkers = ctsettings.talkers
|
||||
del ctsettings.talkers
|
||||
|
||||
if len(talkers) < 1:
|
||||
error = error = (
|
||||
f"Failed to load any talkers, please re-install and check the log located in '{self.config[0].runtime_config.user_log_dir}' for more details",
|
||||
True,
|
||||
)
|
||||
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
logger.debug("Installed Packages")
|
||||
@ -134,7 +143,10 @@ class App:
|
||||
|
||||
# manage the CV API key
|
||||
# None comparison is used so that the empty string can unset the value
|
||||
if self.config[0].talker_comicvine_cv_api_key is not None or self.config[0].talker_comicvine_cv_url is not None:
|
||||
if not error and (
|
||||
self.config[0].talker_comicvine_comicvine_key is not None
|
||||
or self.config[0].talker_comicvine_comicvine_url is not None
|
||||
):
|
||||
settings_path = self.config[0].runtime_config.user_config_dir / "settings.json"
|
||||
if self.config_load_success:
|
||||
self.manager.save_file(self.config[0], settings_path)
|
||||
@ -150,9 +162,6 @@ class App:
|
||||
True,
|
||||
)
|
||||
|
||||
talkers = ctsettings.talkers
|
||||
del ctsettings.talkers
|
||||
|
||||
if self.config[0].runtime_no_gui:
|
||||
if error and error[1]:
|
||||
print(f"A fatal error occurred please check the log for more information: {error[0]}") # noqa: T201
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to select from automated issue matches"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -11,7 +11,7 @@ said_yes, checked = OptionalMessageDialog.question(self, "QtWidgets.Question",
|
||||
)
|
||||
"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to show pages of a comic archive"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQt5 widget for editing the page list info"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 class to load a page image from a ComicArchive in a background thread"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQt5 dialog to show ID log and progress"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to confirm rename"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to select specific series/volume from list"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A PyQT4 dialog to enter app settings"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""The main window of the ComicTagger app"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Version checker"""
|
||||
#
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -2,8 +2,13 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
from importlib_metadata import entry_points
|
||||
else:
|
||||
from importlib.metadata import entry_points
|
||||
|
||||
import comictalker.talkers.comicvine
|
||||
from comictalker.comictalker import ComicTalker, TalkerError
|
||||
from comictalker.resulttypes import ComicIssue, ComicSeries
|
||||
|
||||
@ -21,11 +26,16 @@ def get_talkers(version: str, cache: pathlib.Path) -> dict[str, ComicTalker]:
|
||||
"""Returns all comic talker instances"""
|
||||
talkers: dict[str, ComicTalker] = {}
|
||||
|
||||
for talker in [comictalker.talkers.comicvine.ComicVineTalker]:
|
||||
for talker in entry_points(group="comictagger.talker"):
|
||||
try:
|
||||
obj = talker(version, cache)
|
||||
talkers[obj.id] = obj
|
||||
talker_cls = talker.load()
|
||||
obj = talker_cls(version, cache)
|
||||
if obj.id != talker.name:
|
||||
logger.error("Talker ID must be the same as the entry point name")
|
||||
continue
|
||||
talkers[talker.name] = obj
|
||||
|
||||
except Exception:
|
||||
logger.exception("Failed to load talker: %s", "comicvine")
|
||||
raise TalkerError(source="comicvine", code=4, desc="Failed to initialise talker")
|
||||
logger.exception("Failed to load talker: %s", talker.name)
|
||||
|
||||
return talkers
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""A python class to manage caching of data from Comic Vine"""
|
||||
#
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License;
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -378,7 +378,12 @@ class ComicCacher:
|
||||
)
|
||||
|
||||
# now process the results
|
||||
|
||||
credits = []
|
||||
try:
|
||||
for credit in json.loads(row[13]):
|
||||
credits.append(Credit(**credit))
|
||||
except Exception:
|
||||
logger.exception("credits failed")
|
||||
record = ComicIssue(
|
||||
id=row[1],
|
||||
name=row[2],
|
||||
@ -392,7 +397,7 @@ class ComicCacher:
|
||||
alt_image_urls=row[10].strip().splitlines(),
|
||||
characters=row[11].strip().splitlines(),
|
||||
locations=row[12].strip().splitlines(),
|
||||
credits=json.loads(row[13]),
|
||||
credits=credits,
|
||||
teams=row[14].strip().splitlines(),
|
||||
story_arcs=row[15].strip().splitlines(),
|
||||
complete=bool(row[16]),
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -21,6 +21,7 @@ import settngs
|
||||
|
||||
from comicapi.genericmetadata import GenericMetadata
|
||||
from comictalker.resulttypes import ComicIssue, ComicSeries
|
||||
from comictalker.talker_utils import fix_url
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -107,15 +108,15 @@ class ComicTalker:
|
||||
|
||||
name: str = "Example"
|
||||
id: str = "example"
|
||||
logo_url: str = "https://example.com/logo.png"
|
||||
website: str = "https://example.com/"
|
||||
website: str = "https://example.com"
|
||||
logo_url: str = f"{website}/logo.png"
|
||||
attribution: str = f"Metadata provided by <a href='{website}'>{name}</a>"
|
||||
|
||||
def __init__(self, version: str, cache_folder: pathlib.Path) -> None:
|
||||
self.cache_folder = cache_folder
|
||||
self.version = version
|
||||
self.api_key: str = ""
|
||||
self.api_url: str = ""
|
||||
self.api_key = self.default_api_key = ""
|
||||
self.api_url = self.default_api_url = ""
|
||||
|
||||
def register_settings(self, parser: settngs.Manager) -> None:
|
||||
"""
|
||||
@ -129,6 +130,15 @@ class ComicTalker:
|
||||
settings is a dictionary of settings defined in register_settings.
|
||||
It is only guaranteed that the settings defined in register_settings will be present.
|
||||
"""
|
||||
if settings[f"{self.id}_key"]:
|
||||
self.api_key = settings[f"{self.id}_key"]
|
||||
if settings[f"{self.id}_url"]:
|
||||
self.api_url = fix_url(settings[f"{self.id}_url"])
|
||||
|
||||
if self.api_key == "":
|
||||
self.api_key = self.default_api_key
|
||||
if self.api_url == "":
|
||||
self.api_url = self.default_api_url
|
||||
return settings
|
||||
|
||||
def check_api_key(self, key: str) -> bool:
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -15,6 +15,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import re
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
@ -26,6 +27,14 @@ from comictalker.resulttypes import ComicIssue
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def fix_url(url: str) -> str:
|
||||
tmp_url = urlsplit(url)
|
||||
# joinurl only works properly if there is a trailing slash
|
||||
if tmp_url.path and tmp_url.path[-1] != "/":
|
||||
tmp_url = tmp_url._replace(path=tmp_url.path + "/")
|
||||
return tmp_url.geturl()
|
||||
|
||||
|
||||
def map_comic_issue_to_metadata(
|
||||
issue_results: ComicIssue, source: str, remove_html_tables: bool = False, use_year_volume: bool = False
|
||||
) -> GenericMetadata:
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""
|
||||
ComicVine information source
|
||||
"""
|
||||
# Copyright 2012-2014 Anthony Beville
|
||||
# Copyright 2012-2014 ComicTagger Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -22,7 +22,7 @@ import logging
|
||||
import pathlib
|
||||
import time
|
||||
from typing import Any, Callable, Generic, TypeVar
|
||||
from urllib.parse import urljoin, urlsplit
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
import settngs
|
||||
@ -156,27 +156,19 @@ CV_STATUS_RATELIMIT = 107
|
||||
class ComicVineTalker(ComicTalker):
|
||||
name: str = "Comic Vine"
|
||||
id: str = "comicvine"
|
||||
logo_url: str = "https://comicvine.gamespot.com/a/bundles/comicvinesite/images/logo.png"
|
||||
website: str = "https://comicvine.gamespot.com/"
|
||||
website: str = "https://comicvine.gamespot.com"
|
||||
logo_url: str = f"{website}/a/bundles/comicvinesite/images/logo.png"
|
||||
attribution: str = f"Metadata provided by <a href='{website}'>{name}</a>"
|
||||
|
||||
def __init__(self, version: str, cache_folder: pathlib.Path):
|
||||
super().__init__(version, cache_folder)
|
||||
# Default settings
|
||||
self.api_url: str = "https://comicvine.gamespot.com/api"
|
||||
self.api_key: str = "27431e6787042105bd3e47e169a624521f89f3a4"
|
||||
self.default_api_url = self.api_url = f"{self.website}/api/"
|
||||
self.default_api_key = self.api_key = "27431e6787042105bd3e47e169a624521f89f3a4"
|
||||
self.remove_html_tables: bool = False
|
||||
self.use_series_start_as_volume: bool = False
|
||||
self.wait_on_ratelimit: bool = False
|
||||
|
||||
tmp_url = urlsplit(self.api_url)
|
||||
|
||||
# joinurl only works properly if there is a trailing slash
|
||||
if tmp_url.path and tmp_url.path[-1] != "/":
|
||||
tmp_url = tmp_url._replace(path=tmp_url.path + "/")
|
||||
|
||||
self.api_url = tmp_url.geturl()
|
||||
|
||||
# NOTE: This was hardcoded before which is why it isn't in settings
|
||||
self.wait_on_ratelimit_time: int = 20
|
||||
|
||||
@ -202,34 +194,39 @@ class ComicVineTalker(ComicTalker):
|
||||
display_name="Remove HTML tables",
|
||||
help="Removes html tables instead of converting them to text",
|
||||
)
|
||||
parser.add_setting("--cv-api-key", display_name="API Key", help="Use the given Comic Vine API Key")
|
||||
parser.add_setting("--cv-url", display_name="URL", help="Use the given Comic Vine URL")
|
||||
# The empty string being the default allows this setting to be unset, allowing the default to change
|
||||
parser.add_setting(
|
||||
f"--{self.id}-key",
|
||||
default="",
|
||||
display_name="API Key",
|
||||
help=f"Use the given Comic Vine API Key. (default: {self.default_api_key})",
|
||||
)
|
||||
parser.add_setting(
|
||||
f"--{self.id}-url",
|
||||
default="",
|
||||
display_name="API URL",
|
||||
help=f"Use the given Comic Vine URL. (default: {self.default_api_url})",
|
||||
)
|
||||
|
||||
def parse_settings(self, settings: dict[str, Any]) -> dict[str, Any]:
|
||||
if settings["cv_api_key"]:
|
||||
self.api_key = settings["cv_api_key"]
|
||||
if settings["cv_url"]:
|
||||
tmp_url = urlsplit(settings["cv_url"])
|
||||
# joinurl only works properly if there is a trailing slash
|
||||
if tmp_url.path and tmp_url.path[-1] != "/":
|
||||
tmp_url = tmp_url._replace(path=tmp_url.path + "/")
|
||||
|
||||
self.api_url = tmp_url.geturl()
|
||||
settings = super().parse_settings(settings)
|
||||
|
||||
self.use_series_start_as_volume = settings["cv_use_series_start_as_volume"]
|
||||
self.wait_on_ratelimit = settings["cv_wait_on_ratelimit"]
|
||||
self.remove_html_tables = settings["cv_remove_html_tables"]
|
||||
return settngs
|
||||
return settings
|
||||
|
||||
def check_api_key(self, key: str) -> bool:
|
||||
url = self.api_url
|
||||
def check_api_key(self, key: str, url: str) -> bool:
|
||||
url = talker_utils.fix_url(url)
|
||||
if not url:
|
||||
url = self.default_api_url
|
||||
try:
|
||||
test_url = urljoin(url, "issue/1/")
|
||||
|
||||
cv_response: CVResult = requests.get(
|
||||
test_url,
|
||||
headers={"user-agent": "comictagger/" + self.version},
|
||||
params={"api_key": key, "format": "json", "field_list": "name"},
|
||||
params={"api_key": key or self.default_api_key, "format": "json", "field_list": "name"},
|
||||
).json()
|
||||
|
||||
# Bogus request, but if the key is wrong, you get error 100: "Invalid API Key"
|
||||
@ -237,27 +234,6 @@ class ComicVineTalker(ComicTalker):
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def check_api_url(self, url: str) -> bool:
|
||||
if not url:
|
||||
url = self.api_url
|
||||
try:
|
||||
tmp_url = urlsplit(url)
|
||||
if tmp_url.path and tmp_url.path[-1] != "/":
|
||||
tmp_url = tmp_url._replace(path=tmp_url.path + "/")
|
||||
url = tmp_url.geturl()
|
||||
test_url = urljoin(url, "issue/1/")
|
||||
|
||||
cv_response: CVResult = requests.get(
|
||||
test_url,
|
||||
headers={"user-agent": "comictagger/" + self.version},
|
||||
params={"api_key": self.api_key, "format": "json", "field_list": "name"},
|
||||
).json()
|
||||
|
||||
# Bogus request, but if the url is correct, you get error 102: "Error in URL Format"
|
||||
return cv_response["status_code"] == 102
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def search_for_series(
|
||||
self,
|
||||
series_name: str,
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
"""Print out a line-by-line list of basic tag info from all comics"""
|
||||
|
||||
# Copyright 2012 Anthony Beville
|
||||
# Copyright 2012 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -4,7 +4,7 @@ Make some tree structures and symbolic links to comic files based on metadata
|
||||
organizing by date and series, in different trees
|
||||
"""
|
||||
|
||||
# Copyright 2012 Anthony Beville
|
||||
# Copyright 2012 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,9 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
"""Moves comic files based on metadata organizing in a tree by Publisher/Series (Volume)"""
|
||||
|
||||
# This script is based on make_links.py by Anthony Beville
|
||||
|
||||
# Copyright 2015 Fabio Cancedda, Anthony Beville
|
||||
# Copyright 2015 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
"""Fix the comic file names using a list of transforms"""
|
||||
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -5,7 +5,7 @@ and deleted. Walks recursively through the given folders. Originals
|
||||
are kept in a sub-folder at the level of the original
|
||||
"""
|
||||
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
"""Reduce the image size of pages in the comic archive"""
|
||||
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -2,7 +2,7 @@
|
||||
"""Test archive cover against Comic Vine for a given issue ID
|
||||
"""
|
||||
|
||||
# Copyright 2013 Anthony Beville
|
||||
# Copyright 2013 ComicTagger Authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
Loading…
Reference in New Issue
Block a user