Collection changes and migration for federation
authorJessica Tallon <tsyesika@tsyesika.se>
Thu, 17 Sep 2015 11:47:56 +0000 (13:47 +0200)
committerJessica Tallon <tsyesika@tsyesika.se>
Wed, 7 Oct 2015 12:40:44 +0000 (14:40 +0200)
- Adds a "type" column to the Collection object and allows the
CollectionItem model to contain any object.
- Changes "items" to "num_items" as per TODO
- Renames "uploader", "creator" and "user" to a common "actor" in most places

48 files changed:
mediagoblin/api/views.py
mediagoblin/db/__init__.py
mediagoblin/db/migrations.py
mediagoblin/db/mixin.py
mediagoblin/db/models.py
mediagoblin/db/util.py
mediagoblin/decorators.py
mediagoblin/edit/lib.py
mediagoblin/edit/views.py
mediagoblin/gmg_commands/batchaddmedia.py
mediagoblin/listings/views.py
mediagoblin/media_types/blog/views.py
mediagoblin/notifications/__init__.py
mediagoblin/notifications/tools.py
mediagoblin/plugins/api/tools.py
mediagoblin/plugins/archivalook/templates/archivalook/feature_media_sidebar.html
mediagoblin/plugins/archivalook/tools.py
mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html
mediagoblin/plugins/piwigo/views.py
mediagoblin/submit/lib.py
mediagoblin/templates/mediagoblin/edit/attachments.html
mediagoblin/templates/mediagoblin/edit/edit.html
mediagoblin/templates/mediagoblin/edit/edit_collection.html
mediagoblin/templates/mediagoblin/fragments/header_notifications.html
mediagoblin/templates/mediagoblin/moderation/media_panel.html
mediagoblin/templates/mediagoblin/moderation/report.html
mediagoblin/templates/mediagoblin/user_pages/blog_media.html
mediagoblin/templates/mediagoblin/user_pages/collection.html
mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html
mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html
mediagoblin/templates/mediagoblin/user_pages/media.html
mediagoblin/templates/mediagoblin/user_pages/media_collect.html
mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html
mediagoblin/templates/mediagoblin/user_pages/report.html
mediagoblin/templates/mediagoblin/utils/collection_gallery.html
mediagoblin/templates/mediagoblin/utils/collections.html
mediagoblin/templates/mediagoblin/utils/comment-subscription.html
mediagoblin/templates/mediagoblin/utils/report.html
mediagoblin/templates/mediagoblin/utils/tags.html
mediagoblin/tests/test_api.py
mediagoblin/tests/test_misc.py
mediagoblin/tests/test_modelmethods.py
mediagoblin/tests/test_moderation.py
mediagoblin/tests/test_notifications.py
mediagoblin/tests/test_reporting.py
mediagoblin/tests/tools.py
mediagoblin/user_pages/lib.py
mediagoblin/user_pages/views.py

index 9c2876c2217f63d447e924b40e299457b42fe1db..d3eaacc9a658e78678c3fef9a011ed160548c4c8 100644 (file)
@@ -268,7 +268,7 @@ def feed_endpoint(request, outbox=None):
                         status=403
                     )
 
-                comment = MediaComment(author=request.user.id)
+                comment = MediaComment(actor=request.user.id)
                 comment.unserialize(data["object"], request)
                 comment.save()
 
@@ -299,7 +299,7 @@ def feed_endpoint(request, outbox=None):
                         status=404
                     )
 
