Source code for clld.db.models.source

from sqlalchemy import Column, Integer, String, Unicode, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declared_attr

from zope.interface import implementer

from clld.db.meta import Base, PolymorphicBaseMixin
from clld.db.versioned import Versioned
from clld import interfaces
from clld.lib import bibtex
from clld.lib import coins
from clld.web.util.htmllib import HTML

from . import (
    IdNameDescriptionMixin,
    DataMixin, HasDataMixin, FilesMixin, HasFilesMixin,
    Language, LanguageSource)

__all__ = ('Source', 'HasSourceMixin', 'HasSourceNotNullMixin')


class Source_data(Base, Versioned, DataMixin):
    pass


class Source_files(Base, Versioned, FilesMixin):
    pass


[docs]@implementer(interfaces.ISource) class Source(Base, PolymorphicBaseMixin, Versioned, IdNameDescriptionMixin, HasDataMixin, HasFilesMixin): """A bibliographic record, cited as source for some statement.""" glottolog_id = Column(String) google_book_search_id = Column(String) # # BibTeX fields: # bibtex_type = Column(bibtex.EntryType.db_type()) author = Column(Unicode) year = Column(Unicode) title = Column(Unicode) type = Column(Unicode) booktitle = Column(Unicode) editor = Column(Unicode) pages = Column(Unicode) edition = Column(Unicode) journal = Column(Unicode) school = Column(Unicode) address = Column(Unicode) url = Column(Unicode) note = Column(Unicode) number = Column(Unicode) series = Column(Unicode) volume = Column(Unicode) publisher = Column(Unicode) organization = Column(Unicode) chapter = Column(Unicode) howpublished = Column(Unicode) # typed information we might want to use for searching or sorting: year_int = Column(Integer) startpage_int = Column(Integer) pages_int = Column(Integer) languages = relationship( Language, backref='sources', secondary=LanguageSource.__table__) @property def gbs_identifier(self): if not self.jsondata.get('gbs'): return if not self.jsondata['gbs']['volumeInfo'].get('industryIdentifiers'): return id_ = None for identifier in self.jsondata['gbs']['volumeInfo']['industryIdentifiers']: # prefer ISBN_13 over ISBN_10 over anything else if identifier['type'] == 'ISBN_13': id_ = 'ISBN:' + identifier['identifier'] if identifier['type'] == 'ISBN_10' and not id_: id_ = 'ISBN:' + identifier['identifier'] if not id_: # grab the last one in the list (most probably the only one!) id_ = identifier['identifier'] return id_ def __bibtex__(self): return {} def bibtex(self, exclude={'gbs', 'glottolog_ref_id'}): kw = {k: v for k, v in self.jsondata.items() if k not in exclude} kw.update(self.__bibtex__()) return bibtex.Record.from_object(self, **kw) def coins(self, req): return HTML.span( ' ', **coins.ContextObject.from_bibtex( req.dataset.name, self.bibtex()).span_attrs() )
# # Several objects can be linked to sources, i.e. they can have references. # class HasSourceMixin(object): key = Column(Unicode) # the citation key, specific (and unique) within a contribution description = Column(Unicode) # e.g. page numbers. @declared_attr def source_pk(cls): # pragma: no cover return Column(Integer, ForeignKey('source.pk')) @declared_attr def source(cls): # pragma: no cover return relationship(Source, backref=cls.__name__.lower() + 's') class HasSourceNotNullMixin(HasSourceMixin): @declared_attr def source_pk(cls): return Column(Integer, ForeignKey('source.pk'), nullable=False) @declared_attr def source(cls): return relationship(Source, innerjoin=True, backref=cls.__name__.lower() + 's')