Skip to content

Commit 23e9626

Browse files
committed
Merged in lua-meta (pull request #22)
nginx lua meta
2 parents f98aff6 + c1fea92 commit 23e9626

File tree

12 files changed

+276
-75
lines changed

12 files changed

+276
-75
lines changed

django/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
GEMEINDESCAN_WEBUI_DJANGO=0.3.4
22
DOCKER_EXEC=$(shell command -v docker > /dev/null && echo "docker-compose exec django")
3-
all: run-tests run-tests-dev
3+
all: dev run-tests run-tests-dev
44
.PHONY: all
55
default: dev
66

@@ -25,6 +25,9 @@ adminuser:
2525
collectstatic:
2626
$(DOCKER_EXEC) python3 manage.py collectstatic --noinput
2727

28+
symlinks:
29+
$(DOCKER_EXEC) sh -c "cd /var/services/django; ln -s media downloads"
30+
2831
migrate:
2932
$(DOCKER_EXEC) python3 manage.py migrate
3033
make collectstatic
@@ -45,6 +48,7 @@ import-gemeinden-json:
4548
$(DOCKER_EXEC) rm ./tmp/gemeinden.geojson
4649

4750
init:
51+
make symlinks
4852
make migrate
4953
make adminuser
5054
make import-gemeinden-json

django/gsmap/models.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import string
33
from enum import IntFlag
44
import requests
5+
import os
56
from django.utils import timezone
67
from django.db.models.signals import post_save
78
from django.dispatch import receiver
@@ -11,11 +12,21 @@
1112
from django.contrib.sites.models import Site
1213
from django.utils.html import format_html
1314
from django.conf import settings
15+
from django.core.files.base import ContentFile
16+
from django.core.files.storage import FileSystemStorage
1417
from sortedm2m.fields import SortedManyToManyField
15-
from sorl.thumbnail import ImageField
18+
from sorl.thumbnail import ImageField, get_thumbnail
1619
from gsuser.models import User
1720

1821

22+
class OverwriteStorage(FileSystemStorage):
23+
def get_available_name(self, name, max_length=None):
24+
# If the filename already exists, remove it as if it was a true file system
25+
if self.exists(name):
26+
os.remove(os.path.join(settings.MEDIA_ROOT, name))
27+
return name
28+
29+
1930
class Municipality(models.Model):
2031
class Meta:
2132
verbose_name_plural = 'municipalities'
@@ -146,8 +157,9 @@ def thumbnail(self):
146157

147158
def get_absolute_link(self):
148159
domain = Site.objects.get_current().domain
160+
proto = 'https' if settings.USE_HTTPS else 'http'
149161
return format_html(
150-
f'<a href="//{domain}{self.get_absolute_url()}" target="_blank">'
162+
f'<a href="{proto}://{domain}{self.get_absolute_url()}" target="_blank">'
151163
f'{domain}{self.get_absolute_url()}</a>'
152164
)
153165
get_absolute_link.short_description = "Snapshot Url"
@@ -183,6 +195,18 @@ def test_exists(pk):
183195

184196
super().save(*args, **kwargs)
185197

198+
def image_twitter(self):
199+
return get_thumbnail(
200+
self.screenshot, '1200x630',
201+
crop='bottom', format='PNG'
202+
)
203+
204+
def image_facebook(self):
205+
return get_thumbnail(
206+
self.screenshot, '1200x630',
207+
crop='bottom', format='PNG'
208+
)
209+
186210
def __str__(self):
187211
if self.municipality:
188212
return f'{self.municipality.fullname}, {self.title}, ' \
@@ -193,9 +217,10 @@ def __str__(self):
193217

194218
@receiver(post_save, sender=Snapshot)
195219
def save_screenshot_handler(sender, **kwargs):
220+
instance = kwargs.get('instance')
221+
196222
def save_screenshot():
197223
post_save.disconnect(save_screenshot_handler, sender=Snapshot)
198-
instance = kwargs.get('instance')
199224
# only create snapshot if data changed
200225
if instance.data_changed([
201226
'data', 'screenshot_generated', 'thumbnail_generated'
@@ -213,9 +238,27 @@ def save_screenshot():
213238
finally:
214239
# always reconnect signal
215240
post_save.connect(save_screenshot_handler, sender=Snapshot)
241+
242+
def save_meta(storage):
243+
domain = Site.objects.get_current().domain
244+
proto = 'https' if settings.USE_HTTPS else 'http'
245+
meta = f'''name="og:title" content="{instance.title}"
246+
name="og:url" content="{instance.get_absolute_link()}"
247+
name="og:image" content="{proto}://{domain}/{instance.image_facebook()}"
248+
name="twitter:image" content="{proto}://{domain}/{instance.image_twitter()}"
249+
'''
250+
storage.save(f'snapshot-meta/{instance.id}.html', ContentFile(meta))
251+
216252
if hasattr(settings, 'SAVE_SCREENSHOT_ENABLED') and settings.SAVE_SCREENSHOT_ENABLED is True:
217253
save_screenshot()
218254

255+
if instance.screenshot:
256+
storage = OverwriteStorage()
257+
if instance.permission is int(SnapshotPermission.PUBLIC):
258+
save_meta(storage)
259+
else:
260+
storage.delete(f'snapshot-meta/{instance.id}.html')
261+
219262

220263
class Workspace(models.Model):
221264
class Meta:
@@ -234,9 +277,10 @@ class Meta:
234277
snapshots = SortedManyToManyField(Snapshot)
235278

236279
def get_absolute_link(self):
280+
proto = 'https' if settings.USE_HTTPS else 'http'
237281
domain = Site.objects.get_current().domain
238282
return format_html(
239-
f'<a href="//{domain}{self.get_absolute_url()}" target="_blank">'
283+
f'<a href="{proto}://{domain}{self.get_absolute_url()}" target="_blank">'
240284
f'{domain}{self.get_absolute_url()}</a>'
241285
)
242286
get_absolute_link.short_description = "Workspace Url"
@@ -245,7 +289,6 @@ def get_absolute_url(self):
245289
first_id = self.snapshots.all().first().id
246290
return f'/{self.id}/{first_id}/'
247291

248-
249292
def save(self, *args, **kwargs):
250293
def test_exists(pk):
251294
if self.__class__.objects.filter(pk=pk):

django/gsmap/schema.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from graphene_django.types import DjangoObjectType
99
from graphene_django.filter import DjangoFilterConnectionField
1010
from graphene_django.converter import convert_django_field
11-
from sorl.thumbnail import get_thumbnail
1211
from gsmap.models import Municipality, Snapshot, SnapshotPermission, Workspace
1312

1413

@@ -71,18 +70,10 @@ def resolve_thumbnail(self, info):
7170
return self.thumbnail
7271

7372
def resolve_screenshot_facebook(self, info):
74-
screenshot = get_thumbnail(self.screenshot,
75-
'1200x630',
76-
crop='bottom',
77-
format='PNG')
78-
return screenshot
73+
return self.image_facebook()
7974

8075
def resolve_screenshot_twitter(self, info):
81-
screenshot = get_thumbnail(self.screenshot,
82-
'1200x600',
83-
crop='bottom',
84-
format='PNG')
85-
return screenshot
76+
return self.image_twitter()
8677

8778

8879
class MunicipalityNode(DjangoObjectType):

docker-compose.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ services:
3636
ports:
3737
# - "9222:9222" # debug chrome
3838
- "8079:8079" # snapshost service
39-
- "8080:8080" # vue
4039
- "10001:10001" # vscode
4140

4241
django:
@@ -63,18 +62,19 @@ services:
6362
links:
6463
- pdb
6564
ports:
66-
- "8081:8081"
6765
- "10002:10002" # vscode
6866
# entrypoint: tail
6967
# command: -f /dev/null
7068

71-
# static:
72-
# image: nginx:1.16-alpine
73-
# hostname: static
74-
# volumes:
75-
# - ./etc/nginx:/etc/nginx/conf.d
76-
# - var-gemeindescan-webui:/var/services
77-
# links:
78-
# - django
79-
# ports:
80-
# - 80:80
69+
www:
70+
image: openresty/openresty:1.15.8.3-alpine
71+
hostname: www
72+
volumes:
73+
- ./etc/nginx:/etc/nginx/conf.d
74+
- var-gemeindescan-webui:/var/services
75+
links:
76+
- django
77+
- vue
78+
ports:
79+
- 8080:80
80+
command: tail -f /dev/null

etc/nginx/lang.lua

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
-------------------------------------------------------------------------------
2+
-- HTTP Accept-Language header handler --
3+
-- @originalAuthor: [email protected] --
4+
-- @originalRepository: https://github.com/fghibellini/nginx-http-accept-lang--
5+
-- @modifiedBy: [email protected] --
6+
-- @gist: https://gist.github.com/mauron85/47ed1075262d9e020fe2 --
7+
-- @license: MIT --
8+
-- @requires: --
9+
-- @description: --
10+
-- returns language with greatest quality --
11+
-- value according to RFC:2616 --
12+
-- @example configuration: --
13+
-- --
14+
-- server { --
15+
-- listen 8080 default_server; --
16+
-- index index.html index.htm; --
17+
-- server_name localhost; --
18+
-- --
19+
-- root usr/share/nginx/html; --
20+
-- --
21+
-- location = / { --
22+
-- # $lang_sup holds comma separated languages supported by site --
23+
-- # if no match first will be used (en) in this case --
24+
-- set $lang_sup = "en,sk" --
25+
-- set_by_lua_file $lang_accept /etc/nginx/lang.lua $lang_sup; --
26+
-- rewrite (.*) $scheme://$server_name/$lang_accept$1; --
27+
-- } --
28+
-- } --
29+
-- --
30+
-------------------------------------------------------------------------------
31+
32+
function inTable(tbl, item)
33+
for key, value in pairs(tbl) do
34+
if value == item then return key end
35+
end
36+
return false
37+
end
38+
39+
function string:split( inSplitPattern, outResults )
40+
if not outResults then
41+
outResults = { }
42+
end
43+
local theStart = 1
44+
local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
45+
while theSplitStart do
46+
table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
47+
theStart = theSplitEnd + 1
48+
theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
49+
end
50+
table.insert( outResults, string.sub( self, theStart ) )
51+
return outResults
52+
end
53+
54+
local lang_sup = {"en"}
55+
if ( ngx.arg[1] ~= nil ) then
56+
lang_sup = ngx.arg[1]:split(",")
57+
end
58+
59+
local lang_header = ngx.var.http_accept_language
60+
if ( lang_header == nil ) then
61+
return lang_sup[1]
62+
end
63+
64+
local cleaned = ngx.re.sub(lang_header, "^.*:", "")
65+
local options = {}
66+
local iterator, err = ngx.re.gmatch(cleaned, "\\s*([a-z]+(?:-[a-z])*)\\s*(?:;q=([0-9]+(.[0-9]*)?))?\\s*(,|$)", "i")
67+
for m, err in iterator do
68+
local lang = m[1]
69+
local priority = 1
70+
if m[2] ~= nil then
71+
priority = tonumber(m[2])
72+
if priority == nil then
73+
priority = 1
74+
end
75+
end
76+
table.insert(options, {lang, priority})
77+
end
78+
79+
table.sort(options, function(a,b) return b[2] < a[2] end)
80+
81+
for index, lang in pairs(options) do
82+
if inTable(lang_sup, lang[1]) then
83+
return lang[1]
84+
end
85+
end
86+
87+
return lang_sup[1]

etc/nginx/local.gemeindescan.ch.conf

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)