เชจเซ‹เชถเชจ เช…เชจเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชธเชพเชฅเซ‡ เชนเซ‹เชฎ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชฌเชจเชพเชตเชตเซ€

เชฎเชพเชฐเซ€ เชˆเชฒเซ‡เช•เซเชŸเซเชฐเซ‹เชจเชฟเช• เชฒเชพเชˆเชฌเซเชฐเซ‡เชฐเซ€เชฎเชพเช‚ เชชเซเชธเซเชคเช•เซ‹เชจเซเช‚ เชถเซเชฐเซ‡เชทเซเช  เชตเชฟเชคเชฐเชฃ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซเช‚ เชคเซ‡ เช…เช‚เช—เซ‡ เชฎเชจเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชฐเชธ เชฐเชนเซเชฏเซ‹ เช›เซ‡. เช…เช‚เชคเซ‡, เชนเซเช‚ เชชเซƒเชทเซเช เซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เช…เชจเซ‡ เช…เชจเซเชฏ เช—เซเชกเซ€เชเชจเซ€ เชธเซเชตเชšเชพเชฒเชฟเชค เช—เชฃเชคเชฐเซ€ เชธเชพเชฅเซ‡ เช† เชตเชฟเช•เชฒเซเชช เชชเชฐ เช†เชตเซเชฏเซ‹ เช›เซเช‚. เชนเซเช‚ เชฌเชฟเชฒเชพเชกเซ€ เชนเซ‡เช เชณ เชฐเชธ เชงเชฐเชพเชตเชคเชพ เชคเชฎเชพเชฎ เชฒเซ‹เช•เซ‹เชจเซ‡ เชชเซ‚เช›เซเช‚ เช›เซเช‚.

เชญเชพเช— 1. เชกเซเชฐเซ‰เชชเชฌเซ‰เช•เซเชธ

เชฎเชพเชฐเชพ เชฌเชงเชพ เชชเซเชธเซเชคเช•เซ‹ เชกเซเชฐเซ‹เชชเชฌเซ‹เช•เซเชธ เชชเชฐ เช›เซ‡. เชคเซเชฏเชพเช‚ 4 เชถเซเชฐเซ‡เชฃเซ€เช“ เช›เซ‡ เชœเซ‡เชฎเชพเช‚ เชฎเซ‡เช‚ เชฌเชงเซเช‚ เชตเชฟเชญเชพเชœเชฟเชค เช•เชฐเซเชฏเซเช‚ เช›เซ‡: เชชเชพเช เซเชฏเชชเซเชธเซเชคเช•, เชธเช‚เชฆเชฐเซเชญ, เชธเชพเชนเชฟเชคเซเชฏ, เชจเซ‹เชจ-เชซเชฟเช•เซเชถเชจ. เชชเชฐเช‚เชคเซ เชนเซเช‚ เชŸเซ‡เชฌเชฒ เชชเชฐ เชธเช‚เชฆเชฐเซเชญ เชชเซเชธเซเชคเช•เซ‹ เช‰เชฎเซ‡เชฐเชคเซ‹ เชจเชฅเซ€.

เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เชชเซเชธเซเชคเช•เซ‹ .epub เช›เซ‡, เชฌเชพเช•เซ€เชจเชพ .pdf เช›เซ‡. เชเชŸเชฒเซ‡ เช•เซ‡, เช…เช‚เชคเชฟเชฎ เช‰เช•เซ‡เชฒเชฎเชพเช‚ เช•เซ‹เชˆเช• เชฐเซ€เชคเซ‡ เชฌเช‚เชจเซ‡ เชตเชฟเช•เชฒเซเชชเซ‹ เช†เชตเชฐเซ€ เชฒเซ‡เชตเชพ เชœเซ‹เชˆเช.

เชชเซเชธเซเชคเช•เซ‹ เชคเชฐเชซเชจเชพ เชฎเชพเชฐเชพ เชฎเชพเชฐเซเช—เซ‹ เช•เช‚เชˆเช• เช†เชจเชพ เชœเซ‡เชตเชพ เช›เซ‡:

/ะšะฝะธะณะธ/ะะตั…ัƒะดะพะถะตัั‚ะฒะตะฝะฝะพะต/ะะพะฒะพะต/ะ”ะธะทะฐะนะฝ/ะฎั€ะธะน ะ“ะพั€ะดะพะฝ/ะšะฝะธะณะฐ ะฟั€ะพ ะฑัƒะบะฒั‹ ะพั‚ ะ ะดะพ ะฏ.epub 