-                if media.uploader != request.user.id:
+                if media.actor != request.user.id:
                     return json_error(
                         "Privilege 'commenter' required to comment.",
                         status=403
@@ -366,7 +366,7 @@ def feed_endpoint(request, outbox=None):
 
                 # Check that the person trying to update the comment is
                 # the author of the comment.
-                if comment.author != request.user.id:
+                if comment.actor != request.user.id:
                     return json_error(
                         "Only author of comment is able to update comment.",
                         status=403
@@ -399,7 +399,7 @@ def feed_endpoint(request, outbox=None):
 
                 # Check that the person trying to update the comment is
                 # the author of the comment.
-                if image.uploader != request.user.id:
+                if image.actor != request.user.id:
                     return json_error(
                         "Only uploader of image is able to update image.",
                         status=403
@@ -463,7 +463,7 @@ def feed_endpoint(request, outbox=None):
                 # Find the comment asked for
                 comment = MediaComment.query.filter_by(
                     id=obj_id,
-                    author=request.user.id
+                    actor=request.user.id
                 ).first()
 
                 if comment is None:
@@ -492,7 +492,7 @@ def feed_endpoint(request, outbox=None):
                 # Find the image
                 entry = MediaEntry.query.filter_by(
                     id=obj_id,
-                    uploader=request.user.id
+                    actor=request.user.id
                 ).first()
 
                 if entry is None:
@@ -792,5 +792,3 @@ def whoami(request):
     )
 
     return redirect(request, location=profile)
-
-
index 719b56e7c231319f077d06ed4a036bc571d41fc8..621845bae0b12696d5a3cd09ca53cc22b4bfec22 100644 (file)
@@ -13,4 +13,3 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
index ce7174da987025e75413c5b0fc5cdd22ddcb92fa..4e9d3a2a99045587a4f122992de909aa035d6bf9 100644 (file)
@@ -1676,3 +1676,147 @@ def create_oauth1_dummies(db):
 
     # Commit the changes
     db.commit()
+
+@RegisterMigration(37, MIGRATIONS)
+def federation_collection_schema(db):
+    """ Converts the Collection and CollectionItem """
+    metadata = MetaData(bind=db.bind)
+    collection_table = inspect_table(metadata, "core__collections")
+    collection_items_table = inspect_table(metadata, "core__collection_items")
+    media_entry_table = inspect_table(metadata, "core__media_entries")
+    gmr_table = inspect_table(metadata, "core__generic_model_reference")
+
+    ##
+    # Collection Table
+    ##
+
+    # Add the fields onto the Collection model, we need to set these as
+    # not null to avoid DB integreity errors. We will add the not null
+    # constraint later.
+    updated_column = Column(
+        "updated",
+        DateTime,
+        default=datetime.datetime.utcnow
+    )
+    updated_column.create(collection_table)
+
+    type_column = Column(
+        "type",
+        Unicode,
+    )
+    type_column.create(collection_table)
+
+    db.commit()
+
+    # Iterate over the items and set the updated and type fields
+    for collection in db.execute(collection_table.select()):
+        db.execute(collection_table.update().where(
+            collection_table.c.id==collection.id
+        ).values(
+            updated=collection.created,
+            type="core-user-defined"
+        ))
+
+    db.commit()
+
+    # Add the not null constraint onto the fields
+    updated_column = collection_table.columns["updated"]
+    updated_column.alter(nullable=False)
+
+    type_column = collection_table.columns["type"]
+    type_column.alter(nullable=False)
+
+    db.commit()
+
+    # Rename the "items" to "num_items" as per the TODO
+    num_items_field = collection_table.columns["items"]
+    num_items_field.alter(name="num_items")
+    db.commit()
+
+    ##
+    # CollectionItem
+    ##
+    # Adding the object ID column, this again will have not null added later.
+    object_id = Column(
+        "object_id",
+        Integer,
+        ForeignKey(GenericModelReference_V0.id),
+    )
+    object_id.create(
+        collection_items_table,
+    )
+
+    db.commit()
+
+    # Iterate through and convert the Media reference to object_id
+    for item in db.execute(collection_items_table.select()):
+        # Check if there is a GMR for the MediaEntry
+        object_gmr = db.execute(gmr_table.select(
+            and_(
+                gmr_table.c.obj_pk == item.media_entry,
+                gmr_table.c.model_type == "core__media_entries"
+            )
+        )).first()
+
+        if object_gmr:
+            object_gmr = object_gmr[0]
+        else:
+            # Create a GenericModelReference
+            object_gmr = db.execute(gmr_table.insert().values(
+                obj_pk=item.media_entry,
+                model_type="core__media_entries"
+            )).inserted_primary_key[0]
+
+        # Now set the object_id column to the ID of the GMR
+        db.execute(collection_items_table.update().where(
+            collection_items_table.c.id==item.id
+        ).values(
+            object_id=object_gmr
+        ))
+
+    db.commit()
+
+    # Add not null constraint
+    object_id = collection_items_table.columns["object_id"]
+    object_id.alter(nullable=False)
+
+    db.commit()
+
+    # Now remove the old media_entry column
+    media_entry_column = collection_items_table.columns["media_entry"]
+    media_entry_column.drop()
+
+    db.commit()
+
+@RegisterMigration(38, MIGRATIONS)
+def federation_actor(db):
+    """ Renames refereces to the user to actor """
+    metadata = MetaData(bind=db.bind)
+
+    # RequestToken: user -> actor
+    request_token_table = inspect_table(metadata, "core__request_tokens")
+    rt_user_column = request_token_table.columns["user"]
+    rt_user_column.alter(name="actor")
+
+    # AccessToken: user -> actor
+    access_token_table = inspect_table(metadata, "core__access_tokens")
+    at_user_column = access_token_table.columns["user"]
+    at_user_column.alter(name="actor")
+
+    # MediaEntry: uploader -> actor
+    media_entry_table = inspect_table(metadata, "core__media_entries")
+    me_user_column = media_entry_table.columns["uploader"]
+    me_user_column.alter(name="actor")
+
+    # MediaComment: author -> actor
+    media_comment_table = inspect_table(metadata, "core__media_comments")
+    mc_user_column = media_comment_table.columns["author"]
+    mc_user_column.alter(name="actor")
+
+    # Collection: creator -> actor
+    collection_table = inspect_table(metadata, "core__collections")
+    mc_user_column = collection_table.columns["creator"]
+    mc_user_column.alter(name="actor")
+
+    # commit changes to db.
+    db.commit()
index b954ab907b2a623a3ee7ea49dc77301aac8e9964..7960061e72801ab8f17d4d2cd5b9e6872d3eefa9 100644 (file)
@@ -134,7 +134,7 @@ class MediaEntryMixin(GenerateSlugMixin):
         # (db.models -> db.mixin -> db.util -> db.models)
         from mediagoblin.db.util import check_media_slug_used
 
-        return check_media_slug_used(self.uploader, slug, self.id)
+        return check_media_slug_used(self.actor, slug, self.id)
 
     @property
     def object_type(self):
@@ -188,7 +188,7 @@ class MediaEntryMixin(GenerateSlugMixin):
 
         Use a slug if we have one, else use our 'id'.
         """
-        uploader = self.get_uploader
+        uploader = self.get_actor
 
         return urlgen(
             'mediagoblin.user_pages.media_home',
@@ -338,17 +338,17 @@ class MediaCommentMixin(object):
         return cleaned_markdown_conversion(self.content)
 
     def __unicode__(self):
-        return u'<{klass} #{id} {author} "{comment}">'.format(
+        return u'<{klass} #{id} {actor} "{comment}">'.format(
             klass=self.__class__.__name__,
             id=self.id,
-            author=self.get_author,
+            actor=self.get_actor,
             comment=self.content)
 
     def __repr__(self):
-        return '<{klass} #{id} {author} "{comment}">'.format(
+        return '<{klass} #{id} {actor} "{comment}">'.format(
             klass=self.__class__.__name__,
             id=self.id,
-            author=self.get_author,
+            actor=self.get_actor,
             comment=self.content)
 
 
@@ -360,7 +360,7 @@ class CollectionMixin(GenerateSlugMixin):
         # (db.models -> db.mixin -> db.util -> db.models)
         from mediagoblin.db.util import check_collection_slug_used
 
-        return check_collection_slug_used(self.creator, slug, self.id)
+        return check_collection_slug_used(self.actor, slug, self.id)
 
     @property
     def description_html(self):
@@ -380,7 +380,7 @@ class CollectionMixin(GenerateSlugMixin):
 
         Use a slug if we have one, else use our 'id'.
         """
-        creator = self.get_creator
+        creator = self.get_actor
 
         return urlgen(
             'mediagoblin.user_pages.user_collection',
index 8c8e42e5456704424b8c921b5e457bd5186970e7..9f4a144cfa887fd77d2b7677e33afc6314f36b85 100644 (file)
@@ -29,6 +29,7 @@ from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
 from sqlalchemy.orm import relationship, backref, with_polymorphic, validates, \
         class_mapper
 from sqlalchemy.orm.collections import attribute_mapped_collection
+from sqlalchemy.sql import and_
 from sqlalchemy.sql.expression import desc
 from sqlalchemy.ext.associationproxy import association_proxy
 from sqlalchemy.util import memoized_property
@@ -257,7 +258,7 @@ class User(Base, UserMixin):
         """Deletes a User and all related entries/comments/files/..."""
         # Collections get deleted by relationships.
 
-        media_entries = MediaEntry.query.filter(MediaEntry.uploader == self.id)
+        media_entries = MediaEntry.query.filter(MediaEntry.actor == self.id)
         for media in media_entries:
             # TODO: Make sure that "MediaEntry.delete()" also deletes
             # all related files/Comments
@@ -455,7 +456,7 @@ class RequestToken(Base):
     token = Column(Unicode, primary_key=True)
     secret = Column(Unicode, nullable=False)
     client = Column(Unicode, ForeignKey(Client.id))
-    user = Column(Integer, ForeignKey(User.id), nullable=True)
+    actor = Column(Integer, ForeignKey(User.id), nullable=True)
     used = Column(Boolean, default=False)
     authenticated = Column(Boolean, default=False)
     verifier = Column(Unicode, nullable=True)
@@ -473,7 +474,7 @@ class AccessToken(Base):
 
     token = Column(Unicode, nullable=False, primary_key=True)
     secret = Column(Unicode, nullable=False)
-    user = Column(Integer, ForeignKey(User.id))
+    actor = Column(Integer, ForeignKey(User.id))
     request_token = Column(Unicode, ForeignKey(RequestToken.token))
     created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
     updated = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
@@ -500,7 +501,7 @@ class MediaEntry(Base, MediaEntryMixin):
     public_id = Column(Unicode, unique=True, nullable=True)
     remote = Column(Boolean, default=False)
 
-    uploader = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
+    actor = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
     title = Column(Unicode, nullable=False)
     slug = Column(Unicode)
     description = Column(UnicodeText) # ??
@@ -526,10 +527,10 @@ class MediaEntry(Base, MediaEntryMixin):
     queued_task_id = Column(Unicode)
 
     __table_args__ = (
-        UniqueConstraint('uploader', 'slug'),
+        UniqueConstraint('actor', 'slug'),
         {})
 
-    get_uploader = relationship(User)
+    get_actor = relationship(User)
 
     media_files_helper = relationship("MediaFile",
         collection_class=attribute_mapped_collection("name"),
@@ -555,16 +556,24 @@ class MediaEntry(Base, MediaEntryMixin):
         creator=lambda v: MediaTag(name=v["name"], slug=v["slug"])
         )
 
-    collections_helper = relationship("CollectionItem",
-        cascade="all, delete-orphan"
-        )
-    collections = association_proxy("collections_helper", "in_collection")
     media_metadata = Column(MutationDict.as_mutable(JSONEncoded),
         default=MutationDict())
 
     ## TODO
     # fail_error
 
+    @property
+    def collections(self):
+        """ Get any collections that this MediaEntry is in """
+        return list(Collection.query.join(Collection.collection_items).join(
+            CollectionItem.object_helper
+        ).filter(
+            and_(
+                GenericModelReference.model_type == self.__tablename__,
+                GenericModelReference.obj_pk == self.id
+            )
+        ))
+
     def get_comments(self, ascending=False):
         order_col = MediaComment.created
         if not ascending:
@@ -574,7 +583,7 @@ class MediaEntry(Base, MediaEntryMixin):
     def url_to_prev(self, urlgen):
         """get the next 'newer' entry by this user"""
         media = MediaEntry.query.filter(
-            (MediaEntry.uploader == self.uploader)
+            (MediaEntry.actor == self.actor)
             & (MediaEntry.state == u'processed')
             & (MediaEntry.id > self.id)).order_by(MediaEntry.id).first()
 
@@ -584,7 +593,7 @@ class MediaEntry(Base, MediaEntryMixin):
     def url_to_next(self, urlgen):
         """get the next 'older' entry by this user"""
         media = MediaEntry.query.filter(
-            (MediaEntry.uploader == self.uploader)
+            (MediaEntry.actor == self.actor)
             & (MediaEntry.state == u'processed')
             & (MediaEntry.id < self.id)).order_by(desc(MediaEntry.id)).first()
 
@@ -675,7 +684,7 @@ class MediaEntry(Base, MediaEntryMixin):
         except OSError as error:
             # Returns list of files we failed to delete
             _log.error('No such files from the user "{1}" to delete: '
-                       '{0}'.format(str(error), self.get_uploader))
+                       '{0}'.format(str(error), self.get_actor))
         _log.info('Deleted Media entry id "{0}"'.format(self.id))
         # Related MediaTag's are automatically cleaned, but we might
         # want to clean out unused Tag's too.
@@ -689,7 +698,7 @@ class MediaEntry(Base, MediaEntryMixin):
 
     def serialize(self, request, show_comments=True):
         """ Unserialize MediaEntry to object """
-        author = self.get_uploader
+        author = self.get_actor
         published = UTC.localize(self.created)
         updated = UTC.localize(self.updated)
         public_id = self.get_public_id(request)
@@ -898,7 +907,7 @@ class MediaComment(Base, MediaCommentMixin):
     id = Column(Integer, primary_key=True)
     media_entry = Column(
         Integer, ForeignKey(MediaEntry.id), nullable=False, index=True)
-    author = Column(Integer, ForeignKey(User.id), nullable=False)
+    actor = Column(Integer, ForeignKey(User.id), nullable=False)
     created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
     content = Column(UnicodeText, nullable=False)
     location = Column(Integer, ForeignKey("core__locations.id"))
@@ -907,7 +916,7 @@ class MediaComment(Base, MediaCommentMixin):
     # Cascade: Comments are owned by their creator. So do the full thing.
     # lazy=dynamic: People might post a *lot* of comments,
     #     so make the "posted_comments" a query-like thing.
-    get_author = relationship(User,
+    get_actor = relationship(User,
                               backref=backref("posted_comments",
                                               lazy="dynamic",
                                               cascade="all, delete-orphan"))
@@ -934,7 +943,7 @@ class MediaComment(Base, MediaCommentMixin):
             qualified=True
         )
         media = MediaEntry.query.filter_by(id=self.media_entry).first()
-        author = self.get_author
+        author = self.get_actor
         published = UTC.localize(self.created)
         context = {
             "id": href,
@@ -981,7 +990,15 @@ class MediaComment(Base, MediaCommentMixin):
 
 
 class Collection(Base, CollectionMixin):
-    """An 'album' or 'set' of media by a user.
+    """A representation of a collection of objects.
+
+    This holds a group/collection of objects that could be a user defined album
+    or their inbox, outbox, followers, etc. These are always ordered and accessable
+    via the API and web.
+
+    The collection has a number of types which determine what kind of collection
+    it is, for example the users inbox will be of `Collection.INBOX_TYPE` that will
+    be stored on the `Collection.type` field. It's important to set the correct type.
 
     On deletion, contained CollectionItems get automatically reaped via
     SQL cascade"""
@@ -992,23 +1009,37 @@ class Collection(Base, CollectionMixin):
     slug = Column(Unicode)
     created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow,
                      index=True)
+    updated = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
     description = Column(UnicodeText)
-    creator = Column(Integer, ForeignKey(User.id), nullable=False)
+    actor = Column(Integer, ForeignKey(User.id), nullable=False)
+    num_items = Column(Integer, default=0)
+
+    # There are lots of different special types of collections in the pump.io API
+    # for example: followers, following, inbox, outbox, etc. See type constants
+    # below the fields on this model.
+    type = Column(Unicode, nullable=False)
+
+    # Location
     location = Column(Integer, ForeignKey("core__locations.id"))
     get_location = relationship("Location", lazy="joined")
 
-    # TODO: No of items in Collection. Badly named, can we migrate to num_items?
-    items = Column(Integer, default=0)
-
     # Cascade: Collections are owned by their creator. So do the full thing.
-    get_creator = relationship(User,
+    get_actor = relationship(User,
                                backref=backref("collections",
                                                cascade="all, delete-orphan"))
-
     __table_args__ = (
-        UniqueConstraint('creator', 'slug'),
+        UniqueConstraint('actor', 'slug'),
         {})
 
+    # These are the types, It's strongly suggested if new ones are invented they
+    # are prefixed to ensure they're unique from other types. Any types used in
+    # the main mediagoblin should be prefixed "core-"
+    INBOX_TYPE = "core-inbox"
+    OUTBOX_TYPE = "core-outbox"
+    FOLLOWER_TYPE = "core-followers"
+    FOLLOWING_TYPE = "core-following"
+    USER_DEFINED_TYPE = "core-user-defined"
+
     def get_collection_items(self, ascending=False):
         #TODO, is this still needed with self.collection_items being available?
         order_col = CollectionItem.position
@@ -1019,18 +1050,15 @@ class Collection(Base, CollectionMixin):
 
     def __repr__(self):
         safe_title = self.title.encode('ascii', 'replace')
-        return '<{classname} #{id}: {title} by {creator}>'.format(
+        return '<{classname} #{id}: {title} by {actor}>'.format(
             id=self.id,
             classname=self.__class__.__name__,
-            creator=self.creator,
+            actor=self.actor,
             title=safe_title)
 
     def serialize(self, request):
         # Get all serialized output in a list
-        items = []
-        for item in self.get_collection_items():
-            items.append(item.serialize(request))
-
+        items = [i.serialize(request) for i in self.get_collection_items()]
         return {
             "totalItems": self.items,
             "url": self.url_for_self(request.urlgen, qualified=True),
@@ -1042,23 +1070,36 @@ class CollectionItem(Base, CollectionItemMixin):
     __tablename__ = "core__collection_items"
 
     id = Column(Integer, primary_key=True)
-    media_entry = Column(
-        Integer, ForeignKey(MediaEntry.id), nullable=False, index=True)
+
     collection = Column(Integer, ForeignKey(Collection.id), nullable=False)
     note = Column(UnicodeText, nullable=True)
     added = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
     position = Column(Integer)
-
     # Cascade: CollectionItems are owned by their Collection. So do the full thing.
     in_collection = relationship(Collection,
                                  backref=backref(
                                      "collection_items",
                                      cascade="all, delete-orphan"))
 
-    get_media_entry = relationship(MediaEntry)
+    # Link to the object (could be anything.
+    object_id = Column(
+        Integer,
+        ForeignKey(GenericModelReference.id),
+        nullable=False,
+        index=True
+    )
+    object_helper = relationship(
+        GenericModelReference,
+        foreign_keys=[object_id]
+    )
+    get_object = association_proxy(
+        "object_helper",
+        "get_object",
+        creator=GenericModelReference.find_or_new
+    )
 
     __table_args__ = (
-        UniqueConstraint('collection', 'media_entry'),
+        UniqueConstraint('collection', 'object_id'),
         {})
 
     @property
@@ -1067,14 +1108,15 @@ class CollectionItem(Base, CollectionItemMixin):
         return DictReadAttrProxy(self)
 
     def __repr__(self):
-        return '<{classname} #{id}: Entry {entry} in {collection}>'.format(
+        return '<{classname} #{id}: Object {obj} in {collection}>'.format(
             id=self.id,
             classname=self.__class__.__name__,
             collection=self.collection,
-            entry=self.media_entry)
+            obj=self.get_object()
+        )
 
     def serialize(self, request):
-        return self.get_media_entry.serialize(request)
+        return self.get_object().serialize(request)
 
 
 class ProcessingMetaData(Base):
index 7c026691ed32688196d772b0450b587879da1fce..57e6b9427303b1212f1b224bdad8db7d451def0d 100644 (file)
@@ -37,7 +37,7 @@ def atomic_update(table, query_dict, update_values):
 
 
 def check_media_slug_used(uploader_id, slug, ignore_m_id):
-    query = MediaEntry.query.filter_by(uploader=uploader_id, slug=slug)
+    query = MediaEntry.query.filter_by(actor=uploader_id, slug=slug)
     if ignore_m_id is not None:
         query = query.filter(MediaEntry.id != ignore_m_id)
     does_exist = query.first() is not None
@@ -67,7 +67,7 @@ def clean_orphan_tags(commit=True):
 
 
 def check_collection_slug_used(creator_id, slug, ignore_c_id):
-    filt = (Collection.creator == creator_id) \
+    filt = (Collection.actor == creator_id) \
         & (Collection.slug == slug)
     if ignore_c_id is not None:
         filt = filt & (Collection.id != ignore_c_id)
index d20aca100f2890d43fe962d1a65451e12f1ed9c3..952b45724b7dbcad02111f6df8965c39bab12133 100644 (file)
@@ -126,7 +126,7 @@ def user_may_delete_media(controller):
     """
     @wraps(controller)
     def wrapper(request, *args, **kwargs):
-        uploader_id = kwargs['media'].uploader
+        uploader_id = kwargs['media'].actor
         if not (request.user.has_privilege(u'admin') or
                 request.user.id == uploader_id):
             raise Forbidden()
@@ -192,7 +192,7 @@ def get_user_media_entry(controller):
                 media = MediaEntry.query.filter_by(
                     id=int(media_slug[3:]),
                     state=u'processed',
-                    uploader=user.id).first()
+                    actor=user.id).first()
             except ValueError:
                 raise NotFound()
         else:
@@ -200,7 +200,7 @@ def get_user_media_entry(controller):
             media = MediaEntry.query.filter_by(
                 slug=media_slug,
                 state=u'processed',
-                uploader=user.id).first()
+                actor=user.id).first()
 
         if not media:
             # Didn't find anything?  Okay, 404.
@@ -225,7 +225,7 @@ def get_user_collection(controller):
 
         collection = request.db.Collection.query.filter_by(
             slug=request.matchdict['collection'],
-            creator=user.id).first()
+            actor=user.id).first()
 
         # Still no collection?  Okay, 404.
         if not collection:
@@ -274,7 +274,7 @@ def get_media_entry_by_id(controller):
             return render_404(request)
 
         given_username = request.matchdict.get('user')
-        if given_username and (given_username != media.get_uploader.username):
+        if given_username and (given_username != media.get_actor.username):
             return render_404(request)
 
         return controller(request, media=media, *args, **kwargs)
index 6acebc96f31fb1b414c32c46a6dc14ad495fdd24..3f52376ae1023a43617c93614bc333dac66bd334 100644 (file)
@@ -17,7 +17,7 @@
 
 def may_edit_media(request, media):
     """Check, if the request's user may edit the media details"""
-    if media.uploader == request.user.id:
+    if media.actor == request.user.id:
         return True
     if request.user.has_privilege(u'admin'):
         return True
index af0d0e9b06a2a4ee02dff450795f9d738d84ee99..8e80b3ce215dc96cf7146a76b96279628a90b7fc 100644 (file)
@@ -73,7 +73,7 @@ def edit_media(request, media):
         # Make sure there isn't already a MediaEntry with such a slug
         # and userid.
         slug = slugify(form.slug.data)
-        slug_used = check_media_slug_used(media.uploader, slug, media.id)
+        slug_used = check_media_slug_used(media.actor, slug, media.id)
 
         if slug_used:
             form.slug.errors.append(
@@ -350,12 +350,12 @@ def edit_collection(request, collection):
     if request.method == 'POST' and form.validate():
         # Make sure there isn't already a Collection with such a slug
         # and userid.
-        slug_used = check_collection_slug_used(collection.creator,
+        slug_used = check_collection_slug_used(collection.actor,
                 form.slug.data, collection.id)
 
         # Make sure there isn't already a Collection with this title
         existing_collection = request.db.Collection.query.filter_by(
-                creator=request.user.id,
+                actor=request.user.id,
                 title=form.title.data).first()
 
         if existing_collection and existing_collection.id != collection.id:
@@ -376,7 +376,7 @@ def edit_collection(request, collection):
             return redirect_obj(request, collection)
 
     if request.user.has_privilege(u'admin') \
-            and collection.creator != request.user.id \
+            and collection.actor != request.user.id \
             and request.method != 'POST':
         messages.add_message(
             request, messages.WARNING,
index ed733b9e86adcf9328841331452418c77f715276..2ad7e39e418b4493c96f37cd178ab43268aa79d6 100644 (file)
@@ -213,4 +213,3 @@ def parse_csv_file(file_contents):
         objects_dict[media_id] = (line_dict)
 
     return objects_dict
-
index 07dbb3d504b98cda4ad9572a2429b80cd1d35131..f640cc9521281ee748ca7215cd2e727bb5d99558 100644 (file)
@@ -106,10 +106,10 @@ def atom_feed(request):
             entry.description_html,
             id=entry.url_for_self(request.urlgen,qualified=True),
             content_type='html',
-            author={'name': entry.get_uploader.username,
+            author={'name': entry.get_actor.username,
                 'uri': request.urlgen(
                     'mediagoblin.user_pages.user_home',
-                    qualified=True, user=entry.get_uploader.username)},
+                    qualified=True, user=entry.get_actor.username)},
             updated=entry.get('created'),
             links=[{
                 'href':entry.url_for_self(
index b4f4fbc8503f4ec9e2a424d27dcb338d4887e554..3502d7b8dc3d5b39229dcd50aaa956fbf1b3b9de 100644 (file)
@@ -54,7 +54,7 @@ from mediagoblin.notifications import add_comment_subscription
 @require_active_login
 def blog_edit(request):
     """
-    View for editing an existing blog or creating a new blog 
+    View for editing an existing blog or creating a new blog
     if user have not exceeded maximum allowed acount of blogs.
     """
     url_user = request.matchdict.get('user', None)
@@ -171,7 +171,7 @@ def blogpost_create(request):
 
 @require_active_login
 def blogpost_edit(request):
-    
+
     blog_slug = request.matchdict.get('blog_slug', None)
     blog_post_slug = request.matchdict.get('blog_post_slug', None)
 
@@ -279,7 +279,7 @@ def blog_post_listing(request, page, url_user=None):
          'blog_owner': url_user,
          'blog':blog
         })
-        
+
 
 @require_active_login
 def draft_view(request):
@@ -348,23 +348,23 @@ def blog_delete(request, **kwargs):
         _("The blog was not deleted because you have no rights."))
         return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
         user=request.user.username)
-        
-        
+
+
 def blog_about_view(request):
     """
     Page containing blog description and statistics
     """
     blog_slug = request.matchdict.get('blog_slug', None)
     url_user = request.matchdict.get('user', None)
-    
+
     user = request.db.User.query.filter(
         LocalUser.username=url_user
-    ).first() 
+    ).first()
     blog = get_blog_by_slug(request, blog_slug, author=user.id)
