1
0
Fork 0
mirror of https://github.com/kemayo/leech synced 2025-12-06 08:22:56 +01:00

Use the newer syntax for attrs

This commit is contained in:
David Lynch 2024-11-23 18:12:43 -06:00
parent d6d23e4c60
commit a39e1e9f89
3 changed files with 56 additions and 60 deletions

View file

@ -8,7 +8,7 @@ import html
import unicodedata import unicodedata
import datetime import datetime
import requests import requests
import attr from attrs import define, asdict
html_template = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?> html_template = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
@ -66,17 +66,16 @@ frontmatter_template = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
''' '''
@attr.s @define
class CoverOptions: class CoverOptions:
fontname = attr.ib(default=None, converter=attr.converters.optional(str)) fontname: str = None
fontsize = attr.ib(default=None, converter=attr.converters.optional(int)) fontsize: int = None
width = attr.ib(default=None, converter=attr.converters.optional(int)) width: int = None
height = attr.ib(default=None, converter=attr.converters.optional(int)) height: int = None
wrapat = attr.ib(default=None, converter=attr.converters.optional(int)) wrapat: int = None
bgcolor = attr.ib(default=None, converter=attr.converters.optional(tuple)) bgcolor: tuple = None
textcolor = attr.ib( textcolor: tuple = None
default=None, converter=attr.converters.optional(tuple)) cover_url: str = None
cover_url = attr.ib(default=None, converter=attr.converters.optional(str))
def chapter_html( def chapter_html(
@ -187,8 +186,7 @@ def generate_epub(story, cover_options={}, image_options=None, output_filename=
'height', 'wrapat', 'bgcolor', 'textcolor', 'cover_url') 'height', 'wrapat', 'bgcolor', 'textcolor', 'cover_url')
cover_options = CoverOptions( cover_options = CoverOptions(
**{k: v for k, v in cover_options.items() if k in valid_cover_options}) **{k: v for k, v in cover_options.items() if k in valid_cover_options})
cover_options = attr.asdict( cover_options = asdict(cover_options, filter=lambda k, v: v is not None)
cover_options, filter=lambda k, v: v is not None, retain_collection_types=True)
if cover_options and "cover_url" in cover_options: if cover_options and "cover_url" in cover_options:
image = make_cover_from_url( image = make_cover_from_url(

View file

@ -4,11 +4,12 @@ import glob
import os import os
import random import random
import uuid import uuid
import datetime
import time import time
import logging import logging
import urllib import urllib
import re import re
import attr from attrs import define, field, Factory
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -21,32 +22,32 @@ def _default_uuid_string(self):
return str(uuid.UUID(int=rd.getrandbits(8*16), version=4)) return str(uuid.UUID(int=rd.getrandbits(8*16), version=4))
@attr.s @define
class Image: class Image:
path = attr.ib() path: str
contents = attr.ib() contents: str
content_type = attr.ib() content_type: str
@attr.s @define
class Chapter: class Chapter:
title = attr.ib() title: str
contents = attr.ib() contents: str
date = attr.ib(default=False) date: datetime.datetime = False
images = attr.ib(default=attr.Factory(list)) images: list = Factory(list)
@attr.s @define
class Section: class Section:
title = attr.ib() title: str
author = attr.ib() author: str
url = attr.ib() url: str
cover_url = attr.ib(default='') cover_url: str = ''
id = attr.ib(default=attr.Factory(_default_uuid_string, takes_self=True), converter=str) id: str = Factory(_default_uuid_string, takes_self=True)
contents = attr.ib(default=attr.Factory(list)) contents: list = Factory(list)
footnotes = attr.ib(default=attr.Factory(list)) footnotes: list = Factory(list)
tags = attr.ib(default=attr.Factory(list)) tags: list = Factory(list)
summary = attr.ib(default='') summary: str = ''
def __iter__(self): def __iter__(self):
return self.contents.__iter__() return self.contents.__iter__()
@ -74,17 +75,17 @@ class Section:
yield chapter.date yield chapter.date
@attr.s @define
class Site: class Site:
"""A Site handles checking whether a URL might represent a site, and then """A Site handles checking whether a URL might represent a site, and then
extracting the content of a story from said site. extracting the content of a story from said site.
""" """
session = attr.ib() session: object = field()
footnotes = attr.ib(factory=list, init=False) footnotes: list = field(factory=list, init=False)
options = attr.ib(default=attr.Factory( options: dict = Factory(
lambda site: site.get_default_options(), lambda site: site.get_default_options(),
True takes_self=True
)) )
@classmethod @classmethod
def site_key(cls): def site_key(cls):
@ -288,17 +289,17 @@ class Site:
return contents return contents
@attr.s(hash=True) @define(unsafe_hash=True, frozen=True)
class SiteSpecificOption: class SiteSpecificOption:
"""Represents a site-specific option that can be configured. """Represents a site-specific option that can be configured.
Will be added to the CLI as a click.option -- many of these Will be added to the CLI as a click.option -- many of these
fields correspond to click.option arguments.""" fields correspond to click.option arguments."""
name = attr.ib() name: str
flag_pattern = attr.ib() flag_pattern: str
type = attr.ib(default=None) type: object = None
help = attr.ib(default=None) default: bool = False
default = attr.ib(default=None) help: str = None
def as_click_option(self): def as_click_option(self):
return click.option( return click.option(

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
import logging import logging
import attr from attrs import define
import datetime import datetime
import json import json
import re import re
@ -24,26 +24,23 @@ Example JSON:
""" """
@attr.s @define
class SiteDefinition: class SiteDefinition:
url = attr.ib() url: str
title = attr.ib() title: str
author = attr.ib() author: str
content_selector = attr.ib() content_selector: str
# If present, find something within `content` to use a chapter title; if not found, the link text to it will be used # If present, find something within `content` to use a chapter title; if not found, the link text to it will be used
content_title_selector = attr.ib(default=False) content_title_selector: str = False
# If present, find a specific element in the `content` to be the chapter text # If present, find a specific element in the `content` to be the chapter text
content_text_selector = attr.ib(default=False) content_text_selector: str = False
# If present, it looks for chapters linked from `url`. If not, it assumes `url` points to a chapter. # If present, it looks for chapters linked from `url`. If not, it assumes `url` points to a chapter.
chapter_selector = attr.ib(default=False) chapter_selector: str = False
# If present, use to find a link to the next content page (only used if not using chapter_selector) # If present, use to find a link to the next content page (only used if not using chapter_selector)
next_selector = attr.ib(default=False) next_selector: str = False
# If present, use to filter out content that matches the selector # If present, use to filter out content that matches the selector
filter_selector = attr.ib(default=False) filter_selector: str = False
cover_url = attr.ib(default='') cover_url: str = ''
# If present, use to also download the images and embed them into the epub.
image_selector = attr.ib(default=False)
@register @register