เชœเซ‹ เชชเซเชธเซเชคเช• เช•เชพเชฒเซเชชเชจเชฟเช• เช›เซ‡, เชคเซ‹ เชถเซเชฐเซ‡เชฃเซ€ (เชเชŸเชฒเซ‡ โ€‹โ€‹โ€‹โ€‹เช•เซ‡, เช‰เชชเชฐเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ "เชกเชฟเชเชพเช‡เชจ") เชฆเซ‚เชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เชฎเซ‡เช‚ เชกเซเชฐเซ‰เชชเชฌเซ‰เช•เซเชธ API เชธเชพเชฅเซ‡ เชšเชฟเช‚เชคเชพ เชจ เช•เชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚, เช•เชพเชฐเชฃ เช•เซ‡ เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชคเซ‡เชฎเชจเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช›เซ‡ เชœเซ‡ เชซเซ‹เชฒเซเชกเชฐเชจเซ‡ เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เช เช•เชฐเซ‡ เช›เซ‡. เชเชŸเชฒเซ‡ เช•เซ‡, เชฏเซ‹เชœเชจเชพ เช† เช›เซ‡: เช…เชฎเซ‡ เชซเซ‹เชฒเซเชกเชฐเชฎเชพเช‚เชฅเซ€ เชชเซเชธเซเชคเช•เซ‹ เชฒเชˆเช เช›เซ€เช, เชฆเชฐเซ‡เช• เชชเซเชธเซเชคเช•เชจเซ‡ เชตเชฐเซเชก เช•เชพเช‰เชจเซเชŸเชฐ เชฆเซเชตเชพเชฐเชพ เชšเชฒเชพเชตเซ€เช เช›เซ€เช เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชจเซ‹เชถเชจเชฎเชพเช‚ เช‰เชฎเซ‡เชฐเซ€เช เช›เซ€เช.

เชญเชพเช— 2. เชเช• เชฒเซ€เชŸเซ€ เช‰เชฎเซ‡เชฐเซ‹

เชŸเซ‡เชฌเชฒ เชชเซ‹เชคเซ‡ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เช•เช‚เชˆเช• เชฆเซ‡เช–เชพเชตเซเช‚ เชœเซ‹เชˆเช. เชงเซเชฏเชพเชจ เช†เชชเซ‹: เชฒเซ‡เชŸเชฟเชจเชฎเชพเช‚ เช•เซ‰เชฒเชฎ เชจเชพเชฎเซ‹ เชฌเชจเชพเชตเชตเชพเชจเซเช‚ เชตเชงเซ เชธเชพเชฐเซเช‚ เช›เซ‡.

เชจเซ‹เชถเชจ เช…เชจเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชธเชพเชฅเซ‡ เชนเซ‹เชฎ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชฌเชจเชพเชตเชตเซ€

เช…เชฎเซ‡ เชฌเชฟเชจเชธเชคเซเชคเชพเชตเชพเชฐ เชจเซ‹เชŸเซ‡เชถเชจ API เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚, เช•เชพเชฐเชฃ เช•เซ‡ เชธเชคเซเชคเชพเชตเชพเชฐ เชนเชœเซ€ เชธเซเชงเซ€ เชตเชฟเชคเชฐเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชจเชฅเซ€.

เชจเซ‹เชถเชจ เช…เชจเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชธเชพเชฅเซ‡ เชนเซ‹เชฎ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชฌเชจเชพเชตเชตเซ€

Notion เชชเชฐ เชœเชพเช“, Ctrl + Shift + J เชฆเชฌเชพเชตเซ‹, Application -> Cookies เชชเชฐ เชœเชพเช“, token_v2 เช•เซ‹เชชเซ€ เช•เชฐเซ‹ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ TOKEN เช•เชนเซ‹. เชชเช›เซ€ เช†เชชเชฃเซ‡ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชธเชพเช‡เชจ เชธเชพเชฅเซ‡ เชœเชฐเซ‚เชฐเซ€ เชชเซƒเชทเซเช  เชชเชฐ เชœเชˆเช เช…เชจเซ‡ เชฒเชฟเช‚เช•เชจเซ€ เชจเช•เชฒ เช•เชฐเซ€เช. เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ NOTION เช•เชนเซ€เช เช›เซ€เช.

เชชเช›เซ€ เช†เชชเชฃเซ‡ Notion เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชตเชพ เชฎเชพเชŸเซ‡ เช•เซ‹เชก เชฒเช–เซ€เช เช›เซ€เช.

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

เช†เช—เชณ, เชŸเซ‡เชฌเชฒ เชชเชฐ เชชเช‚เช•เซเชคเชฟ เช‰เชฎเซ‡เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชซเช‚เช•เซเชถเชจ เชฒเช–เซ€เช.

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

