forked from rc/aircox
add website app, move articles to it, fix programs.models
This commit is contained in:
parent
dae9545e27
commit
ef4c098d2e
49
programs/README.md
Normal file
49
programs/README.md
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
This application defines all base classes for the aircox platform. This includes:
|
||||||
|
* **Metadata**: generic class that contains metadata
|
||||||
|
* **Publication**: generic class for models that can be publicated
|
||||||
|
* **Track**: informations on a track in a playlist
|
||||||
|
* **SoundFile**: informations on a sound (podcast)
|
||||||
|
* **Schedule**: schedule informations for programs
|
||||||
|
* **Article**: simple article
|
||||||
|
* **Program**: radio program
|
||||||
|
* **Episode**: occurence of a radio program
|
||||||
|
* **Event**: log info on what has been or what should be played
|
||||||
|
|
||||||
|
|
||||||
|
# Program
|
||||||
|
Each program has a directory in **AIRCOX_PROGRAMS_DATA**; For each, subdir:
|
||||||
|
* **public**: public sound files and data (accessible from the website)
|
||||||
|
* **private**: private sound files and data
|
||||||
|
* **podcasts**: podcasts that can be upload to external plateforms
|
||||||
|
|
||||||
|
|
||||||
|
# Event
|
||||||
|
Event have a double purpose:
|
||||||
|
- log played sounds
|
||||||
|
- plannify diffusions
|
||||||
|
|
||||||
|
|
||||||
|
# manage.py schedule
|
||||||
|
Return the next songs to be played and the schedule and the programmed emissions
|
||||||
|
|
||||||
|
# manage.py monitor
|
||||||
|
The manage.py has a command **monitor** that:
|
||||||
|
* check for new sound files
|
||||||
|
* stat the sound files
|
||||||
|
* match sound files against episodes and eventually program them
|
||||||
|
* upload public podcasts to mixcloud if required
|
||||||
|
|
||||||
|
The command will try to match file name against a planified episode by detecting
|
||||||
|
a date (ISO 8601 date notation YYYY-MM-DD or YYYYMMDD) as name prefix
|
||||||
|
|
||||||
|
Tags set:
|
||||||
|
* **incorrect**: the sound is not correct for diffusion (TODO: parameters)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from django.contrib import admin
|
from django import forms
|
||||||
from django.db import models
|
from django.contrib import admin
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
from suit.admin import SortableTabularInline, SortableModelAdmin
|
from suit.admin import SortableTabularInline, SortableModelAdmin
|
||||||
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
|
from autocomplete_light.contrib.taggit_field import TaggitWidget, TaggitField
|
||||||
|
|
||||||
from programs.forms import *
|
from programs.forms import *
|
||||||
from programs.models import *
|
from programs.models import *
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Inlines
|
# Inlines
|
||||||
|
@ -43,7 +45,7 @@ class MetadataAdmin (admin.ModelAdmin):
|
||||||
'fields': [ 'title', 'tags' ]
|
'fields': [ 'title', 'tags' ]
|
||||||
}),
|
}),
|
||||||
( None, {
|
( None, {
|
||||||
'fields': [ 'date', 'public', 'enumerable' ],
|
'fields': [ 'date', 'public' ],
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -57,9 +59,9 @@ class MetadataAdmin (admin.ModelAdmin):
|
||||||
class PublicationAdmin (MetadataAdmin):
|
class PublicationAdmin (MetadataAdmin):
|
||||||
fieldsets = copy.deepcopy(MetadataAdmin.fieldsets)
|
fieldsets = copy.deepcopy(MetadataAdmin.fieldsets)
|
||||||
|
|
||||||
list_display = ('id', 'title', 'date', 'public', 'enumerable', 'parent')
|
list_display = ('id', 'title', 'date', 'public', 'parent')
|
||||||
list_filter = ['date', 'public', 'parent', 'author']
|
list_filter = ['date', 'public', 'parent', 'author']
|
||||||
list_editable = ('public', 'enumerable')
|
list_editable = ('public',)
|
||||||
search_fields = ['title', 'content']
|
search_fields = ['title', 'content']
|
||||||
|
|
||||||
fieldsets[0][1]['fields'].insert(1, 'subtitle')
|
fieldsets[0][1]['fields'].insert(1, 'subtitle')
|
||||||
|
@ -77,22 +79,15 @@ class SoundAdmin (MetadataAdmin):
|
||||||
|
|
||||||
@admin.register(Stream)
|
@admin.register(Stream)
|
||||||
class StreamAdmin (SortableModelAdmin):
|
class StreamAdmin (SortableModelAdmin):
|
||||||
list_display = ('id', 'name', 'type', 'public', 'enumerable', 'priority')
|
list_display = ('id', 'title', 'type', 'public', 'priority')
|
||||||
list_editable = ('public', 'enumerable')
|
list_editable = ('public',)
|
||||||
sortable = "priority"
|
sortable = "priority"
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Article)
|
|
||||||
class ArticleAdmin (PublicationAdmin):
|
|
||||||
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
|
||||||
|
|
||||||
fieldsets[1][1]['fields'] += ['static_page']
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Program)
|
@admin.register(Program)
|
||||||
class ProgramAdmin (PublicationAdmin):
|
class ProgramAdmin (PublicationAdmin):
|
||||||
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
||||||
inlines = [ ScheduleInline ]
|
inlines = [ ScheduleInline ]
|
||||||
|
|
||||||
fieldsets[1][1]['fields'] += ['email', 'url']
|
fieldsets[1][1]['fields'] += ['email', 'url']
|
||||||
|
|
||||||
|
@ -100,7 +95,7 @@ class ProgramAdmin (PublicationAdmin):
|
||||||
@admin.register(Episode)
|
@admin.register(Episode)
|
||||||
class EpisodeAdmin (PublicationAdmin):
|
class EpisodeAdmin (PublicationAdmin):
|
||||||
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
||||||
list_filter = ['parent'] + PublicationAdmin.list_filter
|
list_filter = ['parent'] + PublicationAdmin.list_filter
|
||||||
|
|
||||||
fieldsets[0][1]['fields'] += ['sounds']
|
fieldsets[0][1]['fields'] += ['sounds']
|
||||||
|
|
||||||
|
|
|
@ -119,16 +119,10 @@ class Model:
|
||||||
elif options.get('tail'):
|
elif options.get('tail'):
|
||||||
items = items[-options.get('tail'):]
|
items = items[-options.get('tail'):]
|
||||||
|
|
||||||
if options.get('json'):
|
|
||||||
if options.get('fields'):
|
|
||||||
print(json.dumps(fields))
|
|
||||||
print(json.dumps(items, default = lambda x: str(x)))
|
|
||||||
return
|
|
||||||
|
|
||||||
if options.get('fields'):
|
if options.get('fields'):
|
||||||
print(' || '.join(fields))
|
print(json.dumps(fields))
|
||||||
for item in items:
|
print(json.dumps(items, default = lambda x: str(x)))
|
||||||
print(' || '.join(item))
|
return
|
||||||
|
|
||||||
|
|
||||||
def DateTime (string):
|
def DateTime (string):
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
# django
|
from django.db import models
|
||||||
from django.db import models
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.models import User
|
from django.template.defaultfilters import slugify
|
||||||
from django.template.defaultfilters import slugify
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils import timezone as tz
|
||||||
from django.utils import timezone as tz
|
from django.utils.html import strip_tags
|
||||||
from django.utils.html import strip_tags
|
|
||||||
|
|
||||||
# extensions
|
from taggit.managers import TaggableManager
|
||||||
from taggit.managers import TaggableManager
|
|
||||||
|
|
||||||
import programs.settings as settings
|
import programs.settings as settings
|
||||||
|
|
||||||
|
|
||||||
def date_or_default (date, date_only = False):
|
def date_or_default (date, date_only = False):
|
||||||
|
@ -29,28 +27,6 @@ def date_or_default (date, date_only = False):
|
||||||
return date
|
return date
|
||||||
|
|
||||||
|
|
||||||
#class Model (models.Model):
|
|
||||||
# @classmethod
|
|
||||||
# def type (cl):
|
|
||||||
# """
|
|
||||||
# Return a string with the type of the model (class name lowered)
|
|
||||||
# """
|
|
||||||
# name = cl.__name__.lower()
|
|
||||||
# return name
|
|
||||||
|
|
||||||
# @classmethod
|
|
||||||
# def name (cl, plural = False):
|
|
||||||
# """
|
|
||||||
# Return the name of the model using meta.verbose_name
|
|
||||||
# """
|
|
||||||
# if plural:
|
|
||||||
# return cl._meta.verbose_name_plural.title()
|
|
||||||
# return cl._meta.verbose_name.title()
|
|
||||||
#
|
|
||||||
# class Meta:
|
|
||||||
# abstract = True
|
|
||||||
|
|
||||||
|
|
||||||
class Metadata (models.Model):
|
class Metadata (models.Model):
|
||||||
"""
|
"""
|
||||||
meta is used to extend a model for future needs
|
meta is used to extend a model for future needs
|
||||||
|
@ -73,16 +49,14 @@ class Metadata (models.Model):
|
||||||
default = True,
|
default = True,
|
||||||
help_text = _('publication is public'),
|
help_text = _('publication is public'),
|
||||||
)
|
)
|
||||||
enumerable = models.BooleanField(
|
|
||||||
_('enumerable'),
|
|
||||||
default = True,
|
|
||||||
help_text = _('publication is listable'),
|
|
||||||
)
|
|
||||||
tags = TaggableManager(
|
tags = TaggableManager(
|
||||||
_('tags'),
|
_('tags'),
|
||||||
blank = True,
|
blank = True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_slug_name (self):
|
||||||
|
return slugify(self.title)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
@ -108,28 +82,6 @@ class Publication (Metadata):
|
||||||
help_text = _('comments are enabled on this publication'),
|
help_text = _('comments are enabled on this publication'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_slug_name (self):
|
|
||||||
return slugify(self.title)
|
|
||||||
|
|
||||||
def get_parents (self, order_by = "desc", include_fields = None):
|
|
||||||
"""
|
|
||||||
Return an array of the parents of the item.
|
|
||||||
If include_fields is an array of files to include.
|
|
||||||
"""
|
|
||||||
# TODO: fields included
|
|
||||||
# FIXME: parameter name + container
|
|
||||||
parents = [ self ]
|
|
||||||
while parents[-1].parent:
|
|
||||||
parent = parents[-1].parent
|
|
||||||
if parent not in parents:
|
|
||||||
# avoid cycles
|
|
||||||
parents.append(parent)
|
|
||||||
parents = parents[1:]
|
|
||||||
|
|
||||||
if order_by == 'desc':
|
|
||||||
return reversed(parents)
|
|
||||||
return parents
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _exclude_args (allow_unpublished = False, prefix = ''):
|
def _exclude_args (allow_unpublished = False, prefix = ''):
|
||||||
if allow_unpublished:
|
if allow_unpublished:
|
||||||
|
@ -181,7 +133,7 @@ class Track (models.Model):
|
||||||
)
|
)
|
||||||
tags = TaggableManager( blank = True )
|
tags = TaggableManager( blank = True )
|
||||||
# position can be used to specify a position in seconds for non-stop
|
# position can be used to specify a position in seconds for non-stop
|
||||||
# programs
|
# programs or a position in the playlist
|
||||||
position = models.SmallIntegerField(
|
position = models.SmallIntegerField(
|
||||||
default = 0,
|
default = 0,
|
||||||
help_text=_('position in the playlist'),
|
help_text=_('position in the playlist'),
|
||||||
|
@ -389,11 +341,11 @@ class Schedule (models.Model):
|
||||||
|
|
||||||
# others
|
# others
|
||||||
for date in dates:
|
for date in dates:
|
||||||
ep_date = date
|
first_date = date
|
||||||
if self.rerun:
|
if self.rerun:
|
||||||
ep_date -= self.date - self.rerun.date
|
first_date -= self.date - self.rerun.date
|
||||||
|
|
||||||
episode = Episode.objects.filter(date = date,
|
episode = Episode.objects.filter(date = first_date,
|
||||||
parent = self.parent)
|
parent = self.parent)
|
||||||
episode = episode[0] if episode.count() else None
|
episode = episode[0] if episode.count() else None
|
||||||
|
|
||||||
|
@ -418,7 +370,7 @@ class Schedule (models.Model):
|
||||||
|
|
||||||
class Diffusion (models.Model):
|
class Diffusion (models.Model):
|
||||||
Type = {
|
Type = {
|
||||||
'normal': 0x00, # simple diffusion (done/planed)
|
'default': 0x00, # simple diffusion (done/planed)
|
||||||
'unconfirmed': 0x01, # scheduled by the generator but not confirmed for diffusion
|
'unconfirmed': 0x01, # scheduled by the generator but not confirmed for diffusion
|
||||||
'cancel': 0x02, # cancellation happened; used to inform users
|
'cancel': 0x02, # cancellation happened; used to inform users
|
||||||
'restart': 0x03, # manual restart; used to remix/give up antenna
|
'restart': 0x03, # manual restart; used to remix/give up antenna
|
||||||
|
@ -472,9 +424,8 @@ class Stream (models.Model):
|
||||||
for key, value in Type.items():
|
for key, value in Type.items():
|
||||||
ugettext_lazy(key)
|
ugettext_lazy(key)
|
||||||
|
|
||||||
# FIXME: id as integer?
|
title = models.CharField(
|
||||||
name = models.CharField(
|
_('title'),
|
||||||
_('name'),
|
|
||||||
max_length = 32,
|
max_length = 32,
|
||||||
blank = True,
|
blank = True,
|
||||||
null = True,
|
null = True,
|
||||||
|
@ -483,8 +434,6 @@ class Stream (models.Model):
|
||||||
verbose_name = _('type'),
|
verbose_name = _('type'),
|
||||||
choices = [ (y, x) for x,y in Type.items() ],
|
choices = [ (y, x) for x,y in Type.items() ],
|
||||||
)
|
)
|
||||||
# FIXME unique value / suit's orderable
|
|
||||||
#
|
|
||||||
priority = models.SmallIntegerField(
|
priority = models.SmallIntegerField(
|
||||||
_('priority'),
|
_('priority'),
|
||||||
default = 0,
|
default = 0,
|
||||||
|
@ -493,12 +442,7 @@ class Stream (models.Model):
|
||||||
public = models.BooleanField(
|
public = models.BooleanField(
|
||||||
_('public'),
|
_('public'),
|
||||||
default = True,
|
default = True,
|
||||||
help_text = _('content is public'),
|
help_text = _('program list is public'),
|
||||||
)
|
|
||||||
enumerable = models.BooleanField(
|
|
||||||
_('enumerable'),
|
|
||||||
default = True,
|
|
||||||
help_text = _('publication is listable'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# get info for:
|
# get info for:
|
||||||
|
@ -509,39 +453,11 @@ class Stream (models.Model):
|
||||||
# - stream/pgm
|
# - stream/pgm
|
||||||
|
|
||||||
def __str__ (self):
|
def __str__ (self):
|
||||||
return self.name + ' / ' + str(self.priority)
|
return '#{} {}'.format(self.priority, self.title)
|
||||||
|
|
||||||
|
|
||||||
class Article (Publication):
|
|
||||||
# FIXME: move to website?
|
|
||||||
parent = models.ForeignKey(
|
|
||||||
'self',
|
|
||||||
verbose_name = _('parent'),
|
|
||||||
blank = True, null = True,
|
|
||||||
help_text = _('parent article'),
|
|
||||||
)
|
|
||||||
static_page = models.BooleanField(
|
|
||||||
_('static page'),
|
|
||||||
default = False,
|
|
||||||
)
|
|
||||||
focus = models.BooleanField(
|
|
||||||
_('article is focus'),
|
|
||||||
default = False,
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('Article')
|
|
||||||
verbose_name_plural = _('Articles')
|
|
||||||
|
|
||||||
|
|
||||||
class Program (Publication):
|
class Program (Publication):
|
||||||
parent = models.ForeignKey(
|
parent = models.ForeignKey(
|
||||||
Article,
|
|
||||||
verbose_name = _('parent'),
|
|
||||||
blank = True, null = True,
|
|
||||||
help_text = _('parent article'),
|
|
||||||
)
|
|
||||||
stream = models.ForeignKey(
|
|
||||||
Stream,
|
Stream,
|
||||||
verbose_name = _('stream'),
|
verbose_name = _('stream'),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
from django.shortcuts import render
|
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
|
||||||
from django.utils import timezone, dateformat
|
|
||||||
|
|
||||||
import programs.models as models
|
|
||||||
import programs.settings
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DiffusionList:
|
|
||||||
type = None
|
|
||||||
next = None
|
|
||||||
prev = None
|
|
||||||
at = None
|
|
||||||
count = None
|
|
||||||
|
|
||||||
|
|
||||||
def __init__ (self, **kwargs):
|
|
||||||
self.__dict__ = kwargs
|
|
||||||
if kwargs:
|
|
||||||
self.get_queryset()
|
|
||||||
|
|
||||||
|
|
||||||
def get_queryset (self):
|
|
||||||
diffusions = models.Diffusion.objects;
|
|
||||||
|
|
||||||
if self.next: diffusions = diffusions.filter( date_end__ge = timezone.now() )
|
|
||||||
elif self.prev: diffusions = diffusions.filter( date_end__le = timezone.now() )
|
|
||||||
else: diffusions = diffusions.all()
|
|
||||||
|
|
||||||
diffusions = diffusions.extra(order_by = ['date'])
|
|
||||||
if self.at: diffusions = diffusions[self.at:]
|
|
||||||
if self.count: diffusions = diffusions[:self.count]
|
|
||||||
|
|
||||||
self.diffusions = diffusions
|
|
||||||
|
|
||||||
|
|
||||||
def raw_string():
|
|
||||||
"""
|
|
||||||
Return a string with diffusions rendered as raw
|
|
||||||
"""
|
|
||||||
res = []
|
|
||||||
for diffusion in diffusions:
|
|
||||||
r = [ dateformat.format(diffusion.date, "Y/m/d H:i:s")
|
|
||||||
, str(diffusion.type)
|
|
||||||
, diffusion.parent.file.path
|
|
||||||
, diffusion.parent.file.url
|
|
||||||
]
|
|
||||||
|
|
||||||
res.push(' '.join(r))
|
|
||||||
|
|
||||||
return '\n'.join(res)
|
|
||||||
|
|
||||||
|
|
||||||
def json_string():
|
|
||||||
import json
|
|
||||||
|
|
||||||
res = []
|
|
||||||
for diffusion in diffusions:
|
|
||||||
r = {
|
|
||||||
'date': dateformat.format(diffusion.date, "Y/m/d H:i:s")
|
|
||||||
, 'date_end': dateformat.format(diffusion.date_end, "Y/m/d H:i:s")
|
|
||||||
, 'type': str(diffusion.type)
|
|
||||||
, 'file_path': diffusion.parent.file.path
|
|
||||||
, 'file_url': diffusion.parent.file.url
|
|
||||||
}
|
|
||||||
|
|
||||||
res.push(json.dumps(r))
|
|
||||||
|
|
||||||
return '\n'.join(res)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
0
website/__init__.py
Normal file
0
website/__init__.py
Normal file
15
website/admin.py
Normal file
15
website/admin.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import copy
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from programs.admin import PublicationAdmin
|
||||||
|
from website.models import *
|
||||||
|
|
||||||
|
@admin.register(Article)
|
||||||
|
class ArticleAdmin (PublicationAdmin):
|
||||||
|
fieldsets = copy.deepcopy(PublicationAdmin.fieldsets)
|
||||||
|
|
||||||
|
fieldsets[1][1]['fields'] += ['static_page']
|
||||||
|
|
||||||
|
|
||||||
|
|
35
website/models.py
Normal file
35
website/models.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
|
from programs.models import Publication
|
||||||
|
|
||||||
|
|
||||||
|
class Article (Publication):
|
||||||
|
parent = models.ForeignKey(
|
||||||
|
'self',
|
||||||
|
verbose_name = _('parent'),
|
||||||
|
blank = True, null = True,
|
||||||
|
help_text = _('parent article'),
|
||||||
|
)
|
||||||
|
static_page = models.BooleanField(
|
||||||
|
_('static page'),
|
||||||
|
default = False,
|
||||||
|
)
|
||||||
|
focus = models.BooleanField(
|
||||||
|
_('article is focus'),
|
||||||
|
default = False,
|
||||||
|
)
|
||||||
|
referring_tag = models.CharField(
|
||||||
|
_('referring tag'),
|
||||||
|
max_length = 32,
|
||||||
|
blank = True, null = True,
|
||||||
|
help_text = _('tag used by other to refers to this article'),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Article')
|
||||||
|
verbose_name_plural = _('Articles')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
3
website/tests.py
Normal file
3
website/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
83
website/utils.py
Normal file
83
website/utils.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils import timezone, dateformat
|
||||||
|
from programs.models import *
|
||||||
|
|
||||||
|
|
||||||
|
class ListQueries:
|
||||||
|
@staticmethod
|
||||||
|
def search (qs, q):
|
||||||
|
qs = qs.filter(tags__slug__in = re.compile(r'(\s|\+)+').split(q)) | \
|
||||||
|
qs.filter(title__icontains = q) | \
|
||||||
|
qs.filter(subtitle__icontains = q) | \
|
||||||
|
qs.filter(content__icontains = q)
|
||||||
|
qs.distinct()
|
||||||
|
return qs
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def thread (qs, q):
|
||||||
|
return qs.filter(parent = q)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def next (qs, q):
|
||||||
|
qs = qs.filter(date__gte = timezone.now())
|
||||||
|
if q:
|
||||||
|
qs = qs.filter(parent = q)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def prev (qs, q):
|
||||||
|
qs = qs.filter(date__lte = timezone.now())
|
||||||
|
if q:
|
||||||
|
qs = qs.filter(parent = q)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def date (qs, q):
|
||||||
|
if not q:
|
||||||
|
q = timezone.datetime.today()
|
||||||
|
if type(q) is str:
|
||||||
|
q = timezone.datetime.strptime(q, '%Y/%m/%d').date()
|
||||||
|
|
||||||
|
return qs.filter(date__startswith = q)
|
||||||
|
|
||||||
|
class Diffusion:
|
||||||
|
@staticmethod
|
||||||
|
def episode (qs, q):
|
||||||
|
return qs.filter(episode = q)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def program (qs, q):
|
||||||
|
return qs.filter(program = q)
|
||||||
|
|
||||||
|
class ListQuery:
|
||||||
|
model = None
|
||||||
|
qs = None
|
||||||
|
|
||||||
|
def __init__ (self, model, *kwargs):
|
||||||
|
self.model = model
|
||||||
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
|
def get_queryset (self, by, q):
|
||||||
|
qs = model.objects.all()
|
||||||
|
if model._meta.get_field_by_name('public'):
|
||||||
|
qs = qs.filter(public = True)
|
||||||
|
|
||||||
|
# run query set
|
||||||
|
queries = Queries.__dict__.get(self.model) or Queries
|
||||||
|
filter = queries.__dict__.get(by)
|
||||||
|
if filter:
|
||||||
|
qs = filter(qs, q)
|
||||||
|
|
||||||
|
# order
|
||||||
|
if self.sort == 'asc':
|
||||||
|
qs = qs.order_by('date', 'id')
|
||||||
|
else:
|
||||||
|
qs = qs.order_by('-date', '-id')
|
||||||
|
|
||||||
|
# exclude
|
||||||
|
qs = qs.exclude(id = exclude)
|
||||||
|
|
||||||
|
self.qs = qs
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
3
website/views.py
Normal file
3
website/views.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
Loading…
Reference in New Issue
Block a user