add missing files
This commit is contained in:
		
							
								
								
									
										24
									
								
								aircox_web/assets/styles.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								aircox_web/assets/styles.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					@charset "utf-8";
 | 
				
			||||||
 | 
					@import "~bulma/sass/utilities/_all.sass";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$body-background-color: $light;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import "~bulma/bulma";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar {
 | 
				
			||||||
 | 
					    margin-bottom: 1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar.has-shadow {
 | 
				
			||||||
 | 
					    box-shadow: 0em 0.1em 0.5em rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar-brand img {
 | 
				
			||||||
 | 
					    min-height: 6em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbar-menu .navbar-item:not(:last-child) {
 | 
				
			||||||
 | 
					    border-right: 1px $grey solid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								aircox_web/fields.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								aircox_web/fields.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					from django.db import models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseMinMaxField:
 | 
				
			||||||
 | 
					    def __init__(self, verbose_name=None, name=None, min=None, max=None,
 | 
				
			||||||
 | 
					                 **kwargs):
 | 
				
			||||||
 | 
					        super().__init__(verbose_name, name, **kwargs)
 | 
				
			||||||
 | 
					        self.min_value = min
 | 
				
			||||||
 | 
					        self.max_value = max
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def minmax(self, value):
 | 
				
			||||||
 | 
					        return min(self.max_value, max(self.min_value, value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def to_python(self, value):
 | 
				
			||||||
 | 
					        return self.minmax(super().to_python(value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_prep_value(self, value):
 | 
				
			||||||
 | 
					        return super().get_prep_value(self.minmax(value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MinMaxField(BaseMinMaxField, models.IntegerField):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SmallMinMaxField(BaseMinMaxField, models.SmallIntegerField):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PositiveMinMaxField(BaseMinMaxField, models.PositiveIntegerField):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PositiveSmallMinMaxField(BaseMinMaxField, models.PositiveSmallIntegerField):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										51
									
								
								aircox_web/plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								aircox_web/plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					from django.db import models
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					from django.utils.html import escape, format_html, mark_safe
 | 
				
			||||||
 | 
					from django.urls import reverse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .image import ImageBase, Image
 | 
				
			||||||
 | 
					from .richtext import RichText
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = ['ImageBase', 'Image', 'RichText']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Link(models.Model):
 | 
				
			||||||
 | 
					    url = models.CharField(
 | 
				
			||||||
 | 
					        _('url'), max_length=128, null=True, blank=True,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    page = models.ForeignKey(
 | 
				
			||||||
 | 
					        'Page', models.SET_NULL, null=True, blank=True,
 | 
				
			||||||
 | 
					        verbose_name=_('Link to a page')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    text = models.CharField(_('text'), max_length=64, null=True, blank=True)
 | 
				
			||||||
 | 
					    info = models.CharField(_('info'), max_length=128, null=True, blank=True,
 | 
				
			||||||
 | 
					                            help_text=_('link description displayed as tooltip'))
 | 
				
			||||||
 | 
					    blank = models.BooleanField(_('new window'), default=False,
 | 
				
			||||||
 | 
					                                help_text=_('open in a new window'))
 | 
				
			||||||
 | 
					    css_class=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_url(self):
 | 
				
			||||||
 | 
					        if self.page:
 | 
				
			||||||
 | 
					            return self.page.path #reverse('page', args=[self.page.path])
 | 
				
			||||||
 | 
					        return self.url or ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def render(self):
 | 
				
			||||||
 | 
					        # FIXME: quote
 | 
				
			||||||
 | 
					        return format_html(
 | 
				
			||||||
 | 
					            '<a href="{}" title="{}"{}>{}</a>',
 | 
				
			||||||
 | 
					            self.get_url(), escape(self.info),
 | 
				
			||||||
 | 
					            ' class=' + escape(self.css_class) + ''
 | 
				
			||||||
 | 
					            if self.css_class else '',
 | 
				
			||||||
 | 
					            self.text or (self.page and self.page.title) or '',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        abstract = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Search(models.Model):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        abstract = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								aircox_web/plugins/image.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								aircox_web/plugins/image.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					from django.db import models
 | 
				
			||||||
 | 
					from django.templatetags.static import static
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					from django.utils.html import format_html, mark_safe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from easy_thumbnails.files import get_thumbnailer
 | 
				
			||||||
 | 
					from filer.fields.image import FilerImageField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = ['ImageBase', 'Image']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ImageBase(models.Model):
 | 
				
			||||||
 | 
					    image = FilerImageField(
 | 
				
			||||||
 | 
					        on_delete=models.CASCADE,
 | 
				
			||||||
 | 
					        verbose_name=_('image'),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    width = None
 | 
				
			||||||
 | 
					    height = None
 | 
				
			||||||
 | 
					    crop = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        abstract = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def thumbnail(self):
 | 
				
			||||||
 | 
					        if self.width == None and self.height == None:
 | 
				
			||||||
 | 
					            return self.image
 | 
				
			||||||
 | 
					        opts = {}
 | 
				
			||||||
 | 
					        if self.crop:
 | 
				
			||||||
 | 
					            opts['crop'] = 'smart'
 | 
				
			||||||
 | 
					        opts['size'] = (self.width or 0, self.height or 0)
 | 
				
			||||||
 | 
					        thumbnailer = get_thumbnailer(self.image)
 | 
				
			||||||
 | 
					        return thumbnailer.get_thumbnail(opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def render(self):
 | 
				
			||||||
 | 
					        return format_html('<img src="{}" alt=""/>', self.thumbnail.url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Image(ImageBase):
 | 
				
			||||||
 | 
					    width = models.PositiveSmallIntegerField(blank=True,null=True)
 | 
				
			||||||
 | 
					    height = models.PositiveSmallIntegerField(blank=True,null=True)
 | 
				
			||||||
 | 
					    crop = models.BooleanField(default=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        abstract = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										37
									
								
								aircox_web/plugins/timetable.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								aircox_web/plugins/timetable.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import models
 | 
				
			||||||
 | 
					from django.templatetags.static import static
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from aircox import models as aircox
 | 
				
			||||||
 | 
					from aircox_web.fields import PositiveSmallMinMaxField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Timetable(models.Model):
 | 
				
			||||||
 | 
					    station = models.ForeignKey(
 | 
				
			||||||
 | 
					        aircox.Station, models.CASCADE, verbose_name=_('station'),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    days_before = models.PositiveSmallMinMaxField(
 | 
				
			||||||
 | 
					        _('days before'), min=0, max=6,
 | 
				
			||||||
 | 
					        help_text=_('Count of days displayed current date'),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    days_after = models.PositiveSmallMinMaxField(
 | 
				
			||||||
 | 
					        _('days after'), min=0, max=6,
 | 
				
			||||||
 | 
					        help_text=_('Count of days displayed current date'),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_queryset(self, date=None):
 | 
				
			||||||
 | 
					        date = date if date is not None else datetime.date.today()
 | 
				
			||||||
 | 
					        qs = aircox.Diffusion.objects.station(self.station)
 | 
				
			||||||
 | 
					        if self.days_before is None and self.days_after is None:
 | 
				
			||||||
 | 
					            return qs.at(date)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        start = date - datetime.timedelta(days=self.days_before) \
 | 
				
			||||||
 | 
					            if self.days_before else date
 | 
				
			||||||
 | 
					        stop = date + datetime.timedelta(days=self.days_after) \
 | 
				
			||||||
 | 
					            if self.days_after else date
 | 
				
			||||||
 | 
					        return aircox.Diffusion.objects.station(self.station) \
 | 
				
			||||||
 | 
					                     .after(start).before(stop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user