From cf62814378a7428baffe662aaa1429f9cfcd82d3 Mon Sep 17 00:00:00 2001 From: itec78 Date: Thu, 19 Aug 2021 10:58:31 +0200 Subject: [PATCH] cover fix --- .gitignore | 2 +- copertina.pdf | Bin 0 -> 17266 bytes copertina.svg | 344 ------------------------------------------------ oloturia2pdf.py | 314 +++++++++++++++++++++---------------------- 4 files changed, 158 insertions(+), 502 deletions(-) create mode 100644 copertina.pdf delete mode 100644 copertina.svg diff --git a/.gitignore b/.gitignore index d136780..18f6652 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ media/ pdf/ *.json -*.pdf + diff --git a/copertina.pdf b/copertina.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c699015964da6c0d6ff360054985eb1e53b89989 GIT binary patch literal 17266 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 x996Nia|UqUjpZMw?qqEr+X21@l - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 001 - 050 - - diff --git a/oloturia2pdf.py b/oloturia2pdf.py index c5d8238..3b946cc 100755 --- a/oloturia2pdf.py +++ b/oloturia2pdf.py @@ -21,28 +21,26 @@ def copertina(text): from PyPDF2 import PdfFileWriter, PdfFileReader import io from reportlab.pdfgen import canvas - from reportlab.lib.pagesizes import A4 + from reportlab.lib.pagesizes import A5 from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase.pdfmetrics import stringWidth - from reportlab.rl_config import defaultPageSize FONT = 'Roboto' - SIZE = 48 + SIZE = 36 packet = io.BytesIO() # create a new PDF with Reportlab pdfmetrics.registerFont(TTFont("Roboto", "template/roboto-regular-webfont.ttf")) - can = canvas.Canvas(packet, pagesize=A4) + can = canvas.Canvas(packet, pagesize=A5) can.setFont(FONT, SIZE) - PAGE_WIDTH = defaultPageSize[0] - #PAGE_HEIGHT = defaultPageSize[1] + PAGE_WIDTH = A5[0] text_width = stringWidth(text,FONT, SIZE) - can.drawString((PAGE_WIDTH - text_width) / 2, 150, text) + can.drawString((PAGE_WIDTH - text_width) / 2, 100, text) can.save() #move to the beginning of the StringIO buffer @@ -60,178 +58,180 @@ def copertina(text): return(page) +def main(): + # Scarica tutti i post da Mastodon -# Scarica tutti i post da Mastodon + print("Scarico i post") -print("Scarico i post") + def default(o): + if isinstance(o, (datetime.date, datetime.datetime)): + return o.isoformat() -def default(o): - if isinstance(o, (datetime.date, datetime.datetime)): - return o.isoformat() + if not os.path.isfile('oloturiadump.json'): + mastodon = Mastodon(api_base_url = "https://mastodon.bida.im") + all_vgos = [] + last_id = None -if not os.path.isfile('oloturiadump.json'): - mastodon = Mastodon(api_base_url = "https://mastodon.bida.im") - all_vgos = [] - last_id = None + while True: + statuses = list(filter(lambda s: s['account']['username'] == 'oloturia', mastodon.timeline_hashtag("vgo", local=True, max_id=last_id))) + if not statuses: + break + all_vgos += list(map( + lambda s: { + 'id': s['id'], + 'uri': s['uri'], + 'content': s['content'], + 'replies_count': s['replies_count'], + #'replies': mastodon.status_context(s['id']) if s['replies_count'] > 0 else [], + 'created': s['created_at'], + 'reblogs': s['reblogs_count'], + 'favourites': s['favourites_count'], + 'media': s['media_attachments'] + } + , statuses)) + last_id = statuses[-1]['id'] - while True: - statuses = list(filter(lambda s: s['account']['username'] == 'oloturia', mastodon.timeline_hashtag("vgo", local=True, max_id=last_id))) - if not statuses: - break - all_vgos += list(map( - lambda s: { - 'id': s['id'], - 'uri': s['uri'], - 'content': s['content'], - 'replies_count': s['replies_count'], - #'replies': mastodon.status_context(s['id']) if s['replies_count'] > 0 else [], - 'created': s['created_at'], - 'reblogs': s['reblogs_count'], - 'favourites': s['favourites_count'], - 'media': s['media_attachments'] - } - , statuses)) - last_id = statuses[-1]['id'] + #print(all_vgos) + #print(json.dumps(all_vgos, default=default)) - #print(all_vgos) - #print(json.dumps(all_vgos, default=default)) - - with open('oloturiadump.json', 'w') as json_file: - json.dump(all_vgos, json_file, indent=4, default=default) + with open('oloturiadump.json', 'w') as json_file: + json.dump(all_vgos, json_file, indent=4, default=default) -# Scarica tutte le immagini + # Scarica tutte le immagini -print("Scarico le immagini") -with open('oloturiadump.json') as json_file: - all_vgos = json.load(json_file) - os.makedirs('media', exist_ok=True) + print("Scarico le immagini") + with open('oloturiadump.json') as json_file: + all_vgos = json.load(json_file) + os.makedirs('media', exist_ok=True) - vgo_dict={} + vgo_dict={} - for vgo in all_vgos: - vgo_num = html2text.html2text(vgo['content']).split(' ')[0] - vgo_name = os.linesep.join([s for s in html2text.html2text(vgo['content']).splitlines() if s]).splitlines()[-1] - #print(vgo_num +' - '+ vgo_name) - #print(str(vgo['id']) +' '+ vgo['uri']) - vgo_dict[vgo_num] = vgo_name - - for media in vgo['media']: - #print(str(media['id']) +' '+ media['url']) - - ext = os.path.splitext(media['preview_url'])[1] - img_name = os.path.join('media',str(media['id']) + ext) - - if not os.path.isfile(img_name): - print(img_name) - img_data = requests.get(media['preview_url']).content - with open(img_name, 'wb') as handler: - handler.write(img_data) - - with open('template.html') as html_file: - html_base = html_file.read() - with open('mediagallery.html') as html_file: - html_mediagallery = html_file.read() - - - # Genera i PDF - - print("Genero i PDF") - os.makedirs('pdf', exist_ok=True) - for vgo in all_vgos: - vgo_num = html2text.html2text(vgo['content']).split(' ')[0] - vgo_name = os.linesep.join([s for s in html2text.html2text(vgo['content']).splitlines() if s]).splitlines()[-1] - - html_name = 'oloturia.html' - pdf_name = os.path.join('pdf', vgo_num + '.pdf') - - if not os.path.isfile(pdf_name): - print(vgo_num +' - '+ vgo_name) - - - media_num = 0 - mediagallery_tot = '' - media_tot = len(vgo['media']) - - sizes = "622px" if media_tot == 1 else "311px" - style = [ - ["inset: auto; width: 100%; height: 100%;"], - ["inset: auto 2px auto auto; width: 50%; height: 100%;","inset: auto auto auto 2px; width: 50%; height: 100%;"], - ["inset: auto 2px auto auto; width: 50%; height: 100%;","inset: auto auto 2px 2px; width: 50%; height: 50%;","inset: 2px auto auto 2px; width: 50%; height: 50%;"], - ["inset: auto 2px 2px auto; width: 50%; height: 50%;","inset: auto auto 2px 2px; width: 50%; height: 50%;","inset: 2px 2px auto auto; width: 50%; height: 50%;","inset: 2px auto auto 2px; width: 50%; height: 50%;"] - ] + for vgo in all_vgos: + vgo_num = html2text.html2text(vgo['content']).split(' ')[0] + vgo_name = os.linesep.join([s for s in html2text.html2text(vgo['content']).splitlines() if s]).splitlines()[-1] + #print(vgo_num +' - '+ vgo_name) + #print(str(vgo['id']) +' '+ vgo['uri']) + vgo_dict[vgo_num] = vgo_name for media in vgo['media']: - mediagallery = html_mediagallery - ext = os.path.splitext(media['url'])[1] + #print(str(media['id']) +' '+ media['url']) + + ext = os.path.splitext(media['preview_url'])[1] img_name = os.path.join('media',str(media['id']) + ext) - mediagallery = mediagallery.replace("[media]", img_name) - mediagallery = mediagallery.replace("[style]", style[media_tot-1][media_num]) - mediagallery = mediagallery.replace("[sizes]", sizes) - mediagallery_tot = mediagallery_tot + mediagallery - media_num = media_num + 1 + + if not os.path.isfile(img_name): + print(img_name) + img_data = requests.get(media['preview_url']).content + with open(img_name, 'wb') as handler: + handler.write(img_data) - content = html_base - content = content.replace("[content]", vgo['content']) - content = content.replace("[date]", datetime.datetime.fromisoformat(vgo['created']).strftime("%-d %B %Y, %H:%M")) - content = content.replace("[reply]", str(vgo['replies_count'])) - content = content.replace("[reblogs]", str(vgo['reblogs'])) - content = content.replace("[favourites]", str(vgo['favourites'])) - content = content.replace("[mediagallery]", mediagallery_tot) + with open('template.html') as html_file: + html_base = html_file.read() + with open('mediagallery.html') as html_file: + html_mediagallery = html_file.read() - with open(html_name, 'w') as handler: - handler.write(content) + + # Genera i PDF + + print("Genero i PDF") + os.makedirs('pdf', exist_ok=True) + for vgo in all_vgos: + vgo_num = html2text.html2text(vgo['content']).split(' ')[0] + vgo_name = os.linesep.join([s for s in html2text.html2text(vgo['content']).splitlines() if s]).splitlines()[-1] + + html_name = 'oloturia.html' + pdf_name = os.path.join('pdf', vgo_num + '.pdf') + + if not os.path.isfile(pdf_name): + print(vgo_num +' - '+ vgo_name) + + + media_num = 0 + mediagallery_tot = '' + media_tot = len(vgo['media']) + + sizes = "622px" if media_tot == 1 else "311px" + style = [ + ["inset: auto; width: 100%; height: 100%;"], + ["inset: auto 2px auto auto; width: 50%; height: 100%;","inset: auto auto auto 2px; width: 50%; height: 100%;"], + ["inset: auto 2px auto auto; width: 50%; height: 100%;","inset: auto auto 2px 2px; width: 50%; height: 50%;","inset: 2px auto auto 2px; width: 50%; height: 50%;"], + ["inset: auto 2px 2px auto; width: 50%; height: 50%;","inset: auto auto 2px 2px; width: 50%; height: 50%;","inset: 2px 2px auto auto; width: 50%; height: 50%;","inset: 2px auto auto 2px; width: 50%; height: 50%;"] + ] + + for media in vgo['media']: + mediagallery = html_mediagallery + ext = os.path.splitext(media['url'])[1] + img_name = os.path.join('media',str(media['id']) + ext) + mediagallery = mediagallery.replace("[media]", img_name) + mediagallery = mediagallery.replace("[style]", style[media_tot-1][media_num]) + mediagallery = mediagallery.replace("[sizes]", sizes) + mediagallery_tot = mediagallery_tot + mediagallery + media_num = media_num + 1 + + content = html_base + content = content.replace("[content]", vgo['content']) + content = content.replace("[date]", datetime.datetime.fromisoformat(vgo['created']).strftime("%-d %B %Y, %H:%M")) + content = content.replace("[reply]", str(vgo['replies_count'])) + content = content.replace("[reblogs]", str(vgo['reblogs'])) + content = content.replace("[favourites]", str(vgo['favourites'])) + content = content.replace("[mediagallery]", mediagallery_tot) + + with open(html_name, 'w') as handler: + handler.write(content) + + options = { + 'page-size': 'A5', + 'margin-top': '0.5cm', + 'margin-right': '0.5cm', + 'margin-bottom': '0.5cm', + 'margin-left': '0.5cm', + 'encoding': "UTF-8", + 'quiet': '' + } + + try: + pdfkit.from_file(html_name, pdf_name, options=options) + except: + pass + + os.remove(html_name) + + + # Genera i libretti + + print("Genero i libretti") + os.makedirs('books', exist_ok=True) + for book_num in range(1, int(len(vgo_dict) / 50) + 1): + pdfWriter = PyPDF2.PdfFileWriter() + print(book_num) + + pagstart = (book_num - 1) * 50 + 1 + pagend = book_num * 50 + + # aggiungere copertina + pdfWriter.addPage(copertina(str(pagstart).zfill(3) + " - " + str(pagend).zfill(3))) + + for vgo_num in [str(x).zfill(3) for x in range(pagstart, pagend + 1)]: + pdf_name = os.path.join('pdf', vgo_num + '.pdf') - options = { - 'page-size': 'A5', - 'margin-top': '0.5cm', - 'margin-right': '0.5cm', - 'margin-bottom': '0.5cm', - 'margin-left': '0.5cm', - 'encoding': "UTF-8", - 'quiet': '' - } - try: - pdfkit.from_file(html_name, pdf_name, options=options) + #print(vgo_num + " - " + vgo_dict[vgo_num]) + pdfFileObj = open(pdf_name, 'rb') + pdfReader = PyPDF2.PdfFileReader(pdfFileObj) + pageObj = pdfReader.getPage(0) + pdfWriter.addPage(pageObj) except: pass - - os.remove(html_name) - - -# Genera i libretti - -print("Genero i libretti") -os.makedirs('books', exist_ok=True) -for book_num in range(1, int(len(vgo_dict) / 50) + 1): - pdfWriter = PyPDF2.PdfFileWriter() - print(book_num) - - pagstart = (book_num - 1) * 50 + 1 - pagend = book_num * 50 - - # aggiungere copertina - pdfWriter.addPage(copertina(str(pagstart).zfill(3) + " - " + str(pagend).zfill(3))) - - for vgo_num in [str(x).zfill(3) for x in range(pagstart, pagend + 1)]: - pdf_name = os.path.join('pdf', vgo_num + '.pdf') - try: - #print(vgo_num + " - " + vgo_dict[vgo_num]) - pdfFileObj = open(pdf_name, 'rb') - pdfReader = PyPDF2.PdfFileReader(pdfFileObj) - pageObj = pdfReader.getPage(0) - pdfWriter.addPage(pageObj) - except: - pass - - # aggiungere indice ed eventualmente pagina finale - - book_name = os.path.join('books', 'book' + str(book_num).zfill(2) + '.pdf') - with open(book_name, 'wb') as pdfOutput: - pdfWriter.write(pdfOutput) + # aggiungere indice ed eventualmente pagina finale + + book_name = os.path.join('books', 'book' + str(book_num).zfill(2) + '.pdf') + with open(book_name, 'wb') as pdfOutput: + pdfWriter.write(pdfOutput) +if __name__ == "__main__": + main()