เช…เชนเชฟเชฏเชพเช‚ เชถเซเช‚ เชฅเช‡ เชฐเชนเซเชฏเซเช‚ เช›เซ‡. เช…เชฎเซ‡ เชชเซเชฐเชฅเชฎ เชชเช‚เช•เซเชคเชฟเชฎเชพเช‚ เช•เซ‹เชทเซเชŸเช•เชฎเชพเช‚ เชเช• เชจเชตเซ€ เชชเช‚เช•เซเชคเชฟ เชฒเชˆเช เช›เซ€เช เช…เชจเซ‡ เช‰เชฎเซ‡เชฐเซ€เช เช›เซ€เช. เช†เช—เชณ, เช…เชฎเซ‡ เช…เชฎเชพเชฐเชพ เชชเชพเชฅเชจเซ‡ "/" เชธเชพเชฅเซ‡ เชตเชฟเชญเชพเชœเชฟเชค เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชŸเซ…เช—เซเชธ เชฎเซ‡เชณเชตเซ€เช เช›เซ€เช. เชŸเซ…เช—เซเชธ - "เช•เชฒเชพ", "เชกเชฟเชเชพเช‡เชจ", เชฒเซ‡เช–เช• เช•เซ‹เชฃ เช›เซ‡, เชตเช—เซ‡เชฐเซ‡เชจเชพ เชธเช‚เชฆเชฐเซเชญเชฎเชพเช‚. เชชเช›เซ€ เช…เชฎเซ‡ เชชเซเชฒเซ‡เชŸเชจเชพ เชคเชฎเชพเชฎ เชœเชฐเซ‚เชฐเซ€ เช•เซเชทเซ‡เชคเซเชฐเซ‹ เชธเซ‡เชŸ เช•เชฐเซ€เช เช›เซ€เช.

เชญเชพเช— 3. เชถเชฌเซเชฆเซ‹, เช•เชฒเชพเช•เซ‹ เช…เชจเซ‡ เช…เชจเซเชฏ เช†เชจเช‚เชฆเชจเซ€ เช—เชฃเชคเชฐเซ€

เช† เชตเชงเซ เชฎเซเชถเซเช•เซ‡เชฒ เช•เชพเชฐเซเชฏ เช›เซ‡. เชœเซ‡เชฎ เช†เชชเชฃเซ‡ เชฏเชพเชฆ เชฐเชพเช–เซ€เช เช›เซ€เช, เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชฌเซ‡ เชซเซ‹เชฐเซเชฎเซ‡เชŸ เช›เซ‡: epub เช…เชจเซ‡ pdf. เชœเซ‹ เช‡เชชเชฌ เชธเชพเชฅเซ‡ เชฌเชงเซเช‚ เชธเซเชชเชทเซเชŸ เช›เซ‡ - เชถเชฌเซเชฆเซ‹ เช•เชฆเชพเชš เชคเซเชฏเชพเช‚ เช›เซ‡, เชคเซ‹ เชชเช›เซ€ เชชเซ€เชกเซ€เชเชซ เชตเชฟเชถเซ‡ เชฌเชงเซเช‚ เชเชŸเชฒเซเช‚ เชธเซเชชเชทเซเชŸ เชจเชฅเซ€: เชคเซ‡เชฎเชพเช‚ เชซเช•เซเชค เช—เซเช‚เชฆเชฐเชตเชพเชณเซ€ เช›เชฌเซ€เช“ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡.

เชคเซ‡เชฅเซ€ เชชเซ€เชกเซ€เชเชซเชฎเชพเช‚ เชถเชฌเซเชฆเซ‹เชจเซ€ เช—เชฃเชคเชฐเซ€ เชฎเชพเชŸเซ‡เชจเซเช‚ เช…เชฎเชพเชฐเซเช‚ เช•เชพเชฐเซเชฏ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เชฆเซ‡เช–เชพเชถเซ‡: เช…เชฎเซ‡ เชชเซƒเชทเซเช เซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เชฒเชˆเช เช›เซ€เช เช…เชจเซ‡ เชšเซ‹เช•เซเช•เชธ เชธเซเชฅเชฟเชฐเชพเช‚เช• (เชชเซƒเชทเซเช  เชฆเซ€เช  เชถเชฌเซเชฆเซ‹เชจเซ€ เชธเชฐเซ‡เชฐเชพเชถ เชธเช‚เช–เซเชฏเชพ) เชฆเซเชตเชพเชฐเชพ เช—เซเชฃเชพเช•เชพเชฐ เช•เชฐเซ€เช เช›เซ€เช.

เชคเซ‡เชฃเซ€ เช…เชนเซ€เช‚ เช›เซ‡:

def get_words_count(pages_number):
    return pages_number * WORDS_PER_PAGE

