from __future__ import unicode_literals, print_function, division, absolute_import
from sqlalchemy import Column, Integer, Boolean, Date, ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship
from zope.interface import implementer
from clld.db.meta import Base, PolymorphicBaseMixin
from clld.db.versioned import Versioned
from clld import interfaces
from . import (
IdNameDescriptionMixin,
DataMixin, HasDataMixin, FilesMixin, HasFilesMixin,
HasSourceNotNullMixin, Contributor)
__all__ = ('Contribution', 'ContributionReference', 'ContributionContributor')
class Contribution_data(Base, Versioned, DataMixin):
pass
class Contribution_files(Base, Versioned, FilesMixin):
pass
[docs]@implementer(interfaces.IContribution)
class Contribution(Base,
PolymorphicBaseMixin,
Versioned,
IdNameDescriptionMixin,
HasDataMixin,
HasFilesMixin):
"""A set of data contributed within the same context by the same contributors."""
__table_args__ = (UniqueConstraint('name'),)
date = Column(Date)
@property
def primary_contributors(self):
return [assoc.contributor for assoc in
sorted(self.contributor_assocs,
key=lambda a: (a.ord, a.contributor.id)) if assoc.primary]
@property
def secondary_contributors(self):
return [assoc.contributor for assoc in
sorted(self.contributor_assocs,
key=lambda a: (a.ord, a.contributor.id)) if not assoc.primary]
def formatted_contributors(self):
contribs = [' and '.join(c.name for c in self.primary_contributors)]
if self.secondary_contributors:
contribs.append(' and '.join(c.name for c in self.secondary_contributors))
return ' with '.join(contribs)
class ContributionReference(Base, Versioned, HasSourceNotNullMixin):
"""Association table."""
__table_args__ = (
UniqueConstraint('contribution_pk', 'source_pk', 'description'),
)
contribution_pk = Column(Integer, ForeignKey('contribution.pk'), nullable=False)
contribution = relationship(Contribution, innerjoin=True, backref="references")
class ContributionContributor(Base, PolymorphicBaseMixin, Versioned):
"""Many-to-many association between contributors and contributions."""
__table_args__ = (UniqueConstraint('contribution_pk', 'contributor_pk'),)
contribution_pk = Column(Integer, ForeignKey('contribution.pk'), nullable=False)
contributor_pk = Column(Integer, ForeignKey('contributor.pk'), nullable=False)
# contributors are ordered.
ord = Column(Integer, default=1)
# we distinguish between primary and secondary (a.k.a. 'with ...') contributors.
primary = Column(Boolean, default=True)
contribution = relationship(Contribution, innerjoin=True, backref='contributor_assocs')
contributor = relationship(Contributor, innerjoin=True, lazy=False, backref='contribution_assocs')