Compare commits
No commits in common. "329b076caf3c979a6ce3a94f0c1508a89aee18d4" and "bcd06ffecc727ed9c71a713db87d83743092754d" have entirely different histories.
329b076caf
...
bcd06ffecc
3 changed files with 38 additions and 66 deletions
96
main.py
96
main.py
|
|
@ -1,4 +1,3 @@
|
||||||
import alive_progress
|
|
||||||
import requests
|
import requests
|
||||||
import connectors
|
import connectors
|
||||||
import argparse
|
import argparse
|
||||||
|
|
@ -30,8 +29,6 @@ class BookCollection(dict):
|
||||||
keys = expand_range(sequence)
|
keys = expand_range(sequence)
|
||||||
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if not args.non_series and not float(key).is_integer():
|
|
||||||
continue
|
|
||||||
self.setdefault(key, [])
|
self.setdefault(key, [])
|
||||||
self[key].append(book.asin)
|
self[key].append(book.asin)
|
||||||
|
|
||||||
|
|
@ -58,17 +55,39 @@ def expand_range(part):
|
||||||
return [] # Handle non-numeric input or invalid format
|
return [] # Handle non-numeric input or invalid format
|
||||||
|
|
||||||
|
|
||||||
|
def process_sequence(books):
|
||||||
|
"""Groups books by ASIN, handling sequence ranges (including floats)."""
|
||||||
|
books_sequence = {}
|
||||||
|
for book in books:
|
||||||
|
asin = book["asin"]
|
||||||
|
sequence = book.get("sequence", "")
|
||||||
|
|
||||||
|
if sequence:
|
||||||
|
keys = expand_range(sequence.split(", ")[0])
|
||||||
|
else:
|
||||||
|
keys = [float(book.get("sort", "1")) * -1]
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
if key not in books_sequence:
|
||||||
|
books_sequence[key] = []
|
||||||
|
books_sequence[key].append(asin)
|
||||||
|
|
||||||
|
keys = sorted(books_sequence.keys(), key=lambda x: float(x))
|
||||||
|
ordered_sequence = {}
|
||||||
|
for key in keys:
|
||||||
|
ordered_sequence[key] = books_sequence[key]
|
||||||
|
return ordered_sequence
|
||||||
|
|
||||||
|
|
||||||
def process_audible_serie(books, serie_name):
|
def process_audible_serie(books, serie_name):
|
||||||
processed_books = BookCollection(serie_name)
|
processed_books = BookCollection(serie_name)
|
||||||
|
|
||||||
for json in books:
|
for json in books:
|
||||||
if json["relationship_type"] == "series":
|
if book["relationship_type"] == "series":
|
||||||
book = Book(json["asin"])
|
book = Book(json["asin"])
|
||||||
book.series.setdefault(serie_name, json["sequence"])
|
book.series.setdefault(serie_name, json["sequence"])
|
||||||
book.series.setdefault(serie_name, f"-{json['sort']}")
|
book.series.setdefault(serie_name, f"-{json['sort']}")
|
||||||
processed_books.add(book)
|
processed_books.add(book)
|
||||||
else:
|
|
||||||
logger.debug("Skipping non-series book: %s", json["asin"])
|
|
||||||
|
|
||||||
return processed_books
|
return processed_books
|
||||||
|
|
||||||
|
|
@ -131,13 +150,9 @@ def main():
|
||||||
libraries = abs.get_library_ids()
|
libraries = abs.get_library_ids()
|
||||||
|
|
||||||
for library in libraries:
|
for library in libraries:
|
||||||
if library["mediaType"] != "book" or library["provider"] != "audible":
|
|
||||||
continue
|
|
||||||
|
|
||||||
logger.info("==== %s ====", library["name"])
|
|
||||||
|
|
||||||
series = abs.get_series_by_library_id(library["id"])
|
series = abs.get_series_by_library_id(library["id"])
|
||||||
for serie in alive_progress.alive_it(series, title=library["name"]):
|
|
||||||
|
for serie in series:
|
||||||
series_name = serie["name"]
|
series_name = serie["name"]
|
||||||
abs_book_sequence = process_abs_serie(serie["books"], series_name)
|
abs_book_sequence = process_abs_serie(serie["books"], series_name)
|
||||||
|
|
||||||
|
|
@ -153,9 +168,7 @@ def main():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
audible_serie = audible.get_produce_from_asin(series_asin)
|
audible_serie = audible.get_produce_from_asin(series_asin)
|
||||||
audible_book_sequence = process_audible_serie(
|
audible_book_sequence = process_sequence(audible_serie["relationships"])
|
||||||
audible_serie["relationships"], series_name
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(abs_book_sequence) >= len(audible_book_sequence):
|
if len(abs_book_sequence) >= len(audible_book_sequence):
|
||||||
continue
|
continue
|
||||||
|
|
@ -173,30 +186,13 @@ def main():
|
||||||
soon_to_release_books = []
|
soon_to_release_books = []
|
||||||
|
|
||||||
for key in missing_keys:
|
for key in missing_keys:
|
||||||
found = False
|
try:
|
||||||
for asin in audible_book_sequence[key]:
|
audnexus.get_book_from_asin(audible_book_sequence[key][0])
|
||||||
try:
|
missing_books.append(key)
|
||||||
audnexus.get_book_from_asin(asin)
|
|
||||||
missing_books.append(key)
|
|
||||||
logger.debug(
|
|
||||||
"%s Book %.1f is missing - %s",
|
|
||||||
series_name,
|
|
||||||
key,
|
|
||||||
audible_book_sequence[key][0],
|
|
||||||
)
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
except requests.exceptions.HTTPError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not found and args.oncoming:
|
except requests.exceptions.HTTPError:
|
||||||
|
logger.debug("%s Book %d is yet to be released", series_name, key)
|
||||||
soon_to_release_books.append(key)
|
soon_to_release_books.append(key)
|
||||||
logger.debug(
|
|
||||||
"%s Book %d is yet to be released - %s",
|
|
||||||
series_name,
|
|
||||||
key,
|
|
||||||
audible_book_sequence[key][0],
|
|
||||||
)
|
|
||||||
|
|
||||||
msgs = []
|
msgs = []
|
||||||
|
|
||||||
|
|
@ -212,29 +208,15 @@ def main():
|
||||||
msg,
|
msg,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: add input to choose which library is to be scaned
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
# General flags
|
parser.add_argument("-d", "--dev", action="store_true")
|
||||||
parser.add_argument(
|
parser.add_argument("-v", "--verbose", action="store_true")
|
||||||
"-v", "--verbose", action="store_true", help="Enable verbose logging"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-d", "--dev", action="store_true", help="Use development/mock connectors"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Feature-specific flags
|
|
||||||
parser.add_argument(
|
|
||||||
"--non-series",
|
|
||||||
action="store_true",
|
|
||||||
help="Include non-series books (books not part of a numbered series)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--oncoming",
|
|
||||||
action="store_true",
|
|
||||||
help="Show books to be released",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
@ -257,8 +239,6 @@ if __name__ == "__main__":
|
||||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||||
|
|
||||||
alive_progress.config_handler.set_global(enrich_print=False)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.setLevel(logging.DEBUG if args.verbose else logging.INFO)
|
logger.setLevel(logging.DEBUG if args.verbose else logging.INFO)
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -32,14 +32,6 @@ python main.py
|
||||||
|
|
||||||
Logs are written to the `log` file.
|
Logs are written to the `log` file.
|
||||||
|
|
||||||
### Feature-specific Arguments
|
|
||||||
|
|
||||||
- `--non-series`
|
|
||||||
Include non-series books (books not part of a numbered series).
|
|
||||||
|
|
||||||
- `--oncoming`
|
|
||||||
Show books that are yet to be released.
|
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
- [main.py](main.py): Entry point and main logic
|
- [main.py](main.py): Entry point and main logic
|
||||||
|
|
|
||||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue