Add copyright header and a bit of pep8ification
[mediagoblin.git] / mediagoblin / db / sql / models.py
CommitLineData
fbad3a9f
E
1# GNU MediaGoblin -- federated, autonomous media hosting
2# Copyright (C) 2011,2012 MediaGoblin contributors. See AUTHORS.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
ccca0fbf
CAW
18import datetime
19
20from sqlalchemy.ext.declarative import declarative_base
21from sqlalchemy import (
22 Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
23 UniqueConstraint)
88e90f41 24from sqlalchemy.orm import relationship
02db7e0a
E
25from sqlalchemy.orm.collections import attribute_mapped_collection
26from sqlalchemy.ext.associationproxy import association_proxy
ccca0fbf 27
02db7e0a 28from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
7b194a79 29from mediagoblin.db.sql.base import GMGTableBase
f42e49c3 30from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
ccca0fbf 31
7b194a79
E
32
33Base = declarative_base(cls=GMGTableBase)
ccca0fbf
CAW
34
35
19ed039b
E
36class SimpleFieldAlias(object):
37 """An alias for any field"""
38 def __init__(self, fieldname):
39 self.fieldname = fieldname
40
41 def __get__(self, instance, cls):
42 return getattr(instance, self.fieldname)
43
44 def __set__(self, instance, val):
45 setattr(instance, self.fieldname, val)
46
47
f42e49c3 48class User(Base, UserMixin):
ccca0fbf
CAW
49 __tablename__ = "users"
50
51 id = Column(Integer, primary_key=True)
52 username = Column(Unicode, nullable=False, unique=True)
53 email = Column(Unicode, nullable=False)
54 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
55 pw_hash = Column(Unicode, nullable=False)
56 email_verified = Column(Boolean)
e365f980 57 status = Column(Unicode, default=u"needs_email_verification", nullable=False)
ccca0fbf
CAW
58 verification_key = Column(Unicode)
59 is_admin = Column(Boolean, default=False, nullable=False)
60 url = Column(Unicode)
fbad3a9f
E
61 bio = Column(UnicodeText) # ??
62 bio_html = Column(UnicodeText) # ??
ccca0fbf 63 fp_verification_key = Column(Unicode)
7c2c56a5 64 fp_token_expire = Column(DateTime)
ccca0fbf
CAW
65
66 ## TODO
67 # plugin data would be in a separate model
68
19ed039b
E
69 _id = SimpleFieldAlias("id")
70
ccca0fbf 71
f42e49c3 72class MediaEntry(Base, MediaEntryMixin):
ccca0fbf
CAW
73 __tablename__ = "media_entries"
74
75 id = Column(Integer, primary_key=True)
76 uploader = Column(Integer, ForeignKey('users.id'), nullable=False)
7c2c56a5 77 title = Column(Unicode, nullable=False)
ccca0fbf
CAW
78 slug = Column(Unicode, nullable=False)
79 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
fbad3a9f
E
80 description = Column(UnicodeText) # ??
81 description_html = Column(UnicodeText) # ??
ccca0fbf 82 media_type = Column(Unicode, nullable=False)
fbad3a9f
E
83 state = Column(Unicode, nullable=False) # or use sqlalchemy.types.Enum?
84
ccca0fbf
CAW
85 fail_error = Column(Unicode)
86 fail_metadata = Column(UnicodeText)
87
02db7e0a 88 queued_media_file = Column(PathTupleWithSlashes)
ccca0fbf
CAW
89
90 queued_task_id = Column(Unicode)
91
92 __table_args__ = (
93 UniqueConstraint('uploader', 'slug'),
94 {})
95
88e90f41
E
96 get_uploader = relationship(User)
97
02db7e0a
E
98 media_files_helper = relationship("MediaFile",
99 collection_class=attribute_mapped_collection("name"),
100 cascade="all, delete-orphan"
101 )
102 media_files = association_proxy('media_files_helper', 'file_path',
fbad3a9f 103 creator=lambda k, v: MediaFile(name=k, file_path=v)
02db7e0a
E
104 )
105
ccca0fbf 106 ## TODO
ccca0fbf
CAW
107 # media_data
108 # attachment_files
109 # fail_error
110
111
02db7e0a
E
112class MediaFile(Base):
113 __tablename__ = "mediafiles"
114
115 media_entry = Column(
116 Integer, ForeignKey(MediaEntry.id),
117 nullable=False, primary_key=True)
118 name = Column(Unicode, primary_key=True)
119 file_path = Column(PathTupleWithSlashes)
120
121 def __repr__(self):
122 return "<MediaFile %s: %r>" % (self.name, self.file_path)
123
124
ccca0fbf
CAW
125class Tag(Base):
126 __tablename__ = "tags"
127
128 id = Column(Integer, primary_key=True)
129 slug = Column(Unicode, nullable=False, unique=True)
130
131
132class MediaTag(Base):
133 __tablename__ = "media_tags"
134
135 id = Column(Integer, primary_key=True)
136 tag = Column(Integer, ForeignKey('tags.id'), nullable=False)
137 name = Column(Unicode)
138 media_entry = Column(
139 Integer, ForeignKey('media_entries.id'),
140 nullable=False)
141 # created = Column(DateTime, nullable=False, default=datetime.datetime.now)
142
143 __table_args__ = (
144 UniqueConstraint('tag', 'media_entry'),
145 {})
146
147
148class MediaComment(Base):
149 __tablename__ = "media_comments"
fbad3a9f 150
ccca0fbf
CAW
151 id = Column(Integer, primary_key=True)
152 media_entry = Column(
153 Integer, ForeignKey('media_entries.id'), nullable=False)
154 author = Column(Integer, ForeignKey('users.id'), nullable=False)
155 created = Column(DateTime, nullable=False, default=datetime.datetime.now)
156 content = Column(UnicodeText, nullable=False)
157 content_html = Column(UnicodeText)
e365f980 158
88e90f41
E
159 get_author = relationship(User)
160
e365f980
E
161
162def show_table_init():
163 from sqlalchemy import create_engine
164 engine = create_engine('sqlite:///:memory:', echo=True)
165
166 Base.metadata.create_all(engine)
167
168
169if __name__ == '__main__':
170 show_table_init()