-    
+
     if not user or not blog:
         return render_404(request)
-    
+
     else:
         blog_posts_processed = blog.get_all_blog_posts(u'processed').count()
         return render_to_response(
@@ -374,11 +374,3 @@ def blog_about_view(request):
                 'blog': blog,
                 'blogpost_count': blog_posts_processed
                 })
-        
-    
-    
-
-
-
-
-
index c7a9a1fb0f9328c93e486f28bb9fcc872260e7e6..ea468f8e583109ebf80e89e65a3066ede24ac922 100644 (file)
@@ -34,7 +34,7 @@ def trigger_notification(comment, media_entry, request):
         if not subscription.notify:
             continue
 
-        if comment.get_author == subscription.user:
+        if comment.get_actor == subscription.user:
             continue
 
         cn = CommentNotification(
index 254327802ea7db4bc988a69000a1d8c31f352106..69017ed07bdef97c5db831cf3cb77e6b404d4990 100644 (file)
@@ -32,11 +32,11 @@ def generate_comment_message(user, comment, media, request):
     comment_url = request.urlgen(
                     'mediagoblin.user_pages.media_home.view_comment',
                     comment=comment.id,
-                    user=media.get_uploader.username,
+                    user=media.get_actor.username,
                     media=media.slug_or_id,
                     qualified=True) + '#comment'
 
-    comment_author = comment.get_author.username
+    comment_author = comment.get_actor.username
 
     rendered_email = render_template(
         request, 'mediagoblin/user_pages/comment_email.txt',
index 56256236bdf936db6dde6f273cd2263d73066de0..e406888ea69e2703c01ad04193303b3a7740c91a 100644 (file)
@@ -62,12 +62,12 @@ def get_entry_serializable(entry, urlgen):
     to views.
     '''
     return {
-            'user': entry.get_uploader.username,
-            'user_id': entry.get_uploader.id,
-            'user_bio': entry.get_uploader.bio,
-            'user_bio_html': entry.get_uploader.bio_html,
+            'user': entry.get_actor.username,
+            'user_id': entry.get_actor.id,
+            'user_bio': entry.get_actor.bio,
+            'user_bio_html': entry.get_actor.bio_html,
             'user_permalink': urlgen('mediagoblin.user_pages.user_home',
-                user=entry.get_uploader.username,
+                user=entry.get_actor.username,
                 qualified=True),
             'id': entry.id,
             'created': entry.created.isoformat(),
index c5b8a7d6882da2ca1dfdde6ec478cea07f4fa7bc..942a888b979c913d766f91fc2bbfa0f5716bbeb8 100644 (file)
@@ -21,7 +21,7 @@
               {% if not media_feature %}
                 <a href="{{ request.urlgen(
                     'mediagoblin.user_pages.media_feature',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id) }}"
         class="button_action" id="button_featuremedia" title="{% trans %}
 Feature Media {% endtrans %}">
@@ -29,7 +29,7 @@ Feature Media {% endtrans %}">
               {% else %}
                 <a href="{{ request.urlgen(
                     'mediagoblin.user_pages.media_unfeature',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id) }}"
         class="button_action" id="button_unfeaturemedia" title="{% trans %}
 Unfeature Media {% endtrans %}">
@@ -37,7 +37,7 @@ Unfeature Media {% endtrans %}">
                 {% if not media_feature.display_type == 'primary' %}
                 <a href="{{ request.urlgen(
                     'mediagoblin.user_pages.feature_promote',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id) }}"
         class="button_action" id="button_promotefeature" title="{% trans %}
 Promote Feature {% endtrans %}">
@@ -45,7 +45,7 @@ Promote Feature {% endtrans %}">
                 {% endif %}{% if not media_feature.display_type == 'tertiary' %}
                 <a href="{{ request.urlgen(
                     'mediagoblin.user_pages.feature_demote',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id) }}"
         class="button_action" id="button_demotefeature" title="{% trans %}
 Demote Feature {% endtrans %}">
index fb5673e10bbf6e19102ceba635618b5f3a3c2164..ad2eee5f9b20b17476ab480f231d350def2d6c90 100644 (file)
@@ -38,7 +38,7 @@ def get_media_entry_from_uploader_slug(uploader_username, slug):
         LocalUser.username==uploader_username
     ).first()
     media = MediaEntry.query.filter(
-        MediaEntry.get_uploader == uploader ).filter(
+        MediaEntry.get_actor == uploader ).filter(
         MediaEntry.slug == slug).first()
     return media
 
@@ -141,7 +141,7 @@ def create_featured_media_textbox():
         for feature in feature_list:
             media_entry = feature.media_entry
             output_text += u'/u/{uploader_username}/m/{media_slug}/\n'.format(
-                uploader_username = media_entry.get_uploader.username,
+                uploader_username = media_entry.get_actor.username,
                 media_slug = media_entry.slug)
 
 
index 3a9d872cf9d32bf2da5c5ac2813dde2a20d618da..15ea15368785ba8f9e60c362ce96d42f2de66247 100644 (file)
@@ -35,7 +35,7 @@
 {% endif %}
 {% if request.user and request.user.has_privilege('admin') %}
   <a href="{{ request.urlgen('mediagoblin.edit.metadata',
-                    user=media.get_uploader.username,
+                    user=media.get_actor.username,
                     media_id=media.id) }}">
   {% trans %}Edit Metadata{% endtrans %}</a>
 {% endif %}
index 1fe1e576a109f8a5c53ced254d0c3c084f1ee44c..ab741a7243cca6caff177760d0252ee306c9c5a6 100644 (file)
@@ -82,7 +82,7 @@ def pwg_categories_getList(request):
 
     if request.user:
         collections = Collection.query.filter_by(
-            get_creator=request.user).order_by(Collection.title)
+            get_actor=request.user).order_by(Collection.title)
 
         for c in collections:
             catlist.append({'id': c.id,
@@ -142,7 +142,7 @@ def pwg_images_addSimple(request):
         collection_id = form.category.data
         if collection_id > 0:
             collection = Collection.query.get(collection_id)
-            if collection is not None and collection.creator == request.user.id:
+            if collection is not None and collection.actor == request.user.id:
                 add_media_to_collection(collection, entry, "")
 
         return {
index a0e1cf90223a963d4e525c7dab1738cc5fccaf79..77dd836b6ccc99c3d9fa48a41bfc834d217f6088 100644 (file)
@@ -52,7 +52,7 @@ def new_upload_entry(user):
     Create a new MediaEntry for uploading
     """
     entry = MediaEntry()
-    entry.uploader = user.id
+    entry.actor = user.id
     entry.license = user.license_preference
     return entry
 
@@ -198,7 +198,7 @@ def submit_media(mg_app, user, submitted_file, filename,
     add_comment_subscription(user, entry)
 
     # Create activity
-    create_activity("post", entry, entry.uploader)
+    create_activity("post", entry, entry.actor)
     entry.save()
 
     # Pass off to processing
@@ -297,7 +297,7 @@ def api_add_to_feed(request, entry):
     activity = create_activity(
         verb="post",
         obj=entry,
-        actor=entry.uploader,
+        actor=entry.actor,
         generator=create_generator(request)
     )
     entry.save()
index d1e33c47a8d14fb1b3d7591b4956794e9848a783..84c9a02c0813431f697476488339e4571c1779ad 100644 (file)
@@ -27,7 +27,7 @@
 
 {% block mediagoblin_content %}
   <form action="{{ request.urlgen('mediagoblin.edit.attachments',
-                               user= media.get_uploader.username,
+                               user= media.get_actor.username,
                                media_id=media.id) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box">
index 9a0400951b92a3e335306024f8fdc2e3d452c52e..5f2ba3c506401e0c20057a8f30b54b54e13c742d 100644 (file)
@@ -28,7 +28,7 @@
 {% block mediagoblin_content %}
 
   <form action="{{ request.urlgen('mediagoblin.edit.edit_media',
-                               user= media.get_uploader.username,
+                               user= media.get_actor.username,
                                media_id=media.id) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box_xl edit_box">
index 5cf5bae83802a8b2d99ef92429a9ee3ed1af50bd..f150b3067e6b064f85d0a4a2b80ef2efd9812b67 100644 (file)
@@ -22,7 +22,7 @@
 {% block mediagoblin_content %}
 
   <form action="{{ request.urlgen('mediagoblin.edit.edit_collection',
-                               user= collection.get_creator.username,
+                               user= collection.get_actor.username,
                                collection= collection.slug) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box_xl edit_box">
@@ -36,4 +36,4 @@
     </div>
   </form>
 
-{% endblock %}    
+{% endblock %}
index 55759a39465f481674a243d70d1f633042db7d79..68c42bf4bdac4e272b1b34c47d902f11e7718bab 100644 (file)
@@ -5,7 +5,7 @@
     <ul>
         {% for notification in  notifications %}
         {% set comment = notification.subject %}
-        {% set comment_author = comment.get_author %}
+        {% set comment_author = comment.get_actor %}
         {% set media = comment.get_entry %}
         <li class="comment_wrapper">
             <div class="comment_author">
@@ -17,7 +17,7 @@
                 </a>
                 <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
                             comment=comment.id,
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id) }}#comment"
                     class="comment_whenlink">
                     <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
@@ -36,7 +36,7 @@
         </li>
         {% endfor %}
     </ul>
-    <a href="{{ request.urlgen('mediagoblin.notifications.mark_all_comment_notifications_seen') }}?next={{ 
+    <a href="{{ request.urlgen('mediagoblin.notifications.mark_all_comment_notifications_seen') }}?next={{
       request.base_url|urlencode }}" id="mark_all_comments_seen">
       {% trans %}Mark all read{% endtrans %}
     </a>
index 9b77f638c3a0a26bbee66573ae0174ae3bbaa465..888e4febb0bac5692e8f2f3f6bb149f4f8c4f1a4 100644 (file)
@@ -44,7 +44,7 @@
     {% for media_entry in processing_entries %}
       <tr>
         <td>{{ media_entry.id }}</td>
-        <td>{{ media_entry.get_uploader.username }}</td>
+        <td>{{ media_entry.get_actor.username }}</td>
         <td>{{ media_entry.title }}</td>
         <td>{{ media_entry.created.strftime("%F %R") }}</td>
         {% if media_entry.transcoding_progress %}
@@ -74,7 +74,7 @@
     {% for media_entry in failed_entries %}
       <tr>
         <td>{{ media_entry.id }}</td>
-        <td>{{ media_entry.get_uploader.username }}</td>
+        <td>{{ media_entry.get_actor.username }}</td>
         <td>{{ media_entry.title }}</td>
         <td>{{ media_entry.created.strftime("%F %R") }}</td>
         {% if media_entry.get_fail_exception() %}
     {% for media_entry in processed_entries %}
       <tr>
         <td>{{ media_entry.id }}</td>
-        <td>{{ media_entry.get_uploader.username }}</td>
+        <td>{{ media_entry.get_actor.username }}</td>
         <td><a href="{{ media_entry.url_for_self(request.urlgen) }}">{{ media_entry.title }}</a></td>
         <td><span title='{{ media_entry.created.strftime("%F %R") }}'>{{ timesince(media_entry.created) }}</span></td>
       </tr>
index 496610ad47b9b7e0d695b31c838d1da842894a74..584dca998691e0af7eb62a8bda0c5171c7396ccb 100644 (file)
 
     {% trans %}Reported comment{% endtrans %}:
     {% set comment = report.comment %}
-    {% set reported_user = comment.get_author %}
+    {% set reported_user = comment.get_actor %}
     <div id="comment-{{ comment.id }}"
         class="comment_wrapper">
       <div class="comment_author">
         <img src="{{ request.staticdirect('/images/icon_comment.png') }}" />
             <a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
-                            user=comment.get_author.username) }}"
+                            user=comment.get_actor.username) }}"
                class="comment_authorlink">
           {{- reported_user.username -}}
         </a>
         <a href="{{ request.urlgen(
                         'mediagoblin.user_pages.media_home.view_comment',
                         comment=comment.id,
-                        user=comment.get_media_entry.get_uploader.username,
+                        user=comment.get_media_entry.get_actor.username,
                         media=comment.get_media_entry.slug_or_id) }}#comment"
            class="comment_whenlink">
           <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
     {% set media_entry = report.media_entry %}
     <div class="three columns media_thumbnail">
       <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
-                            user=media_entry.get_uploader.username,
+                            user=media_entry.get_actor.username,
                             media=media_entry.slug_or_id) }}">
       <img src="{{ media_entry.thumb_url}}"/></a>
       <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
-                    user=media_entry.get_uploader.username,
+                    user=media_entry.get_actor.username,
                     media=media_entry.slug_or_id) }}" class=thumb_entry_title>
         {{ media_entry.title }}</a>
     </div>
       {{ report.report_content }}
     </div>
   </div>
-  {% if not report.is_archived_report() and 
-        not (report.reported_user.has_privilege('admin') and 
+  {% if not report.is_archived_report() and
+        not (report.reported_user.has_privilege('admin') and
         not request.user.has_privilege('admin')) %}
     <input type=button class="button_action" value="{% trans %}Resolve{% endtrans %}" id=open_resolution_form />
     <form action="" method="POST" id=resolution_form>
index c6eedee092cbf92f78ddf670a0114bfce6503788..ece47fe1d92f3939a59519c09bf8e26707077266 100644 (file)
@@ -70,8 +70,8 @@
         {% if request.user and
           (media.uploader == request.user.id or
            request.user.has_privilege('admin')) %}
-      {% set edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit', 
-                                 blog_slug=media.media_manager.get_blog_by_blogpost().slug, 
+      {% set edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit',
+                                 blog_slug=media.media_manager.get_blog_by_blogpost().slug,
                                  user=request.user.username, blog_post_slug=media.slug) %}
       <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
       {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
       {% endif %}
       <ul style="list-style:none">
       {% for comment in comments %}
-        {% set comment_author = comment.get_author %}
+        {% set comment_author = comment.get_actor %}
         <li id="comment-{{ comment.id }}"
           {%- if pagination.active_id == comment.id %}
             class="comment_wrapper comment_active">
   <div class="media_sidebar">
     <h3>{% trans %}Added{% endtrans %}</h3>
     <p><span title="{{ media.created.strftime("%I:%M%p %Y-%m-%d") }}">
-        {%- trans formatted_time=timesince(media.created) -%}    
+        {%- trans formatted_time=timesince(media.created) -%}
           {{ formatted_time }} ago
         {%- endtrans -%}
     </span></p>
index 0f712c01917a667507b861a2a2b6e246cad60ddc..71ba4451219e393dad9cc6cec2a88b37fb893a33 100644 (file)
       {{ collection_title }} by <a href="{{ user_url }}">{{ username }}</a>
     {%- endtrans %}
   </h1>
-  {% if request.user and (collection.creator == request.user.id or
+  {% if request.user and (collection.actor == request.user.id or
                                                 request.user.has_privilege('admin')) %}
     {% set edit_url = request.urlgen('mediagoblin.edit.edit_collection',
-                                     user=collection.get_creator.username,
+                                     user=collection.get_actor.username,
                                      collection=collection.slug) %}
     <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
     {% set delete_url = request.urlgen('mediagoblin.user_pages.collection_confirm_delete',
-                          user=collection.get_creator.username,
+                          user=collection.get_actor.username,
                           collection=collection.slug) %}
     <a class="button_action" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a>
   {% endif %}
index 8cfe4b2902c62b5d39507c5fe293e3298603f4ba..082783498614afe44c718b5cdc4cc16b750811a8 100644 (file)
@@ -30,7 +30,7 @@
 {% block mediagoblin_content %}
 
   <form action="{{ request.urlgen('mediagoblin.user_pages.collection_confirm_delete',
-                                 user=collection.get_creator.username,
+                                 user=collection.get_actor.username,
                                  collection=collection.slug) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box">
@@ -39,9 +39,9 @@
           Really delete collection: {{ title }}?
         {%- endtrans %}
       </h1>
-         
+
       <br />
-         
+
       <p class="delete_checkbox_box">
        {{ form.confirm }}
        {{ wtforms_util.render_label(form.confirm) }}
@@ -58,4 +58,4 @@
       </div>
     </div>
   </form>
-{% endblock %}    
+{% endblock %}
index 84d3eb4c9301719247b2b561e44b23016cf58c17..d7ff49509f6ef8bedeb92c52920708546635e5be 100644 (file)
@@ -20,7 +20,7 @@
 {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
 
 {% block title %}
-    {%- trans media_title=collection_item.get_media_entry.title,
+    {%- trans media_title=collection_item.get_object().title,
                   collection_title=collection_item.in_collection.title -%}
   Remove {{ media_title }} from {{ collection_title }}
   {%- endtrans %} &mdash; {{ super() }}
 {% block mediagoblin_content %}
 
   <form action="{{ request.urlgen('mediagoblin.user_pages.collection_item_confirm_remove',
-                                 user=collection_item.in_collection.get_creator.username,
+                                 user=collection_item.in_collection.get_actor.username,
                                  collection=collection_item.in_collection.slug,
                                  collection_item=collection_item.id) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box">
       <h1>
-        {%- trans media_title=collection_item.get_media_entry.title,
+        {%- trans media_title=collection_item.get_object().title,
                  collection_title=collection_item.in_collection.title -%}
           Really remove {{ media_title }} from {{ collection_title }}?
         {%- endtrans %}
       </h1>
 
       <div style="text-align: center;" >
-        <img src="{{ collection_item.get_media_entry.thumb_url }}" />
+        <img src="{{ collection_item.get_object().thumb_url }}" />
       </div>
 
       <br />
@@ -64,4 +64,4 @@
       </div>
     </div>
   </form>
-{% endblock %}    
+{% endblock %}
index 16ddd62cd68365c7d20d7fe22c505338b25eb3d7..b74ca13e7e6e6bfc623131c5b8e4648f3fb99381 100644 (file)
@@ -38,8 +38,8 @@
   <p class="eleven columns context">
     {%- trans user_url=request.urlgen(
               'mediagoblin.user_pages.user_home',
-              user=media.get_uploader.username),
-              username=media.get_uploader.username -%}
+              user=media.get_actor.username),
+              username=media.get_actor.username -%}
     ❖ Browsing media by <a href="{{user_url}}">{{username}}</a>
     {%- endtrans -%}
   </p>
       {{ media.title }}
     </h2>
     {% if request.user and
-          (media.uploader == request.user.id or
+          (media.actor == request.user.id or
            request.user.has_privilege('admin')) %}
     <div class="pull-right" style="padding-top:20px;">
       {% set edit_url = request.urlgen('mediagoblin.edit.edit_media',
-                                 user= media.get_uploader.username,
+                                 user= media.get_actor.username,
                                  media_id=media.id) %}
       <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
       {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
-                                 user= media.get_uploader.username,
+                                 user= media.get_actor.username,
                                  media_id=media.id) %}
       <a class="button_action button_warning" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a>
       </div>
       {% endif %}
       {% if request.user %}
         <form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
-                                         user= media.get_uploader.username,
+                                         user= media.get_actor.username,
                                          media_id=media.id) }}" method="POST" id="form_comment">
           {{ wtforms_util.render_divs(comment_form) }}
           <div class="form_submit_buttons">
       {% endif %}
       <ul style="list-style:none">
       {% for comment in comments %}
-        {% set comment_author = comment.get_author %}
+        {% set comment_author = comment.get_actor %}
         <li id="comment-{{ comment.id }}"
           {%- if pagination.active_id == comment.id %}
             class="comment_wrapper comment_active">
             </a>
             <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
                             comment=comment.id,
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id) }}#comment"
                class="comment_whenlink">
               <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
           <div>
             {% if app_config.allow_reporting %}
                 <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.report_comment',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id,
                              comment=comment.id) }}">
                     {% trans %}Report{% endtrans %}</a>
     {%- endif %}
     {%- if app_config['allow_attachments']
           and request.user
-          and (media.uploader == request.user.id
+          and (media.actor == request.user.id
                or request.user.has_privilege('admin')) %}
       {%- if not media.attachment_files|count %}
         <h3>{% trans %}Attachments{% endtrans %}</h3>
       {%- endif %}
       <p>
         <a href="{{ request.urlgen('mediagoblin.edit.attachments',
-                      user=media.get_uploader.username,
+                      user=media.get_actor.username,
                       media_id=media.id) }}">
           {%- trans %}Add attachment{% endtrans -%}
         </a>
index b4c9671cbcdd5fa7dde8ffffea39907cee4f2571..ba7424d101914dd20865e5fd60a95b0bf3be36d3 100644 (file)
@@ -32,7 +32,7 @@
 
 {% block mediagoblin_content %}
   <form action="{{ request.urlgen('mediagoblin.user_pages.media_collect',
-                                 user=media.get_uploader.username,
+                                 user=media.get_actor.username,
                                  media_id=media.id) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box">
@@ -70,4 +70,4 @@
       </div>
     </div>
   </form>
-{% endblock %}    
+{% endblock %}
index c948ccec10969e48a4a35b3e54571f16c0b4f329..243edff545179f8cb91b788e0280ba2524bd8f39 100644 (file)
@@ -22,7 +22,7 @@
 {% block mediagoblin_content %}
 
   <form action="{{ request.urlgen('mediagoblin.user_pages.media_confirm_delete',
-                                 user=media.get_uploader.username,
+                                 user=media.get_actor.username,
                                  media_id=media.id) }}"
         method="POST" enctype="multipart/form-data">
     <div class="form_box">
@@ -51,4 +51,4 @@
       </div>
     </div>
   </form>
-{% endblock %}    
+{% endblock %}
index 6f25b996a919053309816a2d8693f26e40178768..09502fcf39dd4c430820a0e0e1a16472f00a0de7 100644 (file)
 <form action="" method=POST >
     {% if comment is defined %}
         <h3>{% trans %}Reporting this Comment{% endtrans %}</h3>
-        {%- set comment_author = comment.get_author %}
+        {%- set comment_author = comment.get_actor %}
         {%- set comment_author_url = request.urlgen(
                                       'mediagoblin.user_pages.user_home',
                                       user=comment_author.username) %}
         {%- set comment_url = request.urlgen(
                             'mediagoblin.user_pages.media_home.view_comment',
                             comment=comment.id,
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id) %}
         <div id="comment-{{ comment.id }}"
             class="comment_wrapper">
         <h3>{% trans %}Reporting this Media Entry{% endtrans %}</h3>
           <div class="media_thumbnail">
             <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id) }}">
               <img src="{{ media.thumb_url }}"/></a>
             <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id) }}"
                class=thumb_entry_title>{{ media.title }}</a>
           </div>
           <div class=clear></div>
-      {%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_uploader.username),
-            username = media.get_uploader.username %}
+      {%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_actor.username),
+            username = media.get_actor.username %}
             ❖ Published by <a href="{{ user_url }}"
                           class="comment_authorlink">{{ username }}</a>
       {% endtrans %}
index 64b30815e6d47e3ea6baf1f589e5b8153fa70179..86680cb6c639af2e6c1df8acee47b106f18b7d34 100644 (file)
                  {%- if loop.first %} thumb_row_first
                  {%- elif loop.last %} thumb_row_last{% endif %}">
         {% for item in row %}
-          {% set media_entry = item.get_media_entry %}
-          {% set entry_url = media_entry.url_for_self(request.urlgen) %}
+          {% set obj = item.get_object() %}
+          {% set obj_url = obj.url_for_self(request.urlgen) %}
           <div class="three columns media_thumbnail thumb_entry
                      {%- if loop.first %} thumb_entry_first
                      {%- elif loop.last %} thumb_entry_last{% endif %}">
-            <a href="{{ entry_url }}">
-              <img src="{{ media_entry.thumb_url }}" />
+            <a href="{{ obj_url }}">
+              <img src="{{ obj.thumb_url }}" />
             </a>
 
             {% if item.note %}
-              <a href="{{ entry_url }}">{{ item.note }}</a>
+              <a href="{{ obj_url }}">{{ item.note }}</a>
             {% endif %}
            {% if request.user and
-                  (item.in_collection.creator == request.user.id or
+                  (item.in_collection.actor == request.user.id or
                   request.user.has_privilege('admin')) %}
              {%- set remove_url=request.urlgen(
                                  'mediagoblin.user_pages.collection_item_confirm_remove',
-                                 user=item.in_collection.get_creator.username,
+                                 user=item.in_collection.get_actor.username,
                                  collection=item.in_collection.slug,
                                  collection_item=item.id) -%}
              <a href="{{ remove_url }}" class="remove">
index 69738e267edc1c86d2946ccf734293695d2f25ab..5e209d6044120b039f47c21d427f66ca4e29e9b0 100644 (file)
         {%- endif %}
         <a href="{{ collection.url_for_self(request.urlgen) }}">
           {{- collection.title }} (
-            {{- collection.get_creator.username -}}
+            {{- collection.get_actor.username -}}
           )</a>
       {%- endfor %}
     </p>
   {%- endif %}
   {%- if request.user %}
     <p>
-      <a type="submit" href="{{ request.urlgen('mediagoblin.user_pages.media_collect', 
-                                  user=media.get_uploader.username,
+      <a type="submit" href="{{ request.urlgen('mediagoblin.user_pages.media_collect',
+                                  user=media.get_actor.username,
                                   media_id=media.id) }}"
          class="button_action">
         {% trans %}Add to a collection{% endtrans %}
index 5c50c80156c26059d2935092a0bc0068fb3f64c9..54663f057b1be94aa128fde432a6015fc4b8432f 100644 (file)
     {% set subscription = get_comment_subscription(request.user.id, media.id) %}
     {% if not subscription or not subscription.notify %}
         <a type="submit" href="{{ request.urlgen('mediagoblin.notifications.subscribe_comments',
-            user=media.get_uploader.username,
+            user=media.get_actor.username,
             media=media.slug_or_id)}}"
             class="button_action">{% trans %}Subscribe to comments{% endtrans %}
         </a>
     {% else %}
         <a type="submit" href="{{ request.urlgen('mediagoblin.notifications.silence_comments',
-            user=media.get_uploader.username,
+            user=media.get_actor.username,
             media=media.slug_or_id)}}"
             class="button_action">{% trans %}Silence comments{% endtrans %}
         </a>
index 3829de977771473ec5c537664e8f21b9a759a232..8da2be7d12cb46ac9197b0964a344121ad99eff6 100644 (file)
@@ -19,7 +19,7 @@
 {% block report_content -%}
   <p>
     <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.report_media',
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                              media=media.slug_or_id) }}"
         class="button_action" id="button_reportmedia" title="Report media">
         {% trans %}Report media{% endtrans %}
index bb4bd1a5c5a19408d759bd8b98c28563aa5cecec..5fc5dd8f9601223152418a765d236e09a87919c9 100644 (file)
         <a href="{{ request.urlgen(
                           'mediagoblin.user_pages.user_tag_gallery',
                           tag=tag['slug'],
-                          user=media.get_uploader.username) }}">{{ tag['name'] }}</a>
+                          user=media.get_actor.username) }}">{{ tag['name'] }}</a>
       {% elif loop.revindex == 2 %}
         <a href="{{ request.urlgen(
                           'mediagoblin.user_pages.user_tag_gallery',
                           tag=tag['slug'],
-                          user=media.get_uploader.username) }}">{{ tag['name'] }}</a>
+                          user=media.get_actor.username) }}">{{ tag['name'] }}</a>
       {% else %}
         <a href="{{ request.urlgen(
                           'mediagoblin.user_pages.user_tag_gallery',
                           tag=tag['slug'],
-                          user=media.get_uploader.username) }}">{{ tag['name'] }}</a>
+                          user=media.get_actor.username) }}">{{ tag['name'] }}</a>
         &middot;
       {% endif %}
     {% endfor %}
index 83003875906c98a50f8b23491755b34f741acd59..b58e112f5857d5c7ac2289a11117de63f9fa468e 100644 (file)
@@ -190,7 +190,7 @@ class TestAPI(object):
         # and self._upload_image.
         id = int(data["object"]["id"].split("/")[-2])
         media = MediaEntry.query.filter_by(id=id).first()
-        media.uploader = self.other_user.id
+        media.actor = self.other_user.id
         media.save()
 
         # Now lets try and edit the image as self.user, this should produce a 403 error.
@@ -324,7 +324,7 @@ class TestAPI(object):
         comment = media.get_comments()[0]
 
         # Tests that it matches in the database
-        assert comment.author == self.user.id
+        assert comment.actor == self.user.id
         assert comment.content == content
 
         # Test that the response is what we should be given
@@ -384,7 +384,7 @@ class TestAPI(object):
         # change who uploaded the comment as it's easier than changing
         comment_id = int(comment_data["object"]["id"].split("/")[-2])
         comment = MediaComment.query.filter_by(id=comment_id).first()
-        comment.author = self.other_user.id
+        comment.actor = self.other_user.id
         comment.save()
 
         # Update the comment as someone else.
@@ -597,4 +597,3 @@ class TestAPI(object):
         model = MediaComment.query.filter_by(id=comment_id).first()
 
         assert model.content == activity["object"]["content"]
-
index b3e59c0924ce120fd9e32c661603014a0d8a26ef..2bff00578dd7c703e1f1ddc81caee3764cfa3f6f 100644 (file)
@@ -50,7 +50,7 @@ def test_user_deletes_other_comments(test_app):
         for m_id in (media_a.id, media_b.id):
             cmt = MediaComment()
             cmt.media_entry = m_id
-            cmt.author = u_id
+            cmt.actor = u_id
             cmt.content = u"Some Comment"
             Session.add(cmt)
 
index 9e0d017cdb7207d306bde5186318823a42afd5bd..4c66e27b98dfdfb7aa53209123d44e6332fb501e 100644 (file)
@@ -56,7 +56,7 @@ class TestMediaEntrySlugs(object):
         entry.title = title or u"Some title"
         entry.slug = slug
         entry.id = this_id
-        entry.uploader = uploader or self.chris_user.id
+        entry.actor = uploader or self.chris_user.id
         entry.media_type = u'image'
 
         if save:
index 1b07172313728d8e42c6f2820f98752be26c2888..85c130cac6082277572400fcb3f1455265824b85 100644 (file)
@@ -158,7 +158,7 @@ VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
         fixture_add_comment(author=self.user.id,
             comment=u'Comment will be removed')
         test_comment = MediaComment.query.filter(
-            MediaComment.author==self.user.id).first()
+            MediaComment.actor==self.user.id).first()
         fixture_add_comment_report(comment=test_comment,
             reported_user=self.user)
         comment_report = CommentReport.query.filter(
@@ -177,7 +177,7 @@ VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
             UserBan.user_id == self.user.id).first()
         assert test_user_ban is not None
         test_comment = MediaComment.query.filter(
-            MediaComment.author==self.user.id).first()
+            MediaComment.actor==self.user.id).first()
         assert test_comment is None
 
         # Then, test what happens when a moderator attempts to punish an admin
index 385da569a7b7d81fb02847567ac7111dca7d7858..f7e67d80a4da337045120a0027836dc17adea0f7 100644 (file)
@@ -112,7 +112,7 @@ class TestNotifications:
         assert type(notification) == CommentNotification
         assert notification.seen == False
         assert notification.user_id == user.id
-        assert notification.subject.get_author.id == self.test_user.id
+        assert notification.subject.get_actor.id == self.test_user.id
         assert notification.subject.content == u'Test comment #42'
 
         if wants_email == True:
index 1f4573cf492274f4dfffb26efc4a1fdd4c83bb53..f036303a3afbb97ece7a92cbb031ad4425c39983 100644 (file)
@@ -133,7 +133,7 @@ class TestReportFiling:
         fixture_add_comment(author=allie_user.id,
             comment=u'Comment will be removed')
         test_comment = MediaComment.query.filter(
-            MediaComment.author==allie_user.id).first()
+            MediaComment.actor==allie_user.id).first()
         fixture_add_comment_report(comment=test_comment,
             reported_user=allie_user,
             report_content=u'Testing Archived Reports #1',
@@ -165,4 +165,3 @@ class TestReportFiling:
 natalie banned user allie indefinitely.
 natalie deleted the comment.'''
         assert archived_report.discriminator == 'comment_report'
-
index 6c974c39a100da4edf3a098e34adbd2e12ae5908..ba143acdccb9a822b3f0a10af0f55dc30d944f97 100644 (file)
@@ -204,12 +204,12 @@ def fixture_add_user(username=u'chris', password=u'toast',
 
 def fixture_comment_subscription(entry, notify=True, send_email=None):
     if send_email is None:
-        uploader = LocalUser.query.filter_by(id=entry.uploader).first()
-        send_email = uploader.wants_comment_notification
+        actor = LocalUser.query.filter_by(id=entry.actor).first()
+        send_email = actor.wants_comment_notification
 
     cs = CommentSubscription(
         media_entry_id=entry.id,
-        user_id=entry.uploader,
+        user_id=entry.actor,
         notify=notify,
         send_email=send_email)
 
@@ -254,7 +254,7 @@ def fixture_media_entry(title=u"Some title", slug=None,
     entry = MediaEntry()
     entry.title = title
     entry.slug = slug
-    entry.uploader = uploader
+    entry.actor = uploader
     entry.media_type = u'image'
     entry.state = state
 
@@ -278,15 +278,21 @@ def fixture_media_entry(title=u"Some title", slug=None,
     return entry
 
 
-def fixture_add_collection(name=u"My first Collection", user=None):
+def fixture_add_collection(name=u"My first Collection", user=None,
+                           collection_type=Collection.USER_DEFINED_TYPE):
     if user is None:
         user = fixture_add_user()
-    coll = Collection.query.filter_by(creator=user.id, title=name).first()
+    coll = Collection.query.filter_by(
+        actor=user.id,
+        title=name,
+        type=collection_type
+    ).first()
     if coll is not None:
         return coll
     coll = Collection()
-    coll.creator = user.id
+    coll.actor = user.id
     coll.title = name
+    coll.type = collection_type
     coll.generate_slug()
     coll.save()
 
@@ -310,7 +316,7 @@ def fixture_add_comment(author=None, media_entry=None, comment=None):
             'Auto-generated test comment by user #{0} on media #{0}'.format(
                 author, media_entry)
 
-    comment = MediaComment(author=author,
+    comment = MediaComment(actor=author,
                       media_entry=media_entry,
                       content=comment)
 
@@ -373,4 +379,4 @@ def fixture_add_activity(obj, verb="post", target=None, generator=None, actor=No
         activity.set_target(target)
 
     activity.save()
-    return activity
\ No newline at end of file
+    return activity
index 5b411a8268bd5785f38910eac7517f91b52225b4..fc1b6a7e03e44042b1911b4e98273b5861848c13 100644 (file)
@@ -38,11 +38,11 @@ def send_comment_email(user, comment, media, request):
     comment_url = request.urlgen(
                     'mediagoblin.user_pages.media_home.view_comment',
                     comment=comment.id,
-                    user=media.get_uploader.username,
+                    user=media.get_actor.username,
                     media=media.slug_or_id,
                     qualified=True) + '#comment'
 
-    comment_author = comment.get_author.username
+    comment_author = comment.get_actor.username
 
     rendered_email = render_template(
         request, 'mediagoblin/user_pages/comment_email.txt',
@@ -64,12 +64,12 @@ def send_comment_email(user, comment, media, request):
 def add_media_to_collection(collection, media, note=None, commit=True):
     collection_item = CollectionItem()
     collection_item.collection = collection.id
-    collection_item.media_entry = media.id
+    collection_item.get_object = media
     if note:
         collection_item.note = note
     Session.add(collection_item)
 
-    collection.items = collection.items + 1
+    collection.num_items = collection.num_items + 1
     Session.add(collection)
     Session.add(media)
 
@@ -106,12 +106,12 @@ def build_report_object(report_form, media_entry=None, comment=None):
         report_object = CommentReport()
         report_object.comment_id = comment.id
         report_object.reported_user_id = MediaComment.query.get(
-            comment.id).get_author.id
+            comment.id).get_actor.id
     elif report_form.validate() and media_entry is not None:
         report_object = MediaReport()
         report_object.media_entry_id = media_entry.id
         report_object.reported_user_id = MediaEntry.query.get(
-            media_entry.id).get_uploader.id
+            media_entry.id).get_actor.id
     else:
         return None
 
index 33ca7c40bc9cc8f1bd34fea6e0f823c3ef827eb7..4ee601b360f5455ef00b3f9e37369ff1d2104d1b 100644 (file)
@@ -64,7 +64,7 @@ def user_home(request, page):
             {'user': user})
 
     cursor = MediaEntry.query.\
-        filter_by(uploader = user.id,
+        filter_by(actor = user.id,
                   state = u'processed').order_by(MediaEntry.created.desc())
 
     pagination = Pagination(page, cursor)
@@ -93,7 +93,7 @@ def user_gallery(request, page, url_user=None):
     """'Gallery' of a LocalUser()"""
     tag = request.matchdict.get('tag', None)
     cursor = MediaEntry.query.filter_by(
-        uploader=url_user.id,
+        actor=url_user.id,
         state=u'processed').order_by(MediaEntry.created.desc())
 
     # Filter potentially by tag too:
@@ -180,7 +180,7 @@ def media_post_comment(request, media):
 
     comment = request.db.MediaComment()
     comment.media_entry = media.id
-    comment.author = request.user.id
+    comment.actor = request.user.id
     comment.content = six.text_type(request.form['comment_content'])
 
     # Show error message if commenting is disabled.
@@ -195,7 +195,7 @@ def media_post_comment(request, media):
             messages.ERROR,
             _("Oops, your comment was empty."))
     else:
-        create_activity("post", comment, comment.author, target=media)
+        create_activity("post", comment, comment.actor, target=media)
         add_comment_subscription(request.user, media)
         comment.save()
 
@@ -228,7 +228,9 @@ def media_collect(request, media):
     form = user_forms.MediaCollectForm(request.form)
     # A user's own collections:
     form.collection.query = Collection.query.filter_by(
-        creator = request.user.id).order_by(Collection.title)
+        actor=request.user.id,
+        type=Collection.USER_DEFINED_TYPE
+    ).order_by(Collection.title)
 
     if request.method != 'POST' or not form.validate():
         # No POST submission, or invalid form
@@ -247,44 +249,50 @@ def media_collect(request, media):
     if form.collection_title.data:
         # Make sure this user isn't duplicating an existing collection
         existing_collection = Collection.query.filter_by(
-                                creator=request.user.id,
-                                title=form.collection_title.data).first()
+            actor=request.user.id,
+            title=form.collection_title.data,
+            type=Collection.USER_DEFINED_TYPE
+        ).first()
         if existing_collection:
             messages.add_message(request, messages.ERROR,
                 _('You already have a collection called "%s"!')
                 % existing_collection.title)
             return redirect(request, "mediagoblin.user_pages.media_home",
-                            user=media.get_uploader.username,
+                            user=media.get_actor.username,
                             media=media.slug_or_id)
 
         collection = Collection()
         collection.title = form.collection_title.data
         collection.description = form.collection_description.data
-        collection.creator = request.user.id
+        collection.actor = request.user.id
+        collection.type = Collection.USER_DEFINED_TYPE
         collection.generate_slug()
-        create_activity("create", collection, collection.creator)
+        create_activity("create", collection, collection.actor)
         collection.save()
 
     # Otherwise, use the collection selected from the drop-down
     else:
         collection = form.collection.data
-        if collection and collection.creator != request.user.id:
+        if collection and collection.actor != request.user.id:
             collection = None
 
     # Make sure the user actually selected a collection
+    item = CollectionItem.query.filter_by(collection=collection.id)
+    item = item.join(CollectionItem.object_helper).filter_by(
+        model_type=media.__tablename__,
+        obj_pk=media.id
+    ).first()
+
     if not collection:
         messages.add_message(
             request, messages.ERROR,
             _('You have to select or add a collection'))
         return redirect(request, "mediagoblin.user_pages.media_collect",
-                    user=media.get_uploader.username,
+                    user=media.get_actor.username,
                     media_id=media.id)
 
-
     # Check whether media already exists in collection
-    elif CollectionItem.query.filter_by(
-        media_entry=media.id,
-        collection=collection.id).first():
+    elif item is not None:
         messages.add_message(request, messages.ERROR,
                              _('"%s" already in collection "%s"')
                              % (media.title, collection.title))
@@ -308,11 +316,11 @@ def media_confirm_delete(request, media):
 
     if request.method == 'POST' and form.validate():
         if form.confirm.data is True:
-            username = media.get_uploader.username
+            username = media.get_actor.username
 
-            media.get_uploader.uploaded = media.get_uploader.uploaded - \
+            media.get_actor.uploaded = media.get_actor.uploaded - \
                 media.file_size
-            media.get_uploader.save()
+            media.get_actor.save()
 
             # Delete MediaEntry and all related files, comments etc.
             media.delete()
@@ -333,7 +341,7 @@ def media_confirm_delete(request, media):
             return redirect_obj(request, media)
 
     if ((request.user.has_privilege(u'admin') and
-         request.user.id != media.uploader)):
+         request.user.id != media.actor)):
         messages.add_message(
             request, messages.WARNING,
             _("You are about to delete another user's media. "
@@ -351,7 +359,7 @@ def media_confirm_delete(request, media):
 def user_collection(request, page, url_user=None):
     """A User-defined Collection"""
     collection = Collection.query.filter_by(
-        get_creator=url_user,
+        get_actor=url_user,
         slug=request.matchdict['collection']).first()
 
     if not collection:
@@ -380,7 +388,7 @@ def user_collection(request, page, url_user=None):
 def collection_list(request, url_user=None):
     """A User-defined Collection"""
     collections = Collection.query.filter_by(
-        get_creator=url_user)
+        get_actor=url_user)
 
     return render_to_response(
         request,
@@ -397,15 +405,15 @@ def collection_item_confirm_remove(request, collection_item):
     form = user_forms.ConfirmCollectionItemRemoveForm(request.form)
 
     if request.method == 'POST' and form.validate():
-        username = collection_item.in_collection.get_creator.username
+        username = collection_item.in_collection.get_actor.username
         collection = collection_item.in_collection
 
         if form.confirm.data is True:
-            entry = collection_item.get_media_entry
-            entry.save()
+            obj = collection_item.get_object()
+            obj.save()
 
             collection_item.delete()
-            collection.items = collection.items - 1
+            collection.num_items = collection.num_items - 1
             collection.save()
 
             messages.add_message(
@@ -418,7 +426,7 @@ def collection_item_confirm_remove(request, collection_item):
         return redirect_obj(request, collection)
 
     if ((request.user.has_privilege(u'admin') and
-         request.user.id != collection_item.in_collection.creator)):
+         request.user.id != collection_item.in_collection.actor)):
         messages.add_message(
             request, messages.WARNING,
             _("You are about to delete an item from another user's collection. "
@@ -440,15 +448,15 @@ def collection_confirm_delete(request, collection):
 
     if request.method == 'POST' and form.validate():
 
-        username = collection.get_creator.username
+        username = collection.get_actor.username
 
         if form.confirm.data is True:
             collection_title = collection.title
 
             # Delete all the associated collection items
             for item in collection.get_collection_items():
-                entry = item.get_media_entry
-                entry.save()
+                obj = item.get_object()
+                obj.save()
                 item.delete()
 
             collection.delete()
@@ -465,7 +473,7 @@ def collection_confirm_delete(request, collection):
             return redirect_obj(request, collection)
 
     if ((request.user.has_privilege(u'admin') and
-         request.user.id != collection.creator)):
+         request.user.id != collection.actor)):
         messages.add_message(
             request, messages.WARNING,
             _("You are about to delete another user's collection. "
@@ -491,7 +499,7 @@ def atom_feed(request):
         return render_404(request)
 
     cursor = MediaEntry.query.filter_by(
-        uploader = user.id,
+        actor = user.id,
         state = u'processed').\
         order_by(MediaEntry.created.desc()).\
         limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS)
@@ -523,15 +531,16 @@ def atom_feed(request):
                links=atomlinks)
 
     for entry in cursor:
-        feed.add(entry.get('title'),
+        feed.add(
+            entry.get('title'),
             entry.description_html,
             id=entry.url_for_self(request.urlgen, qualified=True),
             content_type='html',
             author={
-                'name': entry.get_uploader.username,
+                'name': entry.get_actor.username,
                 'uri': request.urlgen(
                     'mediagoblin.user_pages.user_home',
-                    qualified=True, user=entry.get_uploader.username)},
+                    qualified=True, user=entry.get_actor.username)},
             updated=entry.get('created'),
             links=[{
                 'href': entry.url_for_self(
@@ -553,7 +562,7 @@ def collection_atom_feed(request):
         return render_404(request)
 
     collection = Collection.query.filter_by(
-               creator=user.id,
+               actor=user.id,
                slug=request.matchdict['collection']).first()
     if not collection:
         return render_404(request)
@@ -591,19 +600,20 @@ def collection_atom_feed(request):
                 links=atomlinks)
 
     for item in cursor:
-        entry = item.get_media_entry
-        feed.add(entry.get('title'),
+        obj = item.get_object()
+        feed.add(
+            obj.get('title'),
             item.note_html,
-            id=entry.url_for_self(request.urlgen, qualified=True),
+            id=obj.url_for_self(request.urlgen, qualified=True),
             content_type='html',
             author={
-                'name': entry.get_uploader.username,
+                'name': obj.get_actor().username,
                 'uri': request.urlgen(
                     'mediagoblin.user_pages.user_home',
-                    qualified=True, user=entry.get_uploader.username)},
+                    qualified=True, user=obj.get_actor().username)},
             updated=item.get('added'),
             links=[{
-                'href': entry.url_for_self(
+                'href': obj.url_for_self(
                     request.urlgen,
                     qualified=True),
                 'rel': 'alternate',
@@ -630,18 +640,18 @@ def processing_panel(request):
 
     # Get media entries which are in-processing
     processing_entries = MediaEntry.query.\
-        filter_by(uploader = user.id,
+        filter_by(actor = user.id,
                   state = u'processing').\
         order_by(MediaEntry.created.desc())
 
     # Get media entries which have failed to process
     failed_entries = MediaEntry.query.\
-        filter_by(uploader = user.id,
+        filter_by(actor = user.id,
                   state = u'failed').\
         order_by(MediaEntry.created.desc())
 
     processed_entries = MediaEntry.query.\
-        filter_by(uploader = user.id,
+        filter_by(actor = user.id,
                   state = u'processed').\
         order_by(MediaEntry.created.desc()).\
         limit(10)
@@ -725,4 +735,3 @@ def activity_view(request):
         "mediagoblin/api/activity.html",
         {"activity": activity}
     )
-