22import string
33from enum import IntFlag
44import requests
5+ import os
56from django .utils import timezone
67from django .db .models .signals import post_save
78from django .dispatch import receiver
1112from django .contrib .sites .models import Site
1213from django .utils .html import format_html
1314from django .conf import settings
15+ from django .core .files .base import ContentFile
16+ from django .core .files .storage import FileSystemStorage
1417from sortedm2m .fields import SortedManyToManyField
15- from sorl .thumbnail import ImageField
18+ from sorl .thumbnail import ImageField , get_thumbnail
1619from 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+
1930class Municipality (models .Model ):
2031 class Meta :
2132 verbose_name_plural = 'municipalities'
@@ -59,6 +70,10 @@ class Meta:
5970 def fullname (self ):
6071 return f'{ self .name } ({ self .canton } )'
6172
73+ @property
74+ def bfs_number (self ):
75+ return self .id
76+
6277 def __str__ (self ):
6378 return self .fullname
6479
@@ -144,10 +159,25 @@ def screenshot(self):
144159 def thumbnail (self ):
145160 return self .thumbnail_manual or self .thumbnail_generated
146161
162+ @property
163+ def title_data (self ):
164+ try :
165+ return self .data ['views' ][0 ]['spec' ]['title' ]
166+ except KeyError :
167+ return self .title
168+
169+ @property
170+ def description_data (self ):
171+ try :
172+ return self .data ['views' ][0 ]['spec' ]['description' ]
173+ except KeyError :
174+ return ''
175+
147176 def get_absolute_link (self ):
148177 domain = Site .objects .get_current ().domain
178+ proto = 'https' if settings .USE_HTTPS else 'http'
149179 return format_html (
150- f'<a href="//{ domain } { self .get_absolute_url ()} " target="_blank">'
180+ f'<a href="{ proto } : //{ domain } { self .get_absolute_url ()} " target="_blank">'
151181 f'{ domain } { self .get_absolute_url ()} </a>'
152182 )
153183 get_absolute_link .short_description = "Snapshot Url"
@@ -169,6 +199,28 @@ def create_screenshot_file(self, is_thumbnail=False):
169199 )
170200 return screenshot_file
171201
202+ def image_twitter (self ):
203+ if bool (self .screenshot ):
204+ return get_thumbnail (
205+ self .screenshot , '1200x630' ,
206+ crop = 'bottom' , format = 'PNG'
207+ )
208+ return ''
209+
210+ def image_facebook (self ):
211+ if bool (self .screenshot ):
212+ return get_thumbnail (
213+ self .screenshot , '1200x630' ,
214+ crop = 'bottom' , format = 'PNG'
215+ )
216+
217+ def __str__ (self ):
218+ if self .municipality :
219+ return f'{ self .municipality .fullname } , { self .title } , ' \
220+ f'{ self .id } ({ self .get_permission_display ()} )'
221+ else :
222+ return self .title
223+
172224 def save (self , * args , ** kwargs ):
173225 def test_exists (pk ):
174226 if list (self .__class__ .objects .filter (pk = pk )):
@@ -181,40 +233,46 @@ def test_exists(pk):
181233 self .id = create_slug_hash_6 ()
182234 self .id = test_exists (self .id )
183235
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' )
242+
184243 super ().save (* args , ** kwargs )
185244
186- def __str__ (self ):
187- if self .municipality :
188- return f'{ self .municipality .fullname } , { self .title } , ' \
189- f'{ self .id } ({ self .get_permission_display ()} )'
190- else :
191- return self .title
245+ if hasattr (settings , 'SAVE_SCREENSHOT_ENABLED' ) and settings .SAVE_SCREENSHOT_ENABLED is True :
246+ self .create_screenshot ()
192247
248+ super ().save (* args , ** kwargs )
193249
194- @receiver (post_save , sender = Snapshot )
195- def save_screenshot_handler (sender , ** kwargs ):
196- def save_screenshot ():
197- post_save .disconnect (save_screenshot_handler , sender = Snapshot )
198- instance = kwargs .get ('instance' )
250+ def create_screenshot (self ):
199251 # only create snapshot if data changed
200- if instance .data_changed ([
252+ if self .data_changed ([
201253 'data' , 'screenshot_generated' , 'thumbnail_generated'
202- ]) or not bool (instance .thumbnail_generated ):
203- if not 'resources' in instance .data :
204- return
205- try :
206- # disconnect to break save recursive loop
207- post_save .disconnect (save_screenshot_handler , sender = Snapshot )
208- screenshot_file = instance .create_screenshot_file ()
209- thumbnail_file = instance .create_screenshot_file (is_thumbnail = True )
210- instance .screenshot_generated = screenshot_file
211- instance .thumbnail_generated = thumbnail_file
212- instance .save ()
213- finally :
214- # always reconnect signal
215- post_save .connect (save_screenshot_handler , sender = Snapshot )
216- if hasattr (settings , 'SAVE_SCREENSHOT_ENABLED' ) and settings .SAVE_SCREENSHOT_ENABLED is True :
217- save_screenshot ()
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 ):
265+ domain = Site .objects .get_current ().domain
266+ proto = 'https' if settings .USE_HTTPS else 'http'
267+ meta = f'''
268+ <meta property="og:title" content="{ self .title_data } ">
269+ <meta property="og:description" content="{ self .description_data } ">
270+ <meta property="og:type" content="website">
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 ()} ">
274+ '''
275+ storage .save (f'snapshot-meta/{ self .id } .html' , ContentFile (meta ))
218276
219277
220278class Workspace (models .Model ):
@@ -234,9 +292,10 @@ class Meta:
234292 snapshots = SortedManyToManyField (Snapshot )
235293
236294 def get_absolute_link (self ):
295+ proto = 'https' if settings .USE_HTTPS else 'http'
237296 domain = Site .objects .get_current ().domain
238297 return format_html (
239- f'<a href="//{ domain } { self .get_absolute_url ()} " target="_blank">'
298+ f'<a href="{ proto } : //{ domain } { self .get_absolute_url ()} " target="_blank">'
240299 f'{ domain } { self .get_absolute_url ()} </a>'
241300 )
242301 get_absolute_link .short_description = "Workspace Url"
@@ -245,7 +304,6 @@ def get_absolute_url(self):
245304 first_id = self .snapshots .all ().first ().id
246305 return f'/{ self .id } /{ first_id } /'
247306
248-
249307 def save (self , * args , ** kwargs ):
250308 def test_exists (pk ):
251309 if self .__class__ .objects .filter (pk = pk ):
0 commit comments