From: Jessica Tallon Date: Thu, 17 Sep 2015 11:47:56 +0000 (+0200) Subject: Collection changes and migration for federation X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=0f3bf8d4b180ffd1907d1578e087522aad7d9158;p=mediagoblin.git Collection changes and migration for federation - 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 --- diff --git a/mediagoblin/api/views.py b/mediagoblin/api/views.py index 9c2876c2..d3eaacc9 100644 --- a/mediagoblin/api/views.py +++ b/mediagoblin/api/views.py @@ -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) - - diff --git a/mediagoblin/db/__init__.py b/mediagoblin/db/__init__.py index 719b56e7..621845ba 100644 --- a/mediagoblin/db/__init__.py +++ b/mediagoblin/db/__init__.py @@ -13,4 +13,3 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py index ce7174da..4e9d3a2a 100644 --- a/mediagoblin/db/migrations.py +++ b/mediagoblin/db/migrations.py @@ -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() diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index b954ab90..7960061e 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -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', diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 8c8e42e5..9f4a144c 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -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): diff --git a/mediagoblin/db/util.py b/mediagoblin/db/util.py index 7c026691..57e6b942 100644 --- a/mediagoblin/db/util.py +++ b/mediagoblin/db/util.py @@ -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) diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py index d20aca10..952b4572 100644 --- a/mediagoblin/decorators.py +++ b/mediagoblin/decorators.py @@ -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) diff --git a/mediagoblin/edit/lib.py b/mediagoblin/edit/lib.py index 6acebc96..3f52376a 100644 --- a/mediagoblin/edit/lib.py +++ b/mediagoblin/edit/lib.py @@ -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 diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index af0d0e9b..8e80b3ce 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -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, diff --git a/mediagoblin/gmg_commands/batchaddmedia.py b/mediagoblin/gmg_commands/batchaddmedia.py index ed733b9e..2ad7e39e 100644 --- a/mediagoblin/gmg_commands/batchaddmedia.py +++ b/mediagoblin/gmg_commands/batchaddmedia.py @@ -213,4 +213,3 @@ def parse_csv_file(file_contents): objects_dict[media_id] = (line_dict) return objects_dict - diff --git a/mediagoblin/listings/views.py b/mediagoblin/listings/views.py index 07dbb3d5..f640cc95 100644 --- a/mediagoblin/listings/views.py +++ b/mediagoblin/listings/views.py @@ -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( diff --git a/mediagoblin/media_types/blog/views.py b/mediagoblin/media_types/blog/views.py index b4f4fbc8..3502d7b8 100644 --- a/mediagoblin/media_types/blog/views.py +++ b/mediagoblin/media_types/blog/views.py @@ -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 }) - - - - - - - - diff --git a/mediagoblin/notifications/__init__.py b/mediagoblin/notifications/__init__.py index c7a9a1fb..ea468f8e 100644 --- a/mediagoblin/notifications/__init__.py +++ b/mediagoblin/notifications/__init__.py @@ -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( diff --git a/mediagoblin/notifications/tools.py b/mediagoblin/notifications/tools.py index 25432780..69017ed0 100644 --- a/mediagoblin/notifications/tools.py +++ b/mediagoblin/notifications/tools.py @@ -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', diff --git a/mediagoblin/plugins/api/tools.py b/mediagoblin/plugins/api/tools.py index 56256236..e406888e 100644 --- a/mediagoblin/plugins/api/tools.py +++ b/mediagoblin/plugins/api/tools.py @@ -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(), diff --git a/mediagoblin/plugins/archivalook/templates/archivalook/feature_media_sidebar.html b/mediagoblin/plugins/archivalook/templates/archivalook/feature_media_sidebar.html index c5b8a7d6..942a888b 100644 --- a/mediagoblin/plugins/archivalook/templates/archivalook/feature_media_sidebar.html +++ b/mediagoblin/plugins/archivalook/templates/archivalook/feature_media_sidebar.html @@ -21,7 +21,7 @@ {% if not media_feature %} @@ -29,7 +29,7 @@ Feature Media {% endtrans %}"> {% else %} @@ -37,7 +37,7 @@ Unfeature Media {% endtrans %}"> {% if not media_feature.display_type == 'primary' %} @@ -45,7 +45,7 @@ Promote Feature {% endtrans %}"> {% endif %}{% if not media_feature.display_type == 'tertiary' %} diff --git a/mediagoblin/plugins/archivalook/tools.py b/mediagoblin/plugins/archivalook/tools.py index fb5673e1..ad2eee5f 100644 --- a/mediagoblin/plugins/archivalook/tools.py +++ b/mediagoblin/plugins/archivalook/tools.py @@ -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) diff --git a/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html b/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html index 3a9d872c..15ea1536 100644 --- a/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html +++ b/mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html @@ -35,7 +35,7 @@ {% endif %} {% if request.user and request.user.has_privilege('admin') %} {% trans %}Edit Metadata{% endtrans %} {% endif %} diff --git a/mediagoblin/plugins/piwigo/views.py b/mediagoblin/plugins/piwigo/views.py index 1fe1e576..ab741a72 100644 --- a/mediagoblin/plugins/piwigo/views.py +++ b/mediagoblin/plugins/piwigo/views.py @@ -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 { diff --git a/mediagoblin/submit/lib.py b/mediagoblin/submit/lib.py index a0e1cf90..77dd836b 100644 --- a/mediagoblin/submit/lib.py +++ b/mediagoblin/submit/lib.py @@ -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() diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html index d1e33c47..84c9a02c 100644 --- a/mediagoblin/templates/mediagoblin/edit/attachments.html +++ b/mediagoblin/templates/mediagoblin/edit/attachments.html @@ -27,7 +27,7 @@ {% block mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit.html b/mediagoblin/templates/mediagoblin/edit/edit.html index 9a040095..5f2ba3c5 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit.html +++ b/mediagoblin/templates/mediagoblin/edit/edit.html @@ -28,7 +28,7 @@ {% block mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/edit/edit_collection.html b/mediagoblin/templates/mediagoblin/edit/edit_collection.html index 5cf5bae8..f150b306 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_collection.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_collection.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
@@ -36,4 +36,4 @@
-{% endblock %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html index 55759a39..68c42bf4 100644 --- a/mediagoblin/templates/mediagoblin/fragments/header_notifications.html +++ b/mediagoblin/templates/mediagoblin/fragments/header_notifications.html @@ -5,7 +5,7 @@
    {% 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 %}
  • @@ -17,7 +17,7 @@ @@ -36,7 +36,7 @@
  • {% endfor %}
- {% trans %}Mark all read{% endtrans %} diff --git a/mediagoblin/templates/mediagoblin/moderation/media_panel.html b/mediagoblin/templates/mediagoblin/moderation/media_panel.html index 9b77f638..888e4feb 100644 --- a/mediagoblin/templates/mediagoblin/moderation/media_panel.html +++ b/mediagoblin/templates/mediagoblin/moderation/media_panel.html @@ -44,7 +44,7 @@ {% for media_entry in processing_entries %} {{ media_entry.id }} - {{ media_entry.get_uploader.username }} + {{ media_entry.get_actor.username }} {{ media_entry.title }} {{ media_entry.created.strftime("%F %R") }} {% if media_entry.transcoding_progress %} @@ -74,7 +74,7 @@ {% for media_entry in failed_entries %} {{ media_entry.id }} - {{ media_entry.get_uploader.username }} + {{ media_entry.get_actor.username }} {{ media_entry.title }} {{ media_entry.created.strftime("%F %R") }} {% if media_entry.get_fail_exception() %} @@ -103,7 +103,7 @@ {% for media_entry in processed_entries %} {{ media_entry.id }} - {{ media_entry.get_uploader.username }} + {{ media_entry.get_actor.username }} {{ media_entry.title }} {{ timesince(media_entry.created) }} diff --git a/mediagoblin/templates/mediagoblin/moderation/report.html b/mediagoblin/templates/mediagoblin/moderation/report.html index 496610ad..584dca99 100644 --- a/mediagoblin/templates/mediagoblin/moderation/report.html +++ b/mediagoblin/templates/mediagoblin/moderation/report.html @@ -37,20 +37,20 @@ {% trans %}Reported comment{% endtrans %}: {% set comment = report.comment %} - {% set reported_user = comment.get_author %} + {% set reported_user = comment.get_actor %} - {% 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')) %}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/blog_media.html b/mediagoblin/templates/mediagoblin/user_pages/blog_media.html index c6eedee0..ece47fe1 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/blog_media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/blog_media.html @@ -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) %} {% trans %}Edit{% endtrans %} {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', @@ -107,7 +107,7 @@ {% endif %}
    {% for comment in comments %} - {% set comment_author = comment.get_author %} + {% set comment_author = comment.get_actor %}
  • @@ -148,7 +148,7 @@

    {% trans %}Added{% endtrans %}

    - {%- trans formatted_time=timesince(media.created) -%} + {%- trans formatted_time=timesince(media.created) -%} {{ formatted_time }} ago {%- endtrans -%}

    diff --git a/mediagoblin/templates/mediagoblin/user_pages/collection.html b/mediagoblin/templates/mediagoblin/user_pages/collection.html index 0f712c01..71ba4451 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/collection.html +++ b/mediagoblin/templates/mediagoblin/user_pages/collection.html @@ -44,14 +44,14 @@ {{ collection_title }} by {{ username }} {%- endtrans %} - {% 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) %} {% trans %}Edit{% endtrans %} {% set delete_url = request.urlgen('mediagoblin.user_pages.collection_confirm_delete', - user=collection.get_creator.username, + user=collection.get_actor.username, collection=collection.slug) %} {% trans %}Delete{% endtrans %} {% endif %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html index 8cfe4b29..08278349 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/collection_confirm_delete.html @@ -30,7 +30,7 @@ {% block mediagoblin_content %}
    @@ -39,9 +39,9 @@ Really delete collection: {{ title }}? {%- endtrans %} - +
    - +

    {{ form.confirm }} {{ wtforms_util.render_label(form.confirm) }} @@ -58,4 +58,4 @@

  • -{% endblock %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html b/mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html index 84d3eb4c..d7ff4950 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html +++ b/mediagoblin/templates/mediagoblin/user_pages/collection_item_confirm_remove.html @@ -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 %} — {{ super() }} @@ -30,20 +30,20 @@ {% block mediagoblin_content %}

    - {%- 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 %}

    - +

    @@ -64,4 +64,4 @@
-{% endblock %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html index 16ddd62c..b74ca13e 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media.html @@ -38,8 +38,8 @@

{%- 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 {{username}} {%- endtrans -%}

@@ -76,15 +76,15 @@ {{ media.title }} {% if request.user and - (media.uploader == request.user.id or + (media.actor == request.user.id or request.user.has_privilege('admin')) %}
{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', - user= media.get_uploader.username, + user= media.get_actor.username, media_id=media.id) %} {% trans %}Edit{% endtrans %} {% 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) %} {% trans %}Delete{% endtrans %}
@@ -109,7 +109,7 @@ {% endif %} {% if request.user %}
{{ wtforms_util.render_divs(comment_form) }}
@@ -123,7 +123,7 @@ {% endif %}
    {% for comment in comments %} - {% set comment_author = comment.get_author %} + {% set comment_author = comment.get_actor %}
  • @@ -140,7 +140,7 @@ @@ -157,7 +157,7 @@
    {% if app_config.allow_reporting %} {% trans %}Report{% endtrans %} @@ -215,14 +215,14 @@ {%- 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 %}

    {% trans %}Attachments{% endtrans %}

    {%- endif %}

    {%- trans %}Add attachment{% endtrans -%} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_collect.html b/mediagoblin/templates/mediagoblin/user_pages/media_collect.html index b4c9671c..ba7424d1 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_collect.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_collect.html @@ -32,7 +32,7 @@ {% block mediagoblin_content %}

    @@ -70,4 +70,4 @@
  • -{% endblock %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html index c948ccec..243edff5 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html +++ b/mediagoblin/templates/mediagoblin/user_pages/media_confirm_delete.html @@ -22,7 +22,7 @@ {% block mediagoblin_content %}
    @@ -51,4 +51,4 @@
-{% endblock %} +{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/user_pages/report.html b/mediagoblin/templates/mediagoblin/user_pages/report.html index 6f25b996..09502fcf 100644 --- a/mediagoblin/templates/mediagoblin/user_pages/report.html +++ b/mediagoblin/templates/mediagoblin/user_pages/report.html @@ -22,14 +22,14 @@
{% if comment is defined %}

{% trans %}Reporting this Comment{% endtrans %}

- {%- 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) %}
@@ -60,17 +60,17 @@

{% trans %}Reporting this Media Entry{% endtrans %}

- {%- 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 {{ username }} {% endtrans %} diff --git a/mediagoblin/templates/mediagoblin/utils/collection_gallery.html b/mediagoblin/templates/mediagoblin/utils/collection_gallery.html index 64b30815..86680cb6 100644 --- a/mediagoblin/templates/mediagoblin/utils/collection_gallery.html +++ b/mediagoblin/templates/mediagoblin/utils/collection_gallery.html @@ -25,24 +25,24 @@ {%- 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) %}
- - + + {% if item.note %} - {{ item.note }} + {{ item.note }} {% 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) -%} diff --git a/mediagoblin/templates/mediagoblin/utils/collections.html b/mediagoblin/templates/mediagoblin/utils/collections.html index 69738e26..5e209d60 100644 --- a/mediagoblin/templates/mediagoblin/utils/collections.html +++ b/mediagoblin/templates/mediagoblin/utils/collections.html @@ -26,15 +26,15 @@ {%- endif %} {{- collection.title }} ( - {{- collection.get_creator.username -}} + {{- collection.get_actor.username -}} ) {%- endfor %}

{%- endif %} {%- if request.user %}

- {% trans %}Add to a collection{% endtrans %} diff --git a/mediagoblin/templates/mediagoblin/utils/comment-subscription.html b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html index 5c50c801..54663f05 100644 --- a/mediagoblin/templates/mediagoblin/utils/comment-subscription.html +++ b/mediagoblin/templates/mediagoblin/utils/comment-subscription.html @@ -19,13 +19,13 @@ {% set subscription = get_comment_subscription(request.user.id, media.id) %} {% if not subscription or not subscription.notify %} {% trans %}Subscribe to comments{% endtrans %} {% else %} {% trans %}Silence comments{% endtrans %} diff --git a/mediagoblin/templates/mediagoblin/utils/report.html b/mediagoblin/templates/mediagoblin/utils/report.html index 3829de97..8da2be7d 100644 --- a/mediagoblin/templates/mediagoblin/utils/report.html +++ b/mediagoblin/templates/mediagoblin/utils/report.html @@ -19,7 +19,7 @@ {% block report_content -%}

{% trans %}Report media{% endtrans %} diff --git a/mediagoblin/templates/mediagoblin/utils/tags.html b/mediagoblin/templates/mediagoblin/utils/tags.html index bb4bd1a5..5fc5dd8f 100644 --- a/mediagoblin/templates/mediagoblin/utils/tags.html +++ b/mediagoblin/templates/mediagoblin/utils/tags.html @@ -28,17 +28,17 @@ {{ tag['name'] }} + user=media.get_actor.username) }}">{{ tag['name'] }} {% elif loop.revindex == 2 %} {{ tag['name'] }} + user=media.get_actor.username) }}">{{ tag['name'] }} {% else %} {{ tag['name'] }} + user=media.get_actor.username) }}">{{ tag['name'] }} · {% endif %} {% endfor %} diff --git a/mediagoblin/tests/test_api.py b/mediagoblin/tests/test_api.py index 83003875..b58e112f 100644 --- a/mediagoblin/tests/test_api.py +++ b/mediagoblin/tests/test_api.py @@ -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"] - diff --git a/mediagoblin/tests/test_misc.py b/mediagoblin/tests/test_misc.py index b3e59c09..2bff0057 100644 --- a/mediagoblin/tests/test_misc.py +++ b/mediagoblin/tests/test_misc.py @@ -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) diff --git a/mediagoblin/tests/test_modelmethods.py b/mediagoblin/tests/test_modelmethods.py index 9e0d017c..4c66e27b 100644 --- a/mediagoblin/tests/test_modelmethods.py +++ b/mediagoblin/tests/test_modelmethods.py @@ -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: diff --git a/mediagoblin/tests/test_moderation.py b/mediagoblin/tests/test_moderation.py index 1b071723..85c130ca 100644 --- a/mediagoblin/tests/test_moderation.py +++ b/mediagoblin/tests/test_moderation.py @@ -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 diff --git a/mediagoblin/tests/test_notifications.py b/mediagoblin/tests/test_notifications.py index 385da569..f7e67d80 100644 --- a/mediagoblin/tests/test_notifications.py +++ b/mediagoblin/tests/test_notifications.py @@ -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: diff --git a/mediagoblin/tests/test_reporting.py b/mediagoblin/tests/test_reporting.py index 1f4573cf..f036303a 100644 --- a/mediagoblin/tests/test_reporting.py +++ b/mediagoblin/tests/test_reporting.py @@ -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' - diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 6c974c39..ba143acd 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -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 diff --git a/mediagoblin/user_pages/lib.py b/mediagoblin/user_pages/lib.py index 5b411a82..fc1b6a7e 100644 --- a/mediagoblin/user_pages/lib.py +++ b/mediagoblin/user_pages/lib.py @@ -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 diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 33ca7c40..4ee601b3 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -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} ) -