Skip to content

Commit f8be3d8

Browse files
committed
Merge branch 'master' into stage
2 parents 5285032 + fc760a2 commit f8be3d8

File tree

14 files changed

+165
-105
lines changed

14 files changed

+165
-105
lines changed

Makefile

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
SHELL = /bin/bash
2+
DOCKER_EXEC_DJANGO=$(shell command -v docker > /dev/null && echo "docker-compose exec -T django")
3+
DOCKER_EXEC_VUE=$(shell command -v docker > /dev/null && echo "docker-compose exec vue")
4+
DOCKER_EXEC_WWW=$(shell command -v docker > /dev/null && echo "docker-compose exec www")
5+
26
.PHONY: tests
37

48
init:
@@ -17,10 +21,26 @@ push:
1721
cd vue && make push
1822

1923
enter_django:
20-
cd django && make enter
24+
$(DOCKER_EXEC_DJANGO) ash
2125

2226
enter_vue:
23-
cd vue && make enter
27+
$(DOCKER_EXEC_VUE) ash
28+
29+
enter_www:
30+
$(DOCKER_EXEC_WWW) ash
31+
32+
start_vue:
33+
$(DOCKER_EXEC_VUE) make
34+
35+
start_django:
36+
$(DOCKER_EXEC_DJANGO) make
37+
38+
start_screenshotservice:
39+
$(DOCKER_EXEC_VUE) make screenshotservice
40+
41+
reload_www:
42+
$(DOCKER_EXEC_WWW) sh -c 'openresty -t & openresty -s reload'
43+
2444

