Merged changes with upstream
[mediagoblin.git] / mediagoblin / db / sql / models.py
CommitLineData
ccca0fbf
CAW
1import datetime
2
3from sqlalchemy.ext.declarative import declarative_base
4from sqlalchemy import (
5 Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
6 UniqueConstraint)
88e90f41 7from sqlalchemy.orm import relationship
02db7e0a
E
8from sqlalchemy.orm.collections import attribute_mapped_collection
9from sqlalchemy.ext.associationproxy import association_proxy
ccca0fbf 10
02db7e0a 11from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
7b194a79 12from mediagoblin.db.sql.base import GMGTableBase
f42e49c3 13from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
ccca0fbf 14
7b194a79
E
15
16Base = declarative_base(cls=GMGTableBase)
ccca0fbf
CAW
17
18
19ed039b
E
19class SimpleFieldAlias(object):
20 """An alias for any field"""
21 def __init__(self, fieldname):
22 self.fieldname = fieldname
23
24 def __get__(self, instance, cls):
25 return getattr(instance, self.fieldname)
26
27 def __set__(self, instance, val):
28 setattr(instance, self.fieldname, val)
29
30
f42e49c3 31class User(Base, UserMixin):
ccca0fbf
CAW
32 __tablename__ = "users"
33
34 id = Column(Integer, primary_key=True)
35 username = Column(Unicode, nullable=False, unique=True)
36 email = Column(Unicode, nullable=False)
37 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
38 pw_hash = Column(Unicode, nullable=False)
39 email_verified = Column(Boolean)
e365f980 40 status = Column(Unicode, default=u"needs_email_verification", nullable=False)
ccca0fbf
CAW
41 verification_key = Column(Unicode)
42 is_admin = Column(Boolean, default=False, nullable=False)
43 url = Column(Unicode)
44 bio = Column(UnicodeText) # ??
45 bio_html = Column(UnicodeText) # ??
46 fp_verification_key = Column(Unicode)
7c2c56a5 47 fp_token_expire = Column(DateTime)
ccca0fbf
CAW
48
49 ## TODO
50 # plugin data would be in a separate model
51
19ed039b
E
52 _id = SimpleFieldAlias("id")
53
ccca0fbf 54
f42e49c3 55class MediaEntry(Base, MediaEntryMixin):
ccca0fbf
CAW
56 __tablename__ = "media_entries"
57
58 id = Column(Integer, primary_key=True)
59 uploader = Column(Integer, ForeignKey('users.id'), nullable=False)
7c2c56a5 60 title = Column(Unicode, nullable=False)
ccca0fbf
CAW
61 slug = Column(Unicode, nullable=False)
62 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
63 description = Column(UnicodeText) # ??
64 description_html = Column(UnicodeText) # ??
65 media_type = Column(Unicode, nullable=False)
c6263400 66 state = Column(Unicode, nullable=False) # or use sqlalchemy.types.Enum?
ccca0fbf
CAW
67
68 fail_error = Column(Unicode)
69 fail_metadata = Column(UnicodeText)
70
02db7e0a 71 queued_media_file = Column(PathTupleWithSlashes)
ccca0fbf
CAW
72
73 queued_task_id = Column(Unicode)
74
75 __table_args__ = (
76 UniqueConstraint('uploader', 'slug'),
77 {})
78
88e90f41
E
79 get_uploader = relationship(User)
80
02db7e0a
E
81 media_files_helper = relationship("MediaFile",
82 collection_class=attribute_mapped_collection("name"),
83 cascade="all, delete-orphan"
84 )
85 media_files = association_proxy('media_files_helper', 'file_path',
86 creator=lambda k,v: MediaFile(name=k, file_path=v)
87 )
88
ccca0fbf 89 ## TODO
ccca0fbf
CAW
90 # media_data
91 # attachment_files
92 # fail_error
93
94
02db7e0a
E
95class MediaFile(Base):
96 __tablename__ = "mediafiles"
97
98 media_entry = Column(
99 Integer, ForeignKey(MediaEntry.id),
100 nullable=False, primary_key=True)
101 name = Column(Unicode, primary_key=True)
102 file_path = Column(PathTupleWithSlashes)
103
104 def __repr__(self):
105 return "<MediaFile %s: %r>" % (self.name, self.file_path)
106
107
ccca0fbf
CAW
108class Tag(Base):
109 __tablename__ = "tags"
110
111 id = Column(Integer, primary_key=True)
112 slug = Column(Unicode, nullable=False, unique=True)
113
114
115class MediaTag(Base):
116 __tablename__ = "media_tags"
117
118 id = Column(Integer, primary_key=True)
119 tag = Column(Integer, ForeignKey('tags.id'), nullable=False)
120 name = Column(Unicode)
121 media_entry = Column(
122 Integer, ForeignKey('media_entries.id'),
123 nullable=False)
124 # created = Column(DateTime, nullable=False, default=datetime.datetime.now)
125
126 __table_args__ = (
127 UniqueConstraint('tag', 'media_entry'),
128 {})
129
130
131class MediaComment(Base):
132 __tablename__ = "media_comments"
133
134 id = Column(Integer, primary_key=True)
135 media_entry = Column(
136 Integer, ForeignKey('media_entries.id'), nullable=False)
137 author = Column(Integer, ForeignKey('users.id'), nullable=False)
138 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
139 content = Column(UnicodeText, nullable=False)
140 content_html = Column(UnicodeText)
e365f980 141
88e90f41
E
142 get_author = relationship(User)
143
e365f980
E
144
145def show_table_init():
146 from sqlalchemy import create_engine
147 engine = create_engine('sqlite:///:memory:', echo=True)
148
149 Base.metadata.create_all(engine)
150
151
152if __name__ == '__main__':
153 show_table_init()