Skip to content

Commit d52df6f

Browse files
committed
feature/enhance pdf saving (drop pdfkit and using pyppeteer)
1 parent 234cc41 commit d52df6f

File tree

9 files changed

+128
-66
lines changed

9 files changed

+128
-66
lines changed

src/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ RUN pip install -r requirements.txt
1414

1515
COPY ./entrypoint.sh .
1616

17+
RUN pyppeteer-install
18+
19+
# pyppeteer required libs
20+
RUN apt update && apt-get install -y libxshmfence-dev libdrm-dev libgbm-dev libpangocairo-1.0-0 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 libasound2 libatk1.0-0 libgtk-3-0
21+
1722
COPY . .
1823

1924

src/collectorapp/settings.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
# DJANGO DEBUG BAR
1111
DEBUG_TOOLBAR_CONFIG = {
12-
'SHOW_TOOLBAR_CALLBACK': lambda r: True,
12+
'SHOW_TOOLBAR_CALLBACK': lambda r: not r.path.startswith("/pdf"),
1313
}
1414

1515

@@ -143,6 +143,9 @@
143143

144144
STATIC_URL = '/static/'
145145
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
146+
STATICFILES_DIRS = (
147+
os.path.join(BASE_DIR, 'static'),
148+
)
146149

147150
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
148151
MEDIA_URL = '/media/'
@@ -213,7 +216,7 @@
213216
},
214217
"loggers": {
215218
"django": {
216-
"handlers": ["console",'djangofile']
219+
"handlers": ["console", 'djangofile']
217220
},
218221
"collectorapp.logger": {
219222
"level": "DEBUG",

src/lib/CollectorBot/handler.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,27 @@ def handle_collection(cls, status):
5151
rtl = True
5252
else:
5353
rtl = False
54-
54+
5555
thread_tweets_ids = Grabber.grab_thread_tweets_ids(id)
5656
if len(thread_tweets_ids) > 0:
57-
content = [thread.full_text+'<br><br>']
57+
content = ['<div class="tw-block">'+thread.full_text+'</div>']
5858
for tweet_id in thread_tweets_ids:
5959
tweet = cls.tweepy_client.get_status(
6060
tweet_id, tweet_mode='extended')
6161
if tweet.user.id != thread.user.id:
6262
break
6363
Cleaner.clean_tweet(tweet)
64-
content.append(tweet.full_text+'<br><br>')
64+
content.append(
65+
'<div class="tw-block">' + tweet.full_text+'</div>')
6566
content = ''.join(content)
66-
content = "<p class='article__text'>" + content + '<br><br> </p>'
67+
6768

6869
post = Post.objects.create(
6970
id=id, content=content, author_name=author_name,
7071
author_screen_name=author_screen_name,
7172
author_photo=author_photo,
7273
author_describtion=author_describtion, title=title,
73-
thumnail_photo=thumnail_photo,rtl=rtl)
74+
thumnail_photo=thumnail_photo, rtl=rtl)
7475
logger.info(
7576
f"Collected {len(thread_tweets_ids) + 1} replies from thread id:{id} ")
7677
cls.__add_post_to_user(

src/posts/views.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import pdfkit
21
from django.conf import settings
32
from django.contrib.auth.decorators import login_required
43
from django.core.cache import cache
@@ -8,6 +7,7 @@
87
from django.shortcuts import redirect, render
98
from django.urls import reverse
109
from django.views import View
10+
from pyppeteer import launch
1111
from utils.helpers import paginate
1212

1313
from . import forms
@@ -140,16 +140,25 @@ def get(self, request, id):
140140
def view_pdf(request, id):
141141
post = Post.objects.filter(id=id).first()
142142
if post:
143-
return render(
144-
request, 'posts/pdf.html',
145-
{'title': post.title, 'content': post.content, })
143+
return render(request, 'posts/pdf.html', {'post': post})
146144
return HttpResponseRedirect(reverse('home'))
147145

148146

149-
def download_pdf(request, id):
147+
async def download_pdf(request, id):
150148
# get view_pdf path => /pdf/view/1221554458
149+
# path = reverse('view_pdf', args=(id,))
150+
# pdf = pdfkit.from_url(f'{settings.APP_URL}{path}')
151+
# response = HttpResponse(pdf, content_type='application/pdf')
152+
# response['Content-Disposition'] = f'attachment; filename="{str(id)}.pdf"'
153+
# return response
154+
155+
browser = await launch(options={'args': ['--no-sandbox']}, handleSIGINT=False, handleSIGTERM=False, handleSIGHUP=False)
156+
page = await browser.newPage()
151157
path = reverse('view_pdf', args=(id,))
152-
pdf = pdfkit.from_url(f'{settings.APP_URL}{path}', False)
158+
await page.goto(f'{settings.APP_URL}{path}')
159+
pdf = await page.pdf({"format": 'A4'})
160+
await browser.close()
153161
response = HttpResponse(pdf, content_type='application/pdf')
154162
response['Content-Disposition'] = f'attachment; filename="{str(id)}.pdf"'
163+
response['Content-Length'] = len(pdf)
155164
return response

src/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ django-otp==1.1.3
99
django-qr-code==1.1.0
1010
django-redis==5.2.0
1111
fastcore==1.3.27
12-
pdfkit==1.0.0
1312
Pillow==7.1.2
1413
python-social-auth==0.3.6
1514
qrcode==6.1
@@ -23,4 +22,5 @@ gunicorn==20.1.0
2322
mysqlclient==2.1.0
2423
itsdangerous==1.1.0
2524
argon2-cffi==21.3.0
26-
Celery==5.2.3
25+
Celery==5.2.3
26+
pyppeteer==1.0.2

src/static/css/main-light.css

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
@font-face {
22
font-family: "cairo-regular";
33
src: url("../fonts/cairo-regular-webfont.eot");
4-
src: url("../fonts/cairo-regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/cairo-regular-webfont.woff2") format("woff2"),
5-
url("../fonts/cairo-regular-webfont.woff") format("woff"), url("../fonts/cairo-regular-webfont.ttf") format("truetype"),
4+
src: url("../fonts/cairo-regular-webfont.eot?#iefix") format("embedded-opentype"),
5+
url("../fonts/cairo-regular-webfont.woff2") format("woff2"),
6+
url("../fonts/cairo-regular-webfont.woff") format("woff"),
7+
url("../fonts/cairo-regular-webfont.ttf") format("truetype"),
68
url("../fonts/cairo-regular-webfont.svg#cairo-regular-webfont") format("svg");
79
font-style: normal;
810
font-weight: normal;
911
}
1012
@font-face {
1113
font-family: "cairo-semibold";
1214
src: url("../fonts/cairo-semibold-webfont.eot");
13-
src: url("../fonts/cairo-semibold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/cairo-semibold-webfont.woff2") format("woff2"),
14-
url("../fonts/cairo-semibold-webfont.woff") format("woff"), url("../fonts/cairo-semibold-webfont.ttf") format("truetype"),
15+
src: url("../fonts/cairo-semibold-webfont.eot?#iefix") format("embedded-opentype"),
16+
url("../fonts/cairo-semibold-webfont.woff2") format("woff2"),
17+
url("../fonts/cairo-semibold-webfont.woff") format("woff"),
18+
url("../fonts/cairo-semibold-webfont.ttf") format("truetype"),
1519
url("../fonts/cairo-semibold-webfont.svg#cairo-semibold-webfont") format("svg");
1620
font-style: normal;
1721
font-weight: normal;
@@ -25,7 +29,7 @@ body {
2529
height: 100%;
2630
}
2731
body {
28-
font-family: "cairo-regular";
32+
font-family: "cairo-semibold";
2933
background-color: #ececec;
3034
-webkit-font-smoothing: antialiased;
3135
}
@@ -526,8 +530,6 @@ ul {
526530
border-radius: 6px;
527531
overflow: hidden;
528532
}
529-
.article__gallery img {
530-
}
531533
.article__text {
532534
font-size: 16px;
533535
line-height: 28px;
@@ -540,6 +542,16 @@ ul {
540542
font-family: "cairo-semibold";
541543
font-weight: normal;
542544
}
545+
.tw-block {
546+
font-size: 16px;
547+
line-height: 28px;
548+
color: #222831;
549+
margin-bottom: 0;
550+
margin-top: 30px;
551+
text-align: center;
552+
font-family: "cairo-semibold";
553+
font-weight: normal;
554+
}
543555
.article__list {
544556
margin-top: 30px;
545557
text-align: right;
@@ -1106,4 +1118,3 @@ ul {
11061118
.mfp-fade.mfp-wrap.mfp-removing .mfp-content {
11071119
opacity: 0;
11081120
}
1109-

src/static/css/main.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,18 @@ ul {
550550
font-family: "cairo-semibold";
551551
font-weight: normal;
552552
}
553+
554+
.tw-block {
555+
font-size: 16px;
556+
line-height: 28px;
557+
color: #fff;
558+
margin-bottom: 0;
559+
margin-top: 30px;
560+
text-align: center;
561+
font-family: "cairo-semibold";
562+
font-weight: normal;
563+
}
564+
553565
.article__list {
554566
margin-top: 30px;
555567
text-align: right;

src/templates/posts/pdf.html

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,53 @@
11
<html lang="en">
2-
{% load static %}
3-
<head>
4-
<meta charset="UTF-8" />
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<title>{{title}}</title>
7-
<link rel="stylesheet" href="{% static 'css/styles.min.css' %}" />
8-
<link id="mode" rel="stylesheet" href="{% static 'css/main.css' %}" />
9-
<style>
10-
@media only screen and (max-width: 600px) {
11-
.article__gallery img {
12-
width: 100%;
13-
display: block;
14-
height: auto;
15-
}
2+
{% load static %}
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>{{post.id}}</title>
8+
<link rel="stylesheet" href="{% static 'css/styles.min.css' %}" />
9+
<link rel="stylesheet" href="{% static 'css/main.css' %}" />
10+
<style>
11+
@media only screen and (max-width: 600px) {
12+
.article__gallery img {
13+
width: 100%;
14+
display: block;
15+
height: auto;
1616
}
17-
.article__text{
18-
color:black;
19-
}
20-
body{
21-
background-color:white;
22-
}
23-
.article__gallery{
24-
pointer-events: none;
25-
cursor: default;
26-
text-decoration: none;
27-
color: black;
28-
}
29-
</style>
30-
</head>
31-
<body>
32-
<div class="col-12" style="margin-top: 50px;">
33-
<div class="article" style="text-align: center;">
34-
{{content|safe}}
35-
</div>
17+
}
18+
19+
.article__gallery img {
20+
margin: 0 auto;
21+
display: block;
22+
max-width: 700px;
23+
max-height: 600px;
24+
}
25+
26+
body {
27+
background-color: white;
28+
height: unset;
29+
}
30+
31+
.article__gallery {
32+
pointer-events: none;
33+
cursor: default;
34+
text-decoration: none;
35+
}
36+
37+
.tw-block {
38+
break-inside: avoid;
39+
color: black;
40+
display: block;
41+
}
42+
</style>
43+
</head>
44+
45+
<body {% if post.rtl is True %} style="direction: rtl;" {% endif %}>
46+
<div class="col-12" style="margin-top: 50px;">
47+
<div class="article" style="text-align: center;">
48+
{{post.content|safe}}
3649
</div>
37-
</body>
38-
<script src="{% static 'js/scripts.min.js' %}"></script>
39-
<script src="{% static 'js/main.js' %}"></script>
40-
</html>
50+
</div>
51+
</body>
52+
53+
</html>

src/templates/posts/post.html

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
margin: 0 auto;
2828
}
2929
</style>
30+
{% if post.rtl is True %}
31+
<style>
32+
.tw-block {
33+
direction: rtl;
34+
}
35+
</style>
36+
{% endif %}
3037
<section class="section section--first">
3138
<div class="container">
3239
<div class="row">
@@ -262,7 +269,8 @@
262269
<h4 class="form__title">Add a comment</h4>
263270
</div>
264271
<div class="col-12">
265-
<textarea name="text" cols="40" rows="10" class="form__textarea" placeholder="Write your comment" required></textarea>
272+
<textarea name="text" cols="40" rows="10" class="form__textarea" placeholder="Write your comment"
273+
required></textarea>
266274
</div>
267275

268276
<div class="col-12">
@@ -361,11 +369,11 @@ <h2 class="section__title2">Similar news</h2>
361369
}
362370
$(document).ready(function (e) {
363371

364-
document.querySelectorAll('.article__text').forEach((e) => {
365-
if (isUnicode(e.innerText)) {
366-
e.style.direction = 'rtl'
367-
}
368-
})
372+
// document.querySelectorAll('.article__text').forEach((e) => {
373+
// if (isUnicode(e.innerText)) {
374+
// e.style.direction = 'rtl'
375+
// }
376+
// })
369377
document.querySelectorAll('.desc').forEach((e) => {
370378
if (isUnicode(e.innerText)) { e.style.direction = 'rtl' }
371379
})

0 commit comments

Comments
 (0)