2017-05-29 20:48:49 +00:00
2017-06-05 23:12:47 +00:00
import uuid
2017-05-29 20:48:49 +00:00
from datetime import timedelta
from django . contrib . auth . models import User
from django . contrib . sites . models import Site
from django . core . urlresolvers import reverse
from django . core . validators import MaxValueValidator , MinValueValidator
from django . db import models
2017-07-30 14:57:38 +00:00
from django . db . models import Q , Avg
2017-05-29 20:48:49 +00:00
from django . utils . translation import ugettext_lazy as _
from django . utils . translation import ugettext
from django . utils import timezone
2017-06-05 23:12:47 +00:00
from ponyconf . utils import PonyConfModel
2017-05-29 20:48:49 +00:00
from autoslug import AutoSlugField
from colorful . fields import RGBColorField
from django . contrib . auth . models import User
from django . contrib . sites . models import Site
from django . core . urlresolvers import reverse
from django . db import models
from django . utils . translation import ugettext_lazy as _
from django . utils . translation import ugettext
2017-06-05 23:12:47 +00:00
2017-05-29 20:48:49 +00:00
#from ponyconf.utils import PonyConfModel, enum_to_choices
2017-05-30 19:50:40 +00:00
class Conference ( models . Model ) :
site = models . OneToOneField ( Site , on_delete = models . CASCADE )
2017-07-30 18:11:13 +00:00
name = models . CharField ( blank = True , max_length = 100 , verbose_name = _ ( ' Conference name ' ) )
home = models . TextField ( blank = True , default = " " , verbose_name = _ ( ' Homepage (markdown) ' ) )
venue = models . TextField ( blank = True , default = " " , verbose_name = _ ( ' Venue information ' ) )
city = models . CharField ( max_length = 64 , blank = True , default = " " , verbose_name = _ ( ' City ' ) )
contact_email = models . CharField ( max_length = 100 , blank = True , verbose_name = _ ( ' Contact email ' ) )
staff = models . ManyToManyField ( User , blank = True , verbose_name = _ ( ' Staff members ' ) )
2017-06-06 22:06:32 +00:00
custom_css = models . TextField ( blank = True )
external_css_link = models . URLField ( blank = True )
2017-05-30 19:50:40 +00:00
#subscriptions_open = models.BooleanField(default=False) # workshop subscription
#def cfp_is_open(self):
# events = Event.objects.filter(site=self.site)
# return any(map(lambda x: x.is_open(), events))
2017-07-30 16:07:09 +00:00
@property
def opened_categories ( self ) :
now = timezone . now ( )
return TalkCategory . objects . filter ( site = self . site ) \
. filter ( Q ( opening_date__isnull = True ) | Q ( opening_date__lte = now ) ) \
. filter ( Q ( closing_date__isnull = True ) | Q ( closing_date__gte = now ) )
2017-05-30 19:50:40 +00:00
2017-06-05 23:12:47 +00:00
def from_email ( self ) :
return self . name + ' < ' + self . contact_email + ' > '
2017-05-30 19:50:40 +00:00
def __str__ ( self ) :
return str ( self . site )
2017-05-29 20:48:49 +00:00
class Participant ( PonyConfModel ) :
site = models . ForeignKey ( Site , on_delete = models . CASCADE )
2017-06-06 22:06:32 +00:00
name = models . CharField ( max_length = 128 , verbose_name = _ ( ' Your Name ' ) )
2017-05-29 20:48:49 +00:00
email = models . EmailField ( )
2017-06-06 22:06:32 +00:00
biography = models . TextField ( verbose_name = _ ( ' Biography ' ) )
2017-06-05 23:12:47 +00:00
token = models . UUIDField ( default = uuid . uuid4 , editable = False )
2017-05-29 20:48:49 +00:00
2017-06-06 22:06:32 +00:00
twitter = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' Twitter ' ) )
linkedin = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' LinkedIn ' ) )
github = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' Github ' ) )
website = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' Website ' ) )
facebook = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' Facebook ' ) )
mastodon = models . CharField ( max_length = 100 , blank = True , default = ' ' , verbose_name = _ ( ' Mastodon ' ) )
phone_number = models . CharField ( max_length = 64 , blank = True , default = ' ' , verbose_name = _ ( ' Phone number ' ) )
language = models . CharField ( max_length = 10 , blank = True )
2017-05-29 20:48:49 +00:00
notes = models . TextField ( default = ' ' , blank = True , verbose_name = _ ( " Notes " ) , help_text = _ ( ' This field is only visible by organizers. ' ) )
2017-06-06 22:06:32 +00:00
2017-05-29 20:48:49 +00:00
vip = models . BooleanField ( default = False )
class Meta :
# A User can participe only once to a Conference (= Site)
unique_together = ( ' site ' , ' email ' )
def __str__ ( self ) :
return str ( self . name )
#def get_absolute_url(self):
# return reverse('show-participant', kwargs={'username': self.user.username})
#def is_orga(self):
# return self.orga
#def is_staff(self):
# return self.is_orga() or self.topic_set.exists() or self.track_set.exists()
#@property
#def topic_set(self):
# return self.user.topic_set.filter(site=self.site)
#@property
#def track_set(self):
# return self.user.track_set.filter(site=self.site)
#@property
#def talk_set(self):
# return self.user.talk_set.filter(site=self.site)
2017-07-30 14:57:38 +00:00
@property
def accepted_talk_set ( self ) :
return self . talk_set . filter ( accepted = True )
@property
def pending_talk_set ( self ) :
return self . talk_set . filter ( accepted = None )
@property
def refused_talk_set ( self ) :
return self . talk_set . filter ( accepted = False )
2017-05-29 20:48:49 +00:00
#@property
#def not_refused_talk_set(self): # accepted + pending
# return self.talk_set.exclude(accepted=False)
class Track ( PonyConfModel ) :
site = models . ForeignKey ( Site , on_delete = models . CASCADE )
name = models . CharField ( max_length = 128 , verbose_name = _ ( ' Name ' ) )
slug = AutoSlugField ( populate_from = ' name ' )
description = models . TextField ( blank = True , verbose_name = _ ( ' Description ' ) )
#managers = models.ManyToManyField(User, blank=True, verbose_name=_('Managers'))
class Meta :
unique_together = ( ' site ' , ' name ' )
#def estimated_duration(self):
# return sum([talk.estimated_duration for talk in self.talk_set.all()])
def __str__ ( self ) :
return self . name
#def get_absolute_url(self):
# return reverse('list-talks') + '?track=%s' % self.slug
class TalkCategory ( models . Model ) : # type of talk (conf 30min, 1h, stand, …)
site = models . ForeignKey ( Site , on_delete = models . CASCADE )
name = models . CharField ( max_length = 64 )
duration = models . PositiveIntegerField ( default = 0 , verbose_name = _ ( ' Default duration (min) ' ) )
color = RGBColorField ( default = ' #ffffff ' , verbose_name = _ ( " Color on program " ) )
label = models . CharField ( max_length = 64 , verbose_name = _ ( " Label on program " ) , blank = True , default = " " )
opening_date = models . DateTimeField ( null = True , blank = True , default = None )
closing_date = models . DateTimeField ( null = True , blank = True , default = None )
def is_open ( self ) :
now = timezone . now ( )
if self . opening_date and now < self . opening_date :
return False
if self . closing_date and now > self . closing_date :
return False
return True
class Meta :
unique_together = ( ' site ' , ' name ' )
ordering = ( ' pk ' , )
2017-06-05 23:12:47 +00:00
verbose_name = " category "
verbose_name_plural = " categories "
2017-05-29 20:48:49 +00:00
def __str__ ( self ) :
return ugettext ( self . name )
#def get_absolute_url(self):
# return reverse('list-talks') + '?kind=%d' % self.pk
#class Attendee(PonyConfModel):
#
# user = models.ForeignKey(User, null=True)
# name = models.CharField(max_length=64, blank=True, default="")
# email = models.EmailField(blank=True, default="")
#
# def get_name(self):
# if self.user:
# return str(self.user.profile)
# else:
# return self.name
# get_name.short_description = _('Name')
#
# def get_email(self):
# if self.user:
# return self.user.email
# else:
# return self.email
# get_email.short_description = _('Email')
#
# def __str__(self):
# return self.get_name()
#def talk_materials_destination(talk, filename):
# return join(talk.site.name, talk.slug, filename)
class Talk ( PonyConfModel ) :
2017-06-05 23:12:47 +00:00
LICENCES = (
( ' CC-Zero CC-BY ' , ' CC-Zero CC-BY ' ) ,
( ' CC-BY-SA ' , ' CC-BY-SA ' ) ,
( ' CC-BY-ND ' , ' CC-BY-ND ' ) ,
( ' CC-BY-NC ' , ' CC-BY-NC ' ) ,
( ' CC-BY-NC-SA ' , ' CC-BY-NC-SA ' ) ,
( ' CC-BY-NC-ND ' , ' CC-BY-NC-ND ' ) ,
)
2017-05-29 20:48:49 +00:00
site = models . ForeignKey ( Site , on_delete = models . CASCADE )
#proposer = models.ForeignKey(User, related_name='+')
speakers = models . ManyToManyField ( Participant , verbose_name = _ ( ' Speakers ' ) )
2017-06-05 23:12:47 +00:00
title = models . CharField ( max_length = 128 , verbose_name = _ ( ' Talk Title ' ) )
2017-05-29 20:48:49 +00:00
slug = AutoSlugField ( populate_from = ' title ' , unique = True )
#abstract = models.CharField(max_length=255, blank=True, verbose_name=_('Abstract'))
2017-06-06 22:06:32 +00:00
description = models . TextField ( verbose_name = _ ( ' Description of your talk ' ) )
2017-05-29 20:48:49 +00:00
track = models . ForeignKey ( Track , blank = True , null = True , verbose_name = _ ( ' Track ' ) )
2017-06-05 23:12:47 +00:00
notes = models . TextField ( blank = True , verbose_name = _ ( ' Message to organizers ' ) , help_text = _ ( ' If you have any constraint or if you have anything that may help you to select your talk, like a video or slides of your talk, please write it down here ' ) )
2017-06-06 22:06:32 +00:00
category = models . ForeignKey ( TalkCategory , verbose_name = _ ( ' Talk Category ' ) )
2017-05-29 20:48:49 +00:00
videotaped = models . BooleanField ( _ ( " I ' m ok to be recorded on video " ) , default = True )
2017-06-05 23:12:47 +00:00
video_licence = models . CharField ( choices = LICENCES , default = ' CC-BY-SA ' , max_length = 10 , verbose_name = _ ( " Video licence " ) )
2017-05-29 20:48:49 +00:00
sound = models . BooleanField ( _ ( " I need sound " ) , default = False )
accepted = models . NullBooleanField ( default = None )
#start_date = models.DateTimeField(null=True, blank=True, default=None)
duration = models . PositiveIntegerField ( default = 0 , verbose_name = _ ( ' Duration (min) ' ) )
#room = models.ForeignKey(Room, blank=True, null=True, default=None)
plenary = models . BooleanField ( default = False )
#materials = models.FileField(null=True, upload_to=talk_materials_destination, verbose_name=_('Materials'),
# help_text=_('You can use this field to share some materials related to your intervention.'))
2017-06-05 23:12:47 +00:00
token = models . UUIDField ( default = uuid . uuid4 , editable = False )
2017-05-29 20:48:49 +00:00
class Meta :
ordering = ( ' title ' , )
def __str__ ( self ) :
return self . title
def get_speakers_str ( self ) :
speakers = [ str ( Participant . objects . get ( site = self . site , user = speaker ) ) for speaker in self . speakers . all ( ) ]
if len ( speakers ) == 0 :
return ' superman '
elif len ( speakers ) == 1 :
return speakers [ 0 ]
else :
return ' , ' . join ( speakers [ : - 1 ] ) + ' & ' + str ( speakers [ - 1 ] )
@property
def estimated_duration ( self ) :
return self . duration or self . category . duration
2017-07-30 14:57:38 +00:00
def get_absolute_url ( self ) :
return reverse ( ' talk-details ' , kwargs = { ' talk_id ' : self . token } )
2017-05-29 20:48:49 +00:00
def score ( self ) :
2017-07-30 14:57:38 +00:00
return self . vote_set . aggregate ( Avg ( ' vote ' ) ) [ ' vote__avg ' ] or 0
2017-05-29 20:48:49 +00:00
@property
def end_date ( self ) :
if self . estimated_duration :
return self . start_date + timedelta ( minutes = self . estimated_duration )
else :
return None
#@property
#def dtstart(self):
# return self.start_date.strftime('%Y%m%dT%H%M%SZ')
#@property
#def dtend(self):
# return self.end_date.strftime('%Y%m%dT%H%M%SZ')
#@property
#def materials_name(self):
# return basename(self.materials.name)
class Meta :
ordering = ( ' category__id ' , ' title ' , )
class Vote ( PonyConfModel ) :
talk = models . ForeignKey ( Talk )
user = models . ForeignKey ( User )
vote = models . IntegerField ( validators = [ MinValueValidator ( - 2 ) , MaxValueValidator ( 2 ) ] , default = 0 )
class Meta :
unique_together = ( ' talk ' , ' user ' )
def __str__ ( self ) :
return " %+i by %s for %s " % ( self . vote , self . user , self . talk )
#def get_absolute_url(self):
# return self.talk.get_absolute_url()