2545
deploy_prod:
2646
cd vue && make build

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ For a tour of the app and a testing protocol see [`docs/testing.md`](/docs/testi
2424

2525
## setup project
2626

27-
Add `django` to the 127.0.0.1 entry in `/etc/hosts` (for screenshot service).
27+
Add `www.local` and `django` to the 127.0.0.1 entry in `/etc/hosts` (for screenshot service).
2828

2929
```bash
3030
touch env.hosts.prod # required file, can be empty and edited later
@@ -66,6 +66,19 @@ Database files and static generated files are stored in `var` folder.
6666
make up
6767
```
6868

69+
**start services**
70+
71+
```bash
72+
# 1. shell
73+
make start_vue
74+
# 2. shell
75+
make start_django
76+
# 3. shell
77+
make start_screenshotservice
78+
```
79+
80+
You can also start the vue / django service from the vscode shell (see editor).
81+
6982
### tests
7083

7184
```bash

django/gsmap/admin.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,25 @@
44
from django_json_widget.widgets import JSONEditorWidget
55
from django.utils.html import mark_safe
66
from django.contrib import messages
7+
from django.forms.widgets import Textarea
78
import requests
89
from sortedm2m_filter_horizontal_widget.forms import SortedFilteredSelectMultiple
910
from gsmap.models import Municipality, Snapshot, Workspace
1011

1112

1213
class MunicipalityAdmin(admin.OSMGeoAdmin):
13-
pass
14+
readonly_fields = ('bfs_number',)
15+
fields = ('bfs_number', 'name', 'canton', 'perimeter')
16+
list_display = (
17+
'name',
18+
'bfs_number',
19+
)
20+
list_filter = ('canton',)
21+
search_fields = ('id', 'name', 'canton')
22+
23+
def get_map_widget(self, db_field):
24+
return Textarea
25+
1426

1527

1628
class SnapshotAdmin(admin.OSMGeoAdmin):
@@ -92,7 +104,17 @@ def save_model(self, request, obj, form, change):
92104
try:
93105
obj.save()
94106
except (requests.exceptions.ReadTimeout, requests.exceptions.ConnectionError) as e:
95-
messages.error(request, "Couldn't create the screenshots, screenshot server problem.")
107+
print(repr(e))
108+
messages.error(
109+
request,
110+
"Couldn't create the screenshots, screenshot server problem. (ReadTimeout, ConnectionError)"
111+
)
112+
except Exception as e:
113+
print(repr(e))
114+
messages.error(
115+
request,
116+
"Couldn't create the screenshots, screenshot server problem. (Other Error)"
117+
)
96118

97119

98120
class WorkspaceAdmin(admin.OSMGeoAdmin):

django/gsmap/models.py

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class Meta:
7070
def fullname(self):
7171
return f'{self.name} ({self.canton})'
7272

73+
@property
74+
def bfs_number(self):
75+
return self.id
76+
7377
def __str__(self):
7478
return self.fullname
7579

@@ -195,20 +199,6 @@ def create_screenshot_file(self, is_thumbnail=False):
195199
)
196200
return screenshot_file
197201

198-
def save(self, *args, **kwargs):
199-
def test_exists(pk):
200-
if list(self.__class__.objects.filter(pk=pk)):
201-
new_id = create_slug_hash_6()
202-
test_exists(new_id)
203-
else:
204-
return pk
205-
206-
if self._state.adding:
207-
self.id = create_slug_hash_6()
208-
self.id = test_exists(self.id)
209-
210-
super().save(*args, **kwargs)
211-
212202
def image_twitter(self):
213203
if bool(self.screenshot):
214204
return get_thumbnail(
@@ -231,53 +221,58 @@ def __str__(self):
231221
else:
232222
return self.title
233223

224+
def save(self, *args, **kwargs):
225+
def test_exists(pk):
226+
if list(self.__class__.objects.filter(pk=pk)):
227+
new_id = create_slug_hash_6()
228+
test_exists(new_id)
229+
else:
230+
return pk
231+
232+
if self._state.adding:
233+
self.id = create_slug_hash_6()
234+
self.id = test_exists(self.id)
234235

235-
@receiver(post_save, sender=Snapshot)
236-
def save_screenshot_handler(sender, **kwargs):
237-
instance = kwargs.get('instance')
236+
if self.data:
237+
storage = OverwriteStorage()
238+
if self.permission is int(SnapshotPermission.PUBLIC):
239+
self.create_meta(storage)
240+
else:
241+
storage.delete(f'snapshot-meta/{self.id}.html')
238242

239-
def save_screenshot():
240-
post_save.disconnect(save_screenshot_handler, sender=Snapshot)
243+
super().save(*args, **kwargs)
244+
245+
if hasattr(settings, 'SAVE_SCREENSHOT_ENABLED') and settings.SAVE_SCREENSHOT_ENABLED is True:
246+
self.create_screenshot()
247+
248+
super().save(*args, **kwargs)
249+
250+
def create_screenshot(self):
241251
# only create snapshot if data changed
242-
if instance.data_changed([
252+
if self.data_changed([
243253
'data', 'screenshot_generated', 'thumbnail_generated'
244-
]) or not bool(instance.thumbnail_generated):
245-
if not 'resources' in instance.data:
246-
return
247-
try:
248-
# disconnect to break save recursive loop
249-
post_save.disconnect(save_screenshot_handler, sender=Snapshot)
250-
screenshot_file = instance.create_screenshot_file()
251-
thumbnail_file = instance.create_screenshot_file(is_thumbnail=True)
252-
instance.screenshot_generated = screenshot_file
253-
instance.thumbnail_generated = thumbnail_file
254-
instance.save()
255-
finally:
256-
# always reconnect signal
257-
post_save.connect(save_screenshot_handler, sender=Snapshot)
258-
259-
def save_meta(storage):
254+
]) or not bool(self.thumbnail_generated):
255+
print('resources', 'resources' in self.data)
256+
if not 'resources' in self.data:
257+
raise ValueError('no resources key in data')
258+
259+
screenshot_file = self.create_screenshot_file()
260+
thumbnail_file = self.create_screenshot_file(is_thumbnail=True)
261+
self.screenshot_generated = screenshot_file
262+
self.thumbnail_generated = thumbnail_file
263+
264+
def create_meta(self, storage):
260265
domain = Site.objects.get_current().domain
261266
proto = 'https' if settings.USE_HTTPS else 'http'
262267
meta = f'''
263-
<meta property="og:title" content="{instance.title_data}">
264-
<meta property="og:description" content="{instance.description_data}">
268+
<meta property="og:title" content="{self.title_data}">
269+
<meta property="og:description" content="{self.description_data}">
265270
<meta property="og:type" content="website">
266-
<meta property="og:url" content="{proto}://{domain}{instance.get_absolute_url()}">
267-
<meta property="og:image" content="{proto}://{domain}/{instance.image_facebook()}">
268-
<meta name="twitter:image" content="{proto}://{domain}/{instance.image_twitter()}">
271+
<meta property="og:url" content="{proto}://{domain}{self.get_absolute_url()}">
272+
<meta property="og:image" content="{proto}://{domain}/{self.image_facebook()}">
273+
<meta name="twitter:image" content="{proto}://{domain}/{self.image_twitter()}">
269274
'''
270-
storage.save(f'snapshot-meta/{instance.id}.html', ContentFile(meta))
271-
272-
if hasattr(settings, 'SAVE_SCREENSHOT_ENABLED') and settings.SAVE_SCREENSHOT_ENABLED is True:
273-
save_screenshot()
274-
275-
if instance.data:
276-
storage = OverwriteStorage()
277-
if instance.permission is int(SnapshotPermission.PUBLIC):
278-
save_meta(storage)
279-
else:
280-
storage.delete(f'snapshot-meta/{instance.id}.html')
275+
storage.save(f'snapshot-meta/{self.id}.html', ContentFile(meta))
281276

282277

283278
class Workspace(models.Model):

django/main/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@
129129
CORS_ORIGIN_WHITELIST = [
130130
"http://localhost:8080",
131131
"http://localhost:8081",
132+
"http://www:8000",
133+
"http://www.local:8000",
132134
]
133135
CORS_ALLOW_CREDENTIALS = True
134136
CACHES = {

docker-compose.yml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ services:
2727
environment:
2828
- TERM=xterm-256color
2929
- START_SCREENSHOTSERVICE=NO
30-
- PUBLIC_URL=http://localhost:8080
30+
- PUBLIC_URL=http://www:8000
31+
- VUE_APP_MAPBOX_ACCESSTOKEN=pk.eyJ1IjoiZ2VtZWluZGVzY2FuIiwiYSI6ImNrNXdrOXV2ZjEwdXcza28wcXNoYXE1ZGMifQ.P-nCvxNRK4AOs7YdRbHCLg
32+
- VUE_APP_MAPBOX_DEFAULT_STYLES=mapbox://styles/gemeindescan/ck6rp249516tg1iqkmt48o4pz
3133
working_dir: /opt/vue
3234
volumes:
3335
- ./vue:/opt/vue
3436
- var-gemeindescan-webui:/var/services/
3537
- vscode-remote-vue:/root/.vscode-server
3638
ports:
37-
# - "9222:9222" # debug chrome
39+
- "9222:9222" # debug chrome
3840
- "8079:8079" # snapshost service
3941
- "10001:10001" # vscode
4042

@@ -53,14 +55,12 @@ services:
5355
- DJANGO_HTTPS=False
5456
- DJANGO_EMAIL_HOST=maildev
5557
- DJANGO_SECRET_KEY=adddxxccxx4rt0ioywg3yf5kjq64-t5
56-
- DJANGO_ALLOWED_HOSTS=local.gemeindescan.ch,localhost,django
58+
- DJANGO_ALLOWED_HOSTS=www,www.local,localhost,django
5759
working_dir: /opt/app
5860
volumes:
5961
- ./django:/opt/app
6062
- var-gemeindescan-webui:/var/services
6163
- vscode-remote-django:/root/.vscode-server
62-
links:
63-
- pdb
6464
ports:
6565
- "10002:10002" # vscode
6666
# entrypoint: tail
@@ -72,9 +72,6 @@ services:
7272
volumes:
7373
- ./etc/nginx:/etc/nginx/conf.d
7474
- var-gemeindescan-webui:/var/services
75-
links:
76-
- django
77-
- vue
7875
ports:
79-
- 8080:80
80-
command: tail -f /dev/null
76+
- 8000:8000
77+
# command: tail -f /dev/null

etc/nginx/localhost.conf renamed to etc/nginx/www.local.conf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ upstream vue-dev {
77
}
88

99
server {
10-
listen 80;
11-
server_name localhost;
10+
listen 8000;
11+
server_name www www.local;
1212

13-
access_log /var/log/localhost.access.log;
14-
error_log /var/log/localhost.error.log error;
13+
access_log /var/log/local.www.access.log;
14+
error_log /var/log/local.www.error.log error;
1515

1616
client_max_body_size 10M;
1717

@@ -20,7 +20,7 @@ server {
2020
location = / {
2121
set $lang_sup "de,fr";
2222
set_by_lua_file $lang_accept /etc/nginx/conf.d/lang.lua $lang_sup;
23-
return $scheme://$host:8080/$lang_accept;
23+
return $scheme://$host:8000/$lang_accept;
2424
}
2525

2626

@@ -89,7 +89,7 @@ server {
8989

9090
# vue dev server mode hotreload
9191
location /sockjs-node {
92-
proxy_pass http://vue:8080;
92+
proxy_pass http://vue-dev;
9393
proxy_set_header Host $host;
9494
proxy_set_header X-Real-IP $remote_addr;
9595
proxy_set_header X-Forwarded-For $remote_addr;

vue/.env

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
VUE_APP_GRAPHQL_URI=http://localhost:8080/graphql/
2-
VUE_APP_MAPBOX_ACCESSTOKEN=pk.eyJ1IjoiZ2VtZWluZGVzY2FuIiwiYSI6ImNrNXdrOXV2ZjEwdXcza28wcXNoYXE1ZGMifQ.P-nCvxNRK4AOs7YdRbHCLg
3-
VUE_APP_DJANGOBASEURL=http://localhost:8080
1+
VUE_APP_GRAPHQL_URI=http://www:8000/graphql/
2+
VUE_APP_DJANGOBASEURL=http://www:8000

vue/.env.production

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
VUE_APP_GRAPHQL_URI=/graphql/
2-
VUE_APP_MAPBOX_ACCESSTOKEN=pk.eyJ1IjoiZ2VtZWluZGVzY2FuIiwiYSI6ImNrNXdrOXV2ZjEwdXcza28wcXNoYXE1ZGMifQ.P-nCvxNRK4AOs7YdRbHCLg
32
VUE_APP_DJANGOBASEURL=

vue/screenshot-service/screenshot-server.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ const browserFactory = {
1818
devtools: false,
1919
args: [
2020
'--no-sandbox',
21-
'--disable-dev-shm-usage'
21+
'--disable-dev-shm-usage',
22+
'--disable-setuid-sandbox',
23+
'--disable-accelerated-2d-canvas',
24+
'--disable-gpu'
2225
// '--remote-debugging-port=9222',
2326
// '--remote-debugging-address=0.0.0.0'
2427
]
@@ -71,9 +74,12 @@ app.get('*', async (req, res) => {
7174

7275
const page = await browserPool.acquire();
7376
page.setViewport(pageOptions);
74-
await page.goto(screenshotUrl);
77+
await page.goto(screenshotUrl, {
78+
waitLoad: true,
79+
waitNetworkIdle: true
80+
});
7581
await page.waitForSelector('#mapinfo .v-list-item__title');
76-
await page.waitFor(1000); // extra 1sec wait, for map tiles
82+
// await page.waitFor(1000); // extra 1sec wait, for map tiles
7783
const screenshotBuffer = await page.screenshot({ encoding: 'binary' });
7884
// await browser.close();
7985
await browserPool.release(page);

0 commit comments

Comments
 (0)