aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/db
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin/db')
-rw-r--r--mediagoblin/db/migrations.py15
-rw-r--r--mediagoblin/db/mixin.py11
-rw-r--r--mediagoblin/db/models.py156
3 files changed, 173 insertions, 9 deletions
diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py
index 59aec4d2..88cda6f1 100644
--- a/mediagoblin/db/migrations.py
+++ b/mediagoblin/db/migrations.py
@@ -25,14 +25,14 @@ from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import and_
from migrate.changeset.constraint import UniqueConstraint
-
from mediagoblin.db.extratypes import JSONEncoded, MutationDict
from mediagoblin.db.migration_tools import (
RegisterMigration, inspect_table, replace_table_hack)
-from mediagoblin.db.models import (MediaEntry, Collection, MediaComment, User,
- Privilege)
+from mediagoblin.db.models import (MediaEntry, Collection, MediaComment, User,
+ Privilege)
from mediagoblin.db.extratypes import JSONEncoded, MutationDict
+
MIGRATIONS = {}
@@ -466,7 +466,6 @@ def create_oauth1_tables(db):
db.commit()
-
@RegisterMigration(15, MIGRATIONS)
def wants_notifications(db):
"""Add a wants_notifications field to User model"""
@@ -660,8 +659,8 @@ def create_moderation_tables(db):
# admin, an active user or an inactive user ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for admin_user in admin_users_ids:
admin_user_id = admin_user['id']
- for privilege_id in [admin_privilege_id, uploader_privilege_id,
- reporter_privilege_id, commenter_privilege_id,
+ for privilege_id in [admin_privilege_id, uploader_privilege_id,
+ reporter_privilege_id, commenter_privilege_id,
active_privilege_id]:
db.execute(user_privilege_assoc.insert().values(
core__privilege_id=admin_user_id,
@@ -669,7 +668,7 @@ def create_moderation_tables(db):
for active_user in active_users_ids:
active_user_id = active_user['id']
- for privilege_id in [uploader_privilege_id, reporter_privilege_id,
+ for privilege_id in [uploader_privilege_id, reporter_privilege_id,
commenter_privilege_id, active_privilege_id]:
db.execute(user_privilege_assoc.insert().values(
core__privilege_id=active_user_id,
@@ -677,7 +676,7 @@ def create_moderation_tables(db):
for inactive_user in inactive_users_ids:
inactive_user_id = inactive_user['id']
- for privilege_id in [uploader_privilege_id, reporter_privilege_id,
+ for privilege_id in [uploader_privilege_id, reporter_privilege_id,
commenter_privilege_id]:
db.execute(user_privilege_assoc.insert().values(
core__privilege_id=inactive_user_id,
diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py
index 3d96ba34..87f4383a 100644
--- a/mediagoblin/db/mixin.py
+++ b/mediagoblin/db/mixin.py
@@ -202,6 +202,17 @@ class MediaEntryMixin(GenerateSlugMixin):
thumb_url = mg_globals.app.staticdirector(manager[u'default_thumb'])
return thumb_url
+ @property
+ def original_url(self):
+ """ Returns the URL for the original image
+ will return self.thumb_url if original url doesn't exist"""
+ if u"original" not in self.media_files:
+ return self.thumb_url
+
+ return mg_globals.app.public_store.file_url(
+ self.media_files[u"original"]
+ )
+
@cached_property
def media_manager(self):
"""Returns the MEDIA_MANAGER of the media's media_type
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 4c9345fc..aaceb599 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -20,6 +20,7 @@ TODO: indexes on foreignkeys, where useful.
import logging
import datetime
+import base64
from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \
@@ -136,6 +137,48 @@ class User(Base, UserMixin):
return UserBan.query.get(self.id) is not None
+ def serialize(self, request):
+ user = {
+ "id": "acct:{0}@{1}".format(self.username, request.host),
+ "preferredUsername": self.username,
+ "displayName": "{0}@{1}".format(self.username, request.host),
+ "objectType": "person",
+ "pump_io": {
+ "shared": False,
+ "followed": False,
+ },
+ "links": {
+ "self": {
+ "href": request.urlgen(
+ "mediagoblin.federation.user.profile",
+ username=self.username,
+ qualified=True
+ ),
+ },
+ "activity-inbox": {
+ "href": request.urlgen(
+ "mediagoblin.federation.inbox",
+ username=self.username,
+ qualified=True
+ )
+ },
+ "activity-outbox": {
+ "href": request.urlgen(
+ "mediagoblin.federation.feed",
+ username=self.username,
+ qualified=True
+ )
+ },
+ },
+ }
+
+ if self.bio:
+ user.update({"summary": self.bio})
+ if self.url:
+ user.update({"url": self.url})
+
+ return user
+
class Client(Base):
"""
Model representing a client - Used for API Auth
@@ -201,7 +244,6 @@ class NonceTimestamp(Base):
nonce = Column(Unicode, nullable=False, primary_key=True)
timestamp = Column(DateTime, nullable=False, primary_key=True)
-
class MediaEntry(Base, MediaEntryMixin):
"""
TODO: Consider fetching the media_files using join
@@ -388,6 +430,87 @@ class MediaEntry(Base, MediaEntryMixin):
# pass through commit=False/True in kwargs
super(MediaEntry, self).delete(**kwargs)
+ @property
+ def objectType(self):
+ """ Converts media_type to pump-like type - don't use internally """
+ return self.media_type.split(".")[-1]
+
+ def serialize(self, request, show_comments=True):
+ """ Unserialize MediaEntry to object """
+ author = self.get_uploader
+ url = request.urlgen(
+ "mediagoblin.user_pages.media_home",
+ user=author.username,
+ media=self.slug,
+ qualified=True
+ )
+
+ context = {
+ "id": self.id,
+ "author": author.serialize(request),
+ "objectType": self.objectType,
+ "url": url,
+ "image": {
+ "url": request.host_url + self.thumb_url[1:],
+ },
+ "fullImage":{
+ "url": request.host_url + self.original_url[1:],
+ },
+ "published": self.created.isoformat(),
+ "updated": self.created.isoformat(),
+ "pump_io": {
+ "shared": False,
+ },
+ "links": {
+ "self": {
+ "href": request.urlgen(
+ "mediagoblin.federation.object",
+ objectType=self.objectType,
+ id=self.id,
+ qualified=True
+ ),
+ },
+
+ }
+ }
+
+ if self.title:
+ context["displayName"] = self.title
+
+ if self.description:
+ context["content"] = self.description
+
+ if self.license:
+ context["license"] = self.license
+
+ if show_comments:
+ comments = [comment.serialize(request) for comment in self.get_comments()]
+ total = len(comments)
+ context["replies"] = {
+ "totalItems": total,
+ "items": comments,
+ "url": request.urlgen(
+ "mediagoblin.federation.object.comments",
+ objectType=self.objectType,
+ id=self.id,
+ qualified=True
+ ),
+ }
+
+ return context
+
+ def unserialize(self, data):
+ """ Takes API objects and unserializes on existing MediaEntry """
+ if "displayName" in data:
+ self.title = data["displayName"]
+
+ if "content" in data:
+ self.description = data["content"]
+
+ if "license" in data:
+ self.license = data["license"]
+
+ return True
class FileKeynames(Base):
"""
@@ -534,6 +657,37 @@ class MediaComment(Base, MediaCommentMixin):
lazy="dynamic",
cascade="all, delete-orphan"))
+ def serialize(self, request):
+ """ Unserialize to python dictionary for API """
+ media = MediaEntry.query.filter_by(id=self.media_entry).first()
+ author = self.get_author
+ context = {
+ "id": self.id,
+ "objectType": "comment",
+ "content": self.content,
+ "inReplyTo": media.serialize(request, show_comments=False),
+ "author": author.serialize(request)
+ }
+
+ return context
+
+ def unserialize(self, data):
+ """ Takes API objects and unserializes on existing comment """
+ # Do initial checks to verify the object is correct
+ required_attributes = ["content", "inReplyTo"]
+ for attr in required_attributes:
+ if attr not in data:
+ return False
+
+ # Validate inReplyTo has ID
+ if "id" not in data["inReplyTo"]:
+ return False
+
+ self.media_entry = data["inReplyTo"]["id"]
+ self.content = data["content"]
+ return True
+
+
class Collection(Base, CollectionMixin):
"""An 'album' or 'set' of media by a user.