class FileProperty(Entity): """Properties that can be bound to a file for off-line usage""" identifier = Field(String(20), index = True) value = Field(Unicode(255), nullable = False) file = ManyToOne('File')
class Language(Entity): """""" identifier = Field(String(20), index = True) label = Field(Unicode) titles = ManyToOne('LibraryTitle')
class Release(Entity): """Logically groups all files that belong to a certain release, such as parts of a movie, subtitles.""" last_edit = Field(Integer, default = lambda: int(time.time()), index = True) identifier = Field(String(100), index = True) movie = ManyToOne('Movie') status = ManyToOne('Status') quality = ManyToOne('Quality') files = ManyToMany('File') info = OneToMany('ReleaseInfo', cascade = 'all, delete-orphan') def to_dict(self, deep = None, exclude = None): if not exclude: exclude = [] if not deep: deep = {} orig_dict = super(Release, self).to_dict(deep = deep, exclude = exclude) new_info = {} for info in orig_dict.get('info', []): value = info['value'] try: value = int(info['value']) except: pass new_info[info['identifier']] = value orig_dict['info'] = new_info return orig_dict
class RenameHistory(Entity): """Remembers from where to where files have been moved.""" old = Field(Unicode(255)) new = Field(Unicode(255)) file = ManyToOne('File')
class SeasonLibrary(Library, DictMixin): using_options(inheritance='multi') season_number = Field(Integer, index=True) last_updated = Field(Integer, index=True) def getEpisodes(self): data = OrderedDict() for c in self.children: data[c.episode_number] = c return data # Read access episode by number: library[1][4] for season 1, episode 4 data = {} def __getitem__(self, key): if not self.data: self.setData() if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def get(self, key, failobj=None): if key not in self: return failobj return self[key] def keys(self): return self.data.keys() def setData(self): for c in self.children: self.data[c.episode_number] = c
class GeographicalData(Entity): id = Field(Integer,primary_key=True) google_place_id = Field(String(255)) lat = Field(String(20)) lon = Field(String(20)) using_options(tablename="GeoData") using_table_options(mysql_engine="InnoDB")
class Comment(Entity): id = Field(Integer,primary_key=True) content = Field(Text) user_id = Field(Integer) post_id = Field(Integer) using_options(tablename="Comment") using_table_options(mysql_engine="InnoDB")
class Status(Entity): """The status of a release, such as Downloaded, Deleted, Wanted etc""" identifier = Field(String(20), unique=True) label = Field(Unicode(20)) releases = OneToMany('Release')
class Notification(Entity): using_options(order_by = 'added') added = Field(Integer, default = lambda: int(time.time())) read = Field(Boolean, default = False) message = Field(Unicode(255)) data = Field(JsonType)
class LibraryInfo(Entity): """""" identifier = Field(String(50)) value = Field(Unicode(255), nullable=False) library = ManyToOne('Library')
class ReleaseInfo(Entity): """Properties that can be bound to a file for off-line usage""" identifier = Field(String(50), index = True) value = Field(Unicode(255), nullable = False) release = ManyToOne('Release')
class Organization( Party ): """An organization represents any internal or external organization. Organizations can include businesses and groups of individuals""" using_options( tablename = 'organization', inheritance = 'multi' ) name = Field( Unicode( 50 ), required = True, index = True ) logo = Field( camelot.types.Image( upload_to = 'organization-logo' ), deferred = True ) tax_id = Field( Unicode( 20 ) ) directors = OneToMany( 'DirectedDirector', inverse = 'established_from', cascade='all, delete, delete-orphan' ) employees = OneToMany( 'EmployerEmployee', inverse = 'established_from', cascade='all, delete, delete-orphan' ) suppliers = OneToMany( 'SupplierCustomer', inverse = 'established_to', cascade='all, delete, delete-orphan' ) customers = OneToMany( 'SupplierCustomer', inverse = 'established_from', cascade='all, delete, delete-orphan' ) shareholders = OneToMany( 'SharedShareholder', inverse = 'established_from', cascade='all, delete, delete-orphan' ) def __unicode__( self ): return self.name or '' @property def number_of_shares_issued( self ): return sum( ( shareholder.shares for shareholder in self.shareholders ), 0 ) class Admin( Party.Admin ): verbose_name = _( 'Organization' ) verbose_name_plural = _( 'Organizations' ) list_display = ['name', 'tax_id', 'contact_mechanisms_email', 'contact_mechanisms_phone'] form_display = TabForm( [( _('Basic'), Form( ['name', 'tax_id', 'addresses', 'contact_mechanisms'] ) ), ( _('Employment'), Form( ['employees'] ) ), ( _('Customers'), Form( ['customers'] ) ), ( _('Suppliers'), Form( ['suppliers'] ) ), ( _('Corporate'), Form( ['directors', 'shareholders', 'shares'] ) ), ( _('Branding'), Form( ['logo'] ) ), ( _('Status'), Form( ['status'] ) ), ] )
class Translation(Entity): using_options(tablename='translation') language = Field(camelot.types.Language, index=True) source = Field(Unicode(500), index=True) # value needs to be indexed as well, because when starting up we # want to load only the translations that have a value specified value = Field(Unicode(500), index=True) cid = Field(INT(), default=0, index=True) uid = Field(INT(), default=0, index=True) # cache, to prevent too much of the same sql queries _cache = dict() class Admin(EntityAdmin): verbose_name_plural = _('Translations') form_size = (700, 150) section = 'configuration' list_display = ['source', 'language', 'value', 'uid'] list_filter = ['language'] list_actions = [ExportAsPO()] field_attributes = {'language': {'default': default_language}} @classmethod def translate(cls, source, language): """Translate source to language, return None if no translation is found""" if source: key = (source, language) if key in cls._cache: return cls._cache[key] translation = cls.query.filter_by( source=unicode(source), language=language).filter(Translation.uid != 0).first() if translation: cls._cache[key] = translation.value return translation.value return None return '' @classmethod def translate_or_register(cls, source, language): """Translate source to language, if no translation is found, register the source as to be translated and return the source""" if source: source = unicode(source) translation = cls.translate(source, language) if not translation: if not cls.query.filter_by(source=source, language=language).first(): if (source, language) not in cls._cache: from elixir import session registered_translation = Translation(source=source, language=language) cls._cache[(source, language)] = source session.flush([registered_translation]) logger.debug('registed %s with id %s' % (source, registered_translation.id)) return source return translation return ''
class LibraryTitle(Entity): """""" title = Field(Unicode) default = Field(Boolean) language = OneToMany('Language') libraries = ManyToOne('Library')
class AuthenticationMechanism( Entity ): using_options( tablename = 'authentication_mechanism' ) last_login = Field( DateTime() ) is_active = Field( Boolean, default = True, index = True ) class Admin( EntityAdmin ): verbose_name = _('Authentication mechanism') list_display = ['last_login', 'is_active']
class ForgotPassword(Entity): id = Field(Integer,primary_key=True) uuid = Field(String(255)) timestamp = Field(DateTime) user_id = Field(Integer) used = Field(Boolean) using_options(tablename="ForgotPassword") using_table_options(mysql_engine="InnoDB")
class PartyAddressRoleType( Entity ): using_options( tablename = 'party_address_role_type' ) code = Field( Unicode( 10 ) ) description = Field( Unicode( 40 ) ) class Admin( EntityAdmin ): verbose_name = _('Address role type') list_display = ['code', 'description']
class Synchronized( Entity ): using_options( tablename = 'synchronized' ) database = Field( Unicode( 30 ), index = True ) tablename = Field( Unicode( 30 ), index = True ) primary_key = Field( Integer(), index = True ) last_update = Field( DateTime(), index = True, default = datetime.datetime.now, onupdate = datetime.datetime.now )
class FileType(Entity): """Types could be trailer, subtitle, movie, partial movie etc.""" identifier = Field(String(20), unique = True) type = Field(Unicode(20)) name = Field(Unicode(50), nullable = False) files = OneToMany('File')
class LibraryTitle(Entity): """""" using_options(order_by='-default') title = Field(Unicode) default = Field(Boolean) language = OneToMany('Language') libraries = ManyToOne('Library')
class History(Entity): """History of actions that are connected to a certain release, such as, renamed to, downloaded, deleted, download subtitles etc""" added = Field(Integer) message = Field(UnicodeText()) type = Field(Unicode(50)) release = ManyToOne('Release')
class ShowLibrary(Library, DictMixin): using_options(inheritance='multi') last_updated = Field(Integer, index=True) show_status = Field(String(10), index=True) # XXX: Maybe we should convert this to seconds? # airs_time u'21:00' airs_time = Field(Unicode, index=True) # airs_dayofweek = Field(Integer, index = True) # u'Monday': 1, # u'Tuesday': 2, # u'Wednesday': 4, # u'Thursday': 8, # u'Friday': 16, # u'Saturday': 32, # u'Sunday': 64, # u'Daily': 127, airs_dayofweek = Field(Integer, index=True) def getSeasons(self): data = OrderedDict() for c in self.children: data[c.season_number] = c return data def getEpisodes(self, season_number): data = OrderedDict() for c in self.children[season_number].children: data[c.episode_number] = c return data # Read access to season by number: library[1] for season 1 data = {} def __getitem__(self, key): if not self.data: self.setData() if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def get(self, key, failobj=None): if key not in self: return failobj return self[key] def keys(self): return self.data.keys() def setData(self): for c in self.children: self.data[c.season_number] = c
class ProfileType(Entity): """""" using_options(order_by = 'order') order = Field(Integer, default = 0, index = True) finish = Field(Boolean, default = True) wait_for = Field(Integer, default = 0) quality = ManyToOne('Quality') profile = ManyToOne('Profile')
class ProfileType(Entity): """""" using_options(order_by='order') order = Field(Integer) finish = Field(Boolean) wait_for = Field(Integer) quality = ManyToOne('Quality') profile = ManyToOne('Profile')
class PartyRelationship( Entity ): using_options( tablename = 'party_relationship' ) from_date = Field( Date(), default = datetime.date.today, required = True, index = True ) thru_date = Field( Date(), default = end_of_times, required = True, index = True ) comment = Field( camelot.types.RichText() ) is_synchronized( 'synchronized', lazy = True ) class Admin( EntityAdmin ): verbose_name = _('Relationship') verbose_name_plural = _('Relationships') list_display = ['established_from', 'established_to', 'from_date', 'thru_date']
class Profile(Entity): """""" using_options(order_by='order') label = Field(Unicode(50)) order = Field(Integer) core = Field(Boolean) hide = Field(Boolean) movie = OneToMany('Movie') types = OneToMany('ProfileType', cascade='all, delete-orphan')
class GeographicBoundary( Entity ): """The base class for Country and City""" using_options( tablename = 'geographic_boundary' ) code = Field( Unicode( 10 ) ) name = Field( Unicode( 40 ), required = True ) @ColumnProperty def full_name( self ): return self.code + ' ' + self.name def __unicode__( self ): return u'%s %s' % ( self.code, self.name )
class Quality(Entity): """Quality name of a release, DVD, 720p, DVD-Rip etc""" using_options(order_by = 'order') identifier = Field(String(20), unique = True) label = Field(Unicode(20)) order = Field(Integer, default = 0, index = True) size_min = Field(Integer) size_max = Field(Integer) releases = OneToMany('Release') profile_types = OneToMany('ProfileType')
class File(Entity): """File that belongs to a release.""" path = Field(Unicode(255), nullable=False, unique=True) part = Field(Integer, default=1) type = ManyToOne('FileType') properties = OneToMany('FileProperty') history = OneToMany('RenameHistory') movie = ManyToMany('Movie') release = ManyToMany('Release') library = ManyToMany('Library')
class Library(Entity): """""" year = Field(Integer) identifier = Field(String(20), index = True) plot = Field(UnicodeText) tagline = Field(UnicodeText(255)) info = Field(JsonType) status = ManyToOne('Status') movies = OneToMany('Movie', cascade = 'all, delete-orphan') titles = OneToMany('LibraryTitle', cascade = 'all, delete-orphan') files = ManyToMany('File', cascade = 'all, delete-orphan', single_parent = True)