Een thuisbibliotheek maken met Notion en Python

Ik ben altijd geïnteresseerd geweest in de beste manier om boeken in mijn elektronische bibliotheek te distribueren. Uiteindelijk kwam ik bij deze optie uit met automatische berekening van het aantal pagina's en andere goodies. Ik vraag alle geïnteresseerden onder cat.

Deel 1. Dropbox

Al mijn boeken staan ​​op dropbox. Er zijn 4 categorieën waarin ik alles heb verdeeld: leerboek, naslagwerk, fictie, non-fictie. Maar ik voeg geen naslagwerken toe aan de tabel.

De meeste boeken zijn .epub, de rest is .pdf. Dat wil zeggen dat de uiteindelijke oplossing op de een of andere manier beide opties moet omvatten.

Mijn paden naar boeken zijn ongeveer als volgt:

/Книги/Нехудожественное/Новое/Дизайн/Юрий Гордон/Книга про буквы от А до Я.epub 

Als het boek fictie is, wordt de categorie (dat wil zeggen 'Ontwerp' in het bovenstaande geval) verwijderd.

Ik besloot me niet bezig te houden met de Dropbox API, omdat ik hun applicatie heb die de map synchroniseert. Dat wil zeggen, het plan is dit: we halen boeken uit de map, doorlopen elk boek door een woordenteller en voegen het toe aan Notion.

Deel 2. Voeg een regel toe

De tabel zelf zou er ongeveer zo uit moeten zien. LET OP: het is beter om kolomnamen in het Latijn te maken.

Een thuisbibliotheek maken met Notion en Python

We zullen de onofficiële Notion API gebruiken, omdat de officiële nog niet is geleverd.

Een thuisbibliotheek maken met Notion en Python

Ga naar Notion, druk op Ctrl + Shift + J, ga naar Toepassing -> Cookies, kopieer token_v2 en noem het TOKEN. Vervolgens gaan we naar de pagina die we nodig hebben met het bibliotheekbord en kopiëren de link. Wij noemen het NOTIE.

Vervolgens schrijven we de code om verbinding te maken met Notion.

database = client.get_collection_view(NOTION)
current_rows = database.default_query().execute()

Laten we vervolgens een functie schrijven om een ​​rij aan de tabel toe te voegen.

def add_row(path, file, words_count, pages_count, hours):
    row = database.collection.add_row()
    row.title = file

    tags = path.split("/")

    if len(tags) >= 1:
        row.what = tags[0]

    if len(tags) >= 2:
        row.state = tags[1]

    if len(tags) >= 3:
        if tags[0] == "Художественное":
            row.author = tags[2]

        elif tags[0] == "Нехудожественное":
            row.tags = tags[2]

        elif tags[0] == "Учебники":
            row.tags = tags[2]

    if len(tags) >= 4:
        row.author = tags[3]

    row.hours = hours
    row.pages = pages_count
    row.words = words_count

Wat is hier aan de hand. We nemen en voegen een nieuwe rij toe aan de tabel in de eerste rij. Vervolgens splitsen we ons pad langs “/” en krijgen we tags. Tags - in termen van “Kunst”, “Ontwerp”, wie de auteur is, enzovoort. Vervolgens stellen we alle benodigde velden van de plaat in.

Deel 3. Woorden, uren en andere geneugten tellen

Dit is een moeilijkere taak. Zoals we ons herinneren, hebben we twee formaten: epub en pdf. Als bij de epub alles duidelijk is - de woorden staan ​​er waarschijnlijk in, dan is bij de pdf alles niet zo duidelijk: deze kan simpelweg uit gelijmde afbeeldingen bestaan.

Onze functie voor het tellen van woorden in PDF ziet er dus als volgt uit: we nemen het aantal pagina's en vermenigvuldigen dit met een bepaalde constante (het gemiddelde aantal woorden per pagina).

Hier is ze:

def get_words_count(pages_number):
    return pages_number * WORDS_PER_PAGE

Deze WORDS_PER_PAGE voor een A4-pagina is ongeveer 300.

Laten we nu een functie schrijven om pagina's te tellen. We zullen gebruiken pyPDF2.

def get_pdf_pages_number(path, filename):
    pdf = PdfFileReader(open(os.path.join(path, filename), 'rb'))
    return pdf.getNumPages()

Vervolgens zullen we iets schrijven voor het tellen van pagina's in Epub. We gebruiken epub_converter. Hier nemen we het boek, zetten het om in regels en tellen de woorden voor elke regel.

def get_epub_pages_number(path, filename):
    book = open_book(os.path.join(path, filename))
    lines = convert_epub_to_lines(book)
    words_count = 0

    for line in lines:
        words_count += len(line.split(" "))

    return round(words_count / WORDS_PER_PAGE)

Laten we nu de tijd berekenen. We nemen het aantal favoriete woorden en delen dit door uw leessnelheid.

def get_reading_time(words_count):
    return round(((words_count / WORDS_PER_MINUTE) / 60) * 10) / 10

Deel 4. Alle onderdelen verbinden

We moeten alle mogelijke paden in onze boekenmap doorlopen. Controleer of er al een boek in Notion staat: als dat zo is, hoeven we geen regel meer aan te maken.
Vervolgens moeten we het bestandstype bepalen, afhankelijk hiervan het aantal woorden tellen. Voeg aan het einde een boek toe.

Dit is de code die we krijgen:

for root, subdirs, files in os.walk(BOOKS_DIR):
    if len(files) > 0 and check_for_excusion(root):
        for file in files:
            array = file.split(".")
            filetype = file.split(".")[len(array) - 1]
            filename = file.replace("." + filetype, "")
            local_root = root.replace(BOOKS_DIR, "")

            print("Dir: {}, file: {}".format(local_root, file))

            if not check_for_existence(filename):
                print("Dir: {}, file: {}".format(local_root, file))

                if filetype == "pdf":
                    count = get_pdf_pages_number(root, file)

                else:
                    count = get_epub_pages_number(root, file)

                words_count = get_words_count(count)
                hours = get_reading_time(words_count)
                print("Pages: {}, Words: {}, Hours: {}".format(count, words_count, hours))
                add_row(local_root, filename, words_count, count, hours)

En de functie om te controleren of er een boek is toegevoegd ziet er als volgt uit:

def check_for_existence(filename):
    for row in current_rows:
        if row.title in filename:
            return True

        elif filename in row.title:
            return True

    return False

Conclusie

Dank aan iedereen die dit artikel heeft gelezen. Ik hoop dat het je helpt verder te lezen :)

Bron: www.habr.com

Voeg een reactie