A4 เชชเซƒเชทเซเช  เชฎเชพเชŸเซ‡ เช† WORDS_PER_PAGE เช†เชถเชฐเซ‡ 300 เช›เซ‡.

เชนเชตเซ‡ เชชเชพเชจเชพ เช—เชฃเชตเชพ เชฎเชพเชŸเซ‡ เชซเช‚เช•เซเชถเชจ เชฒเช–เซ€เช. เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚ pyPDF2.

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

เช†เช—เชณ, เช…เชฎเซ‡ Epub เชฎเชพเช‚ เชชเซƒเชทเซเช เซ‹เชจเซ€ เช—เชฃเชคเชฐเซ€ เชฎเชพเชŸเซ‡ เชเช• เชตเชธเซเชคเซ เชฒเช–เซ€เชถเซเช‚. เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช epub_converter. เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชชเซเชธเซเชคเช• เชฒเชˆเช เช›เซ€เช, เชคเซ‡เชจเซ‡ เชฒเซ€เชŸเซ€เช“เชฎเชพเช‚ เช•เชจเซเชตเชฐเซเชŸ เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชฆเชฐเซ‡เช• เชฒเซ€เชŸเซ€ เชฎเชพเชŸเซ‡ เชถเชฌเซเชฆเซ‹ เช—เชฃเซ€เช เช›เซ€เช.

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)

เชนเชตเซ‡ เชธเชฎเชฏเชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเซ€เช. เช…เชฎเซ‡ เช…เชฎเชพเชฐเชพ เชฎเชจเชชเชธเช‚เชฆ เชถเชฌเซเชฆเซ‹เชจเซ€ เช—เชฃเชคเชฐเซ€ เชฒเชˆเช เช›เซ€เช เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชคเชฎเชพเชฐเซ€ เชตเชพเช‚เชšเชจเชจเซ€ เชเชกเชช เชฆเซเชตเชพเชฐเชพ เชตเชฟเชญเชพเชœเซ€เชค เช•เชฐเซ€เช เช›เซ€เช.

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

เชญเชพเช— 4. เชฌเชงเชพ เชญเชพเช—เซ‹เชจเซ‡ เชœเซ‹เชกเชตเซเช‚

เช…เชฎเชพเชฐเซ‡ เช…เชฎเชพเชฐเชพ เชชเซเชธเซเชคเช•เซ‹เชจเชพ เชซเซ‹เชฒเซเชกเชฐเชฎเชพเช‚ เชคเชฎเชพเชฎ เชธเช‚เชญเชตเชฟเชค เชฐเชธเซเชคเชพเช“เชฎเชพเช‚เชฅเซ€ เชชเชธเชพเชฐ เชฅเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชจเซ‹เช‚เชงเชฎเชพเช‚ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เช•เซ‹เชˆ เชชเซเชธเซเชคเช• เช›เซ‡ เช•เซ‡ เช•เซ‡เชฎ เชคเซ‡ เชคเชชเชพเชธเซ‹: เชœเซ‹ เชคเซเชฏเชพเช‚ เช›เซ‡, เชคเซ‹ เช†เชชเชฃเซ‡ เชนเชตเซ‡ เชฒเชพเช‡เชจ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€.
เชชเช›เซ€ เช†เชชเชฃเซ‡ เชซเชพเช‡เชฒ เชชเซเชฐเช•เชพเชฐ เชจเช•เซเช•เซ€ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡, เชคเซ‡เชจเชพ เช†เชงเชพเชฐเซ‡, เชถเชฌเซเชฆเซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพ เช—เชฃเซ‹. เช…เช‚เชคเซ‡ เชเช• เชชเซเชธเซเชคเช• เช‰เชฎเซ‡เชฐเซ‹.

เช† เช•เซ‹เชก เช…เชฎเชจเซ‡ เชฎเชณเซ‡ เช›เซ‡:

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)

เช…เชจเซ‡ เชชเซเชธเซเชคเช• เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡ เช•เซ‡ เช•เซ‡เชฎ เชคเซ‡ เชคเชชเชพเชธเชตเชพเชจเซเช‚ เช•เชพเชฐเซเชฏ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

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

เชจเชฟเชทเซเช•เชฐเซเชท

เช† เชฒเซ‡เช– เชตเชพเช‚เชšเชจเชพเชฐ เชฆเชฐเซ‡เช•เชจเซ‹ เช†เชญเชพเชฐ. เชฎเชจเซ‡ เช†เชถเชพ เช›เซ‡ เช•เซ‡ เชคเซ‡ เชคเชฎเชจเซ‡ เชตเชงเซ เชตเชพเช‚เชšเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเชถเซ‡ :)

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