Compare commits
5 commits
bcd06ffecc
...
329b076caf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
329b076caf | ||
|
|
e31ae00528 | ||
|
|
330554435d | ||
|
|
043f57842a | ||
|
|
6e151a8d28 |
3 changed files with 66 additions and 38 deletions
96
main.py
96
main.py
|
|
@ -1,3 +1,4 @@
|
|||
import alive_progress
|
||||
import requests
|
||||
import connectors
|
||||
import argparse
|
||||
|
|
@ -29,6 +30,8 @@ class BookCollection(dict):
|
|||
keys = expand_range(sequence)
|
||||
|
||||
for key in keys:
|
||||
if not args.non_series and not float(key).is_integer():
|
||||
continue
|
||||
self.setdefault(key, [])
|
||||
self[key].append(book.asin)
|
||||
|
||||
|
|
@ -55,39 +58,17 @@ def expand_range(part):
|
|||
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):
|
||||
processed_books = BookCollection(serie_name)
|
||||
|
||||
for json in books:
|
||||
if book["relationship_type"] == "series":
|
||||
if json["relationship_type"] == "series":
|
||||
book = Book(json["asin"])
|
||||
book.series.setdefault(serie_name, json["sequence"])
|
||||
book.series.setdefault(serie_name, f"-{json['sort']}")
|
||||
processed_books.add(book)
|
||||
else:
|
||||
logger.debug("Skipping non-series book: %s", json["asin"])
|
||||
|
||||
return processed_books
|
||||
|
||||
|
|
@ -150,9 +131,13 @@ def main():
|
|||
libraries = abs.get_library_ids()
|
||||
|
||||
for library in libraries:
|
||||
series = abs.get_series_by_library_id(library["id"])
|
||||
if library["mediaType"] != "book" or library["provider"] != "audible":
|
||||
continue
|
||||
|
||||
for serie in series:
|
||||
logger.info("==== %s ====", library["name"])
|
||||
|
||||
series = abs.get_series_by_library_id(library["id"])
|
||||
for serie in alive_progress.alive_it(series, title=library["name"]):
|
||||
series_name = serie["name"]
|
||||
abs_book_sequence = process_abs_serie(serie["books"], series_name)
|
||||
|
||||
|
|
@ -168,7 +153,9 @@ def main():
|
|||
continue
|
||||
|
||||
audible_serie = audible.get_produce_from_asin(series_asin)
|
||||
audible_book_sequence = process_sequence(audible_serie["relationships"])
|
||||
audible_book_sequence = process_audible_serie(
|
||||
audible_serie["relationships"], series_name
|
||||
)
|
||||
|
||||
if len(abs_book_sequence) >= len(audible_book_sequence):
|
||||
continue
|
||||
|
|
@ -186,13 +173,30 @@ def main():
|
|||
soon_to_release_books = []
|
||||
|
||||
for key in missing_keys:
|
||||
try:
|
||||
audnexus.get_book_from_asin(audible_book_sequence[key][0])
|
||||
missing_books.append(key)
|
||||
found = False
|
||||
for asin in audible_book_sequence[key]:
|
||||
try:
|
||||
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
|
||||
|
||||
except requests.exceptions.HTTPError:
|
||||
logger.debug("%s Book %d is yet to be released", series_name, key)
|
||||
if not found and args.oncoming:
|
||||
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 = []
|
||||
|
||||
|
|
@ -208,15 +212,29 @@ def main():
|
|||
msg,
|
||||
)
|
||||
|
||||
# TODO: add input to choose which library is to be scaned
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-d", "--dev", action="store_true")
|
||||
parser.add_argument("-v", "--verbose", action="store_true")
|
||||
# General flags
|
||||
parser.add_argument(
|
||||
"-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()
|
||||
|
||||
|
|
@ -239,6 +257,8 @@ if __name__ == "__main__":
|
|||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
|
||||
alive_progress.config_handler.set_global(enrich_print=False)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG if args.verbose else logging.INFO)
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -32,6 +32,14 @@ python main.py
|
|||
|
||||
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
|
||||
|
||||
- [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