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
This commit is contained in:
Jessica Tallon 2015-09-17 13:47:56 +02:00
parent 80ba8ad1d1
commit 0f3bf8d4b1
48 changed files with 437 additions and 250 deletions

View File

@ -268,7 +268,7 @@ def feed_endpoint(request, outbox=None):
status=403 status=403
) )
comment = MediaComment(author=request.user.id) comment = MediaComment(actor=request.user.id)
comment.unserialize(data["object"], request) comment.unserialize(data["object"], request)
comment.save() comment.save()
@ -299,7 +299,7 @@ def feed_endpoint(request, outbox=None):
status=404 status=404
) )
if media.uploader != request.user.id: if media.actor != request.user.id:
return json_error( return json_error(
"Privilege 'commenter' required to comment.", "Privilege 'commenter' required to comment.",
status=403 status=403
@ -366,7 +366,7 @@ def feed_endpoint(request, outbox=None):
# Check that the person trying to update the comment is # Check that the person trying to update the comment is
# the author of the comment. # the author of the comment.
if comment.author != request.user.id: if comment.actor != request.user.id:
return json_error( return json_error(
"Only author of comment is able to update comment.", "Only author of comment is able to update comment.",
status=403 status=403
@ -399,7 +399,7 @@ def feed_endpoint(request, outbox=None):
# Check that the person trying to update the comment is # Check that the person trying to update the comment is
# the author of the comment. # the author of the comment.
if image.uploader != request.user.id: if image.actor != request.user.id:
return json_error( return json_error(
"Only uploader of image is able to update image.", "Only uploader of image is able to update image.",
status=403 status=403
@ -463,7 +463,7 @@ def feed_endpoint(request, outbox=None):
# Find the comment asked for # Find the comment asked for
comment = MediaComment.query.filter_by( comment = MediaComment.query.filter_by(
id=obj_id, id=obj_id,
author=request.user.id actor=request.user.id
).first() ).first()
if comment is None: if comment is None:
@ -492,7 +492,7 @@ def feed_endpoint(request, outbox=None):
# Find the image # Find the image
entry = MediaEntry.query.filter_by( entry = MediaEntry.query.filter_by(
id=obj_id, id=obj_id,
uploader=request.user.id actor=request.user.id
).first() ).first()
if entry is None: if entry is None:
@ -792,5 +792,3 @@ def whoami(request):
) )
return redirect(request, location=profile) return redirect(request, location=profile)

View File

@ -13,4 +13,3 @@
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@ -1676,3 +1676,147 @@ def create_oauth1_dummies(db):
# Commit the changes # Commit the changes
db.commit() 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()

View File

@ -134,7 +134,7 @@ class MediaEntryMixin(GenerateSlugMixin):
# (db.models -> db.mixin -> db.util -> db.models) # (db.models -> db.mixin -> db.util -> db.models)
from mediagoblin.db.util import check_media_slug_used 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 @property
def object_type(self): def object_type(self):
@ -188,7 +188,7 @@ class MediaEntryMixin(GenerateSlugMixin):
Use a slug if we have one, else use our 'id'. Use a slug if we have one, else use our 'id'.
""" """
uploader = self.get_uploader uploader = self.get_actor
return urlgen( return urlgen(
'mediagoblin.user_pages.media_home', 'mediagoblin.user_pages.media_home',
@ -338,17 +338,17 @@ class MediaCommentMixin(object):
return cleaned_markdown_conversion(self.content) return cleaned_markdown_conversion(self.content)
def __unicode__(self): def __unicode__(self):
return u'<{klass} #{id} {author} "{comment}">'.format( return u'<{klass} #{id} {actor} "{comment}">'.format(
klass=self.__class__.__name__, klass=self.__class__.__name__,
id=self.id, id=self.id,
author=self.get_author, actor=self.get_actor,
comment=self.content) comment=self.content)
def __repr__(self): def __repr__(self):
return '<{klass} #{id} {author} "{comment}">'.format( return '<{klass} #{id} {actor} "{comment}">'.format(
klass=self.__class__.__name__, klass=self.__class__.__name__,
id=self.id, id=self.id,
author=self.get_author, actor=self.get_actor,
comment=self.content) comment=self.content)
@ -360,7 +360,7 @@ class CollectionMixin(GenerateSlugMixin):
# (db.models -> db.mixin -> db.util -> db.models) # (db.models -> db.mixin -> db.util -> db.models)
from mediagoblin.db.util import check_collection_slug_used 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 @property
def description_html(self): def description_html(self):
@ -380,7 +380,7 @@ class CollectionMixin(GenerateSlugMixin):
Use a slug if we have one, else use our 'id'. Use a slug if we have one, else use our 'id'.
""" """
creator = self.get_creator creator = self.get_actor
return urlgen( return urlgen(
'mediagoblin.user_pages.user_collection', 'mediagoblin.user_pages.user_collection',

View File

@ -29,6 +29,7 @@ from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
from sqlalchemy.orm import relationship, backref, with_polymorphic, validates, \ from sqlalchemy.orm import relationship, backref, with_polymorphic, validates, \
class_mapper class_mapper
from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.sql import and_
from sqlalchemy.sql.expression import desc from sqlalchemy.sql.expression import desc
from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.util import memoized_property from sqlalchemy.util import memoized_property
@ -257,7 +258,7 @@ class User(Base, UserMixin):
"""Deletes a User and all related entries/comments/files/...""" """Deletes a User and all related entries/comments/files/..."""
# Collections get deleted by relationships. # 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: for media in media_entries:
# TODO: Make sure that "MediaEntry.delete()" also deletes # TODO: Make sure that "MediaEntry.delete()" also deletes
# all related files/Comments # all related files/Comments
@ -455,7 +456,7 @@ class RequestToken(Base):
token = Column(Unicode, primary_key=True) token = Column(Unicode, primary_key=True)
secret = Column(Unicode, nullable=False) secret = Column(Unicode, nullable=False)
client = Column(Unicode, ForeignKey(Client.id)) 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) used = Column(Boolean, default=False)
authenticated = Column(Boolean, default=False) authenticated = Column(Boolean, default=False)
verifier = Column(Unicode, nullable=True) verifier = Column(Unicode, nullable=True)
@ -473,7 +474,7 @@ class AccessToken(Base):
token = Column(Unicode, nullable=False, primary_key=True) token = Column(Unicode, nullable=False, primary_key=True)
secret = Column(Unicode, nullable=False) secret = Column(Unicode, nullable=False)
user = Column(Integer, ForeignKey(User.id)) actor = Column(Integer, ForeignKey(User.id))
request_token = Column(Unicode, ForeignKey(RequestToken.token)) request_token = Column(Unicode, ForeignKey(RequestToken.token))
created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow) created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
updated = 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) public_id = Column(Unicode, unique=True, nullable=True)
remote = Column(Boolean, default=False) 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) title = Column(Unicode, nullable=False)
slug = Column(Unicode) slug = Column(Unicode)
description = Column(UnicodeText) # ?? description = Column(UnicodeText) # ??
@ -526,10 +527,10 @@ class MediaEntry(Base, MediaEntryMixin):
queued_task_id = Column(Unicode) queued_task_id = Column(Unicode)
__table_args__ = ( __table_args__ = (
UniqueConstraint('uploader', 'slug'), UniqueConstraint('actor', 'slug'),
{}) {})
get_uploader = relationship(User) get_actor = relationship(User)
media_files_helper = relationship("MediaFile", media_files_helper = relationship("MediaFile",
collection_class=attribute_mapped_collection("name"), collection_class=attribute_mapped_collection("name"),
@ -555,16 +556,24 @@ class MediaEntry(Base, MediaEntryMixin):
creator=lambda v: MediaTag(name=v["name"], slug=v["slug"]) 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), media_metadata = Column(MutationDict.as_mutable(JSONEncoded),
default=MutationDict()) default=MutationDict())
## TODO ## TODO
# fail_error # 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): def get_comments(self, ascending=False):
order_col = MediaComment.created order_col = MediaComment.created
if not ascending: if not ascending:
@ -574,7 +583,7 @@ class MediaEntry(Base, MediaEntryMixin):
def url_to_prev(self, urlgen): def url_to_prev(self, urlgen):
"""get the next 'newer' entry by this user""" """get the next 'newer' entry by this user"""
media = MediaEntry.query.filter( media = MediaEntry.query.filter(
(MediaEntry.uploader == self.uploader) (MediaEntry.actor == self.actor)
& (MediaEntry.state == u'processed') & (MediaEntry.state == u'processed')
& (MediaEntry.id > self.id)).order_by(MediaEntry.id).first() & (MediaEntry.id > self.id)).order_by(MediaEntry.id).first()
@ -584,7 +593,7 @@ class MediaEntry(Base, MediaEntryMixin):
def url_to_next(self, urlgen): def url_to_next(self, urlgen):
"""get the next 'older' entry by this user""" """get the next 'older' entry by this user"""
media = MediaEntry.query.filter( media = MediaEntry.query.filter(
(MediaEntry.uploader == self.uploader) (MediaEntry.actor == self.actor)
& (MediaEntry.state == u'processed') & (MediaEntry.state == u'processed')
& (MediaEntry.id < self.id)).order_by(desc(MediaEntry.id)).first() & (MediaEntry.id < self.id)).order_by(desc(MediaEntry.id)).first()
@ -675,7 +684,7 @@ class MediaEntry(Base, MediaEntryMixin):
except OSError as error: except OSError as error:
# Returns list of files we failed to delete # Returns list of files we failed to delete
_log.error('No such files from the user "{1}" 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)) _log.info('Deleted Media entry id "{0}"'.format(self.id))
# Related MediaTag's are automatically cleaned, but we might # Related MediaTag's are automatically cleaned, but we might
# want to clean out unused Tag's too. # want to clean out unused Tag's too.
@ -689,7 +698,7 @@ class MediaEntry(Base, MediaEntryMixin):
def serialize(self, request, show_comments=True): def serialize(self, request, show_comments=True):
""" Unserialize MediaEntry to object """ """ Unserialize MediaEntry to object """
author = self.get_uploader author = self.get_actor
published = UTC.localize(self.created) published = UTC.localize(self.created)
updated = UTC.localize(self.updated) updated = UTC.localize(self.updated)
public_id = self.get_public_id(request) public_id = self.get_public_id(request)
@ -898,7 +907,7 @@ class MediaComment(Base, MediaCommentMixin):
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
media_entry = Column( media_entry = Column(
Integer, ForeignKey(MediaEntry.id), nullable=False, index=True) 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) created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
content = Column(UnicodeText, nullable=False) content = Column(UnicodeText, nullable=False)
location = Column(Integer, ForeignKey("core__locations.id")) 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. # Cascade: Comments are owned by their creator. So do the full thing.
# lazy=dynamic: People might post a *lot* of comments, # lazy=dynamic: People might post a *lot* of comments,
# so make the "posted_comments" a query-like thing. # so make the "posted_comments" a query-like thing.
get_author = relationship(User, get_actor = relationship(User,
backref=backref("posted_comments", backref=backref("posted_comments",
lazy="dynamic", lazy="dynamic",
cascade="all, delete-orphan")) cascade="all, delete-orphan"))
@ -934,7 +943,7 @@ class MediaComment(Base, MediaCommentMixin):
qualified=True qualified=True
) )
media = MediaEntry.query.filter_by(id=self.media_entry).first() media = MediaEntry.query.filter_by(id=self.media_entry).first()
author = self.get_author author = self.get_actor
published = UTC.localize(self.created) published = UTC.localize(self.created)
context = { context = {
"id": href, "id": href,
@ -981,7 +990,15 @@ class MediaComment(Base, MediaCommentMixin):
class Collection(Base, CollectionMixin): 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 On deletion, contained CollectionItems get automatically reaped via
SQL cascade""" SQL cascade"""
@ -992,23 +1009,37 @@ class Collection(Base, CollectionMixin):
slug = Column(Unicode) slug = Column(Unicode)
created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow, created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow,
index=True) index=True)
updated = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
description = Column(UnicodeText) 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")) location = Column(Integer, ForeignKey("core__locations.id"))
get_location = relationship("Location", lazy="joined") 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. # Cascade: Collections are owned by their creator. So do the full thing.
get_creator = relationship(User, get_actor = relationship(User,
backref=backref("collections", backref=backref("collections",
cascade="all, delete-orphan")) cascade="all, delete-orphan"))
__table_args__ = ( __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): def get_collection_items(self, ascending=False):
#TODO, is this still needed with self.collection_items being available? #TODO, is this still needed with self.collection_items being available?
order_col = CollectionItem.position order_col = CollectionItem.position
@ -1019,18 +1050,15 @@ class Collection(Base, CollectionMixin):
def __repr__(self): def __repr__(self):
safe_title = self.title.encode('ascii', 'replace') safe_title = self.title.encode('ascii', 'replace')
return '<{classname} #{id}: {title} by {creator}>'.format( return '<{classname} #{id}: {title} by {actor}>'.format(
id=self.id, id=self.id,
classname=self.__class__.__name__, classname=self.__class__.__name__,
creator=self.creator, actor=self.actor,
title=safe_title) title=safe_title)
def serialize(self, request): def serialize(self, request):
# Get all serialized output in a list # Get all serialized output in a list
items = [] items = [i.serialize(request) for i in self.get_collection_items()]
for item in self.get_collection_items():
items.append(item.serialize(request))
return { return {
"totalItems": self.items, "totalItems": self.items,
"url": self.url_for_self(request.urlgen, qualified=True), "url": self.url_for_self(request.urlgen, qualified=True),
@ -1042,23 +1070,36 @@ class CollectionItem(Base, CollectionItemMixin):
__tablename__ = "core__collection_items" __tablename__ = "core__collection_items"
id = Column(Integer, primary_key=True) 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) collection = Column(Integer, ForeignKey(Collection.id), nullable=False)
note = Column(UnicodeText, nullable=True) note = Column(UnicodeText, nullable=True)
added = Column(DateTime, nullable=False, default=datetime.datetime.utcnow) added = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)
position = Column(Integer) position = Column(Integer)
# Cascade: CollectionItems are owned by their Collection. So do the full thing. # Cascade: CollectionItems are owned by their Collection. So do the full thing.
in_collection = relationship(Collection, in_collection = relationship(Collection,
backref=backref( backref=backref(
"collection_items", "collection_items",
cascade="all, delete-orphan")) 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__ = ( __table_args__ = (
UniqueConstraint('collection', 'media_entry'), UniqueConstraint('collection', 'object_id'),
{}) {})
@property @property
@ -1067,14 +1108,15 @@ class CollectionItem(Base, CollectionItemMixin):
return DictReadAttrProxy(self) return DictReadAttrProxy(self)
def __repr__(self): def __repr__(self):
return '<{classname} #{id}: Entry {entry} in {collection}>'.format( return '<{classname} #{id}: Object {obj} in {collection}>'.format(
id=self.id, id=self.id,
classname=self.__class__.__name__, classname=self.__class__.__name__,
collection=self.collection, collection=self.collection,
entry=self.media_entry) obj=self.get_object()
)
def serialize(self, request): def serialize(self, request):
return self.get_media_entry.serialize(request) return self.get_object().serialize(request)
class ProcessingMetaData(Base): class ProcessingMetaData(Base):

View File

@ -37,7 +37,7 @@ def atomic_update(table, query_dict, update_values):
def check_media_slug_used(uploader_id, slug, ignore_m_id): 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: if ignore_m_id is not None:
query = query.filter(MediaEntry.id != ignore_m_id) query = query.filter(MediaEntry.id != ignore_m_id)
does_exist = query.first() is not None 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): def check_collection_slug_used(creator_id, slug, ignore_c_id):
filt = (Collection.creator == creator_id) \ filt = (Collection.actor == creator_id) \
& (Collection.slug == slug) & (Collection.slug == slug)
if ignore_c_id is not None: if ignore_c_id is not None:
filt = filt & (Collection.id != ignore_c_id) filt = filt & (Collection.id != ignore_c_id)

View File

@ -126,7 +126,7 @@ def user_may_delete_media(controller):
""" """
@wraps(controller) @wraps(controller)
def wrapper(request, *args, **kwargs): def wrapper(request, *args, **kwargs):
uploader_id = kwargs['media'].uploader uploader_id = kwargs['media'].actor
if not (request.user.has_privilege(u'admin') or if not (request.user.has_privilege(u'admin') or
request.user.id == uploader_id): request.user.id == uploader_id):
raise Forbidden() raise Forbidden()
@ -192,7 +192,7 @@ def get_user_media_entry(controller):
media = MediaEntry.query.filter_by( media = MediaEntry.query.filter_by(
id=int(media_slug[3:]), id=int(media_slug[3:]),
state=u'processed', state=u'processed',
uploader=user.id).first() actor=user.id).first()
except ValueError: except ValueError:
raise NotFound() raise NotFound()
else: else:
@ -200,7 +200,7 @@ def get_user_media_entry(controller):
media = MediaEntry.query.filter_by( media = MediaEntry.query.filter_by(
slug=media_slug, slug=media_slug,
state=u'processed', state=u'processed',
uploader=user.id).first() actor=user.id).first()
if not media: if not media:
# Didn't find anything? Okay, 404. # Didn't find anything? Okay, 404.
@ -225,7 +225,7 @@ def get_user_collection(controller):
collection = request.db.Collection.query.filter_by( collection = request.db.Collection.query.filter_by(
slug=request.matchdict['collection'], slug=request.matchdict['collection'],
creator=user.id).first() actor=user.id).first()
# Still no collection? Okay, 404. # Still no collection? Okay, 404.
if not collection: if not collection:
@ -274,7 +274,7 @@ def get_media_entry_by_id(controller):
return render_404(request) return render_404(request)
given_username = request.matchdict.get('user') 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 render_404(request)
return controller(request, media=media, *args, **kwargs) return controller(request, media=media, *args, **kwargs)

View File

@ -17,7 +17,7 @@
def may_edit_media(request, media): def may_edit_media(request, media):
"""Check, if the request's user may edit the media details""" """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 return True
if request.user.has_privilege(u'admin'): if request.user.has_privilege(u'admin'):
return True return True

View File

@ -73,7 +73,7 @@ def edit_media(request, media):
# Make sure there isn't already a MediaEntry with such a slug # Make sure there isn't already a MediaEntry with such a slug
# and userid. # and userid.
slug = slugify(form.slug.data) 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: if slug_used:
form.slug.errors.append( form.slug.errors.append(
@ -350,12 +350,12 @@ def edit_collection(request, collection):
if request.method == 'POST' and form.validate(): if request.method == 'POST' and form.validate():
# Make sure there isn't already a Collection with such a slug # Make sure there isn't already a Collection with such a slug
# and userid. # and userid.
slug_used = check_collection_slug_used(collection.creator, slug_used = check_collection_slug_used(collection.actor,
form.slug.data, collection.id) form.slug.data, collection.id)
# Make sure there isn't already a Collection with this title # Make sure there isn't already a Collection with this title
existing_collection = request.db.Collection.query.filter_by( existing_collection = request.db.Collection.query.filter_by(
creator=request.user.id, actor=request.user.id,
title=form.title.data).first() title=form.title.data).first()
if existing_collection and existing_collection.id != collection.id: if existing_collection and existing_collection.id != collection.id:
@ -376,7 +376,7 @@ def edit_collection(request, collection):
return redirect_obj(request, collection) return redirect_obj(request, collection)
if request.user.has_privilege(u'admin') \ if request.user.has_privilege(u'admin') \
and collection.creator != request.user.id \ and collection.actor != request.user.id \
and request.method != 'POST': and request.method != 'POST':
messages.add_message( messages.add_message(
request, messages.WARNING, request, messages.WARNING,

View File

@ -213,4 +213,3 @@ def parse_csv_file(file_contents):
objects_dict[media_id] = (line_dict) objects_dict[media_id] = (line_dict)
return objects_dict return objects_dict

View File

@ -106,10 +106,10 @@ def atom_feed(request):
entry.description_html, entry.description_html,
id=entry.url_for_self(request.urlgen,qualified=True), id=entry.url_for_self(request.urlgen,qualified=True),
content_type='html', content_type='html',
author={'name': entry.get_uploader.username, author={'name': entry.get_actor.username,
'uri': request.urlgen( 'uri': request.urlgen(
'mediagoblin.user_pages.user_home', 'mediagoblin.user_pages.user_home',
qualified=True, user=entry.get_uploader.username)}, qualified=True, user=entry.get_actor.username)},
updated=entry.get('created'), updated=entry.get('created'),
links=[{ links=[{
'href':entry.url_for_self( 'href':entry.url_for_self(

View File

@ -54,7 +54,7 @@ from mediagoblin.notifications import add_comment_subscription
@require_active_login @require_active_login
def blog_edit(request): 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. if user have not exceeded maximum allowed acount of blogs.
""" """
url_user = request.matchdict.get('user', None) url_user = request.matchdict.get('user', None)
@ -171,7 +171,7 @@ def blogpost_create(request):
@require_active_login @require_active_login
def blogpost_edit(request): def blogpost_edit(request):
blog_slug = request.matchdict.get('blog_slug', None) blog_slug = request.matchdict.get('blog_slug', None)
blog_post_slug = request.matchdict.get('blog_post_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_owner': url_user,
'blog':blog 'blog':blog
}) })
@require_active_login @require_active_login
def draft_view(request): def draft_view(request):
@ -348,23 +348,23 @@ def blog_delete(request, **kwargs):
_("The blog was not deleted because you have no rights.")) _("The blog was not deleted because you have no rights."))
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard", return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
user=request.user.username) user=request.user.username)
def blog_about_view(request): def blog_about_view(request):
""" """
Page containing blog description and statistics Page containing blog description and statistics
""" """
blog_slug = request.matchdict.get('blog_slug', None) blog_slug = request.matchdict.get('blog_slug', None)
url_user = request.matchdict.get('user', None) url_user = request.matchdict.get('user', None)
user = request.db.User.query.filter( user = request.db.User.query.filter(
LocalUser.username=url_user LocalUser.username=url_user
).first() ).first()
blog = get_blog_by_slug(request, blog_slug, author=user.id) blog = get_blog_by_slug(request, blog_slug, author=user.id)
if not user or not blog: if not user or not blog:
return render_404(request) return render_404(request)
else: else:
blog_posts_processed = blog.get_all_blog_posts(u'processed').count() blog_posts_processed = blog.get_all_blog_posts(u'processed').count()
return render_to_response( return render_to_response(
@ -374,11 +374,3 @@ def blog_about_view(request):
'blog': blog, 'blog': blog,
'blogpost_count': blog_posts_processed 'blogpost_count': blog_posts_processed
}) })

View File

@ -34,7 +34,7 @@ def trigger_notification(comment, media_entry, request):
if not subscription.notify: if not subscription.notify:
continue continue
if comment.get_author == subscription.user: if comment.get_actor == subscription.user:
continue continue
cn = CommentNotification( cn = CommentNotification(

View File

@ -32,11 +32,11 @@ def generate_comment_message(user, comment, media, request):
comment_url = request.urlgen( comment_url = request.urlgen(
'mediagoblin.user_pages.media_home.view_comment', 'mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, comment=comment.id,
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id, media=media.slug_or_id,
qualified=True) + '#comment' qualified=True) + '#comment'
comment_author = comment.get_author.username comment_author = comment.get_actor.username
rendered_email = render_template( rendered_email = render_template(
request, 'mediagoblin/user_pages/comment_email.txt', request, 'mediagoblin/user_pages/comment_email.txt',

View File

@ -62,12 +62,12 @@ def get_entry_serializable(entry, urlgen):
to views. to views.
''' '''
return { return {
'user': entry.get_uploader.username, 'user': entry.get_actor.username,
'user_id': entry.get_uploader.id, 'user_id': entry.get_actor.id,
'user_bio': entry.get_uploader.bio, 'user_bio': entry.get_actor.bio,
'user_bio_html': entry.get_uploader.bio_html, 'user_bio_html': entry.get_actor.bio_html,
'user_permalink': urlgen('mediagoblin.user_pages.user_home', 'user_permalink': urlgen('mediagoblin.user_pages.user_home',
user=entry.get_uploader.username, user=entry.get_actor.username,
qualified=True), qualified=True),
'id': entry.id, 'id': entry.id,
'created': entry.created.isoformat(), 'created': entry.created.isoformat(),

View File

@ -21,7 +21,7 @@
{% if not media_feature %} {% if not media_feature %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.media_feature', 'mediagoblin.user_pages.media_feature',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}" media=media.slug_or_id) }}"
class="button_action" id="button_featuremedia" title="{% trans %} class="button_action" id="button_featuremedia" title="{% trans %}
Feature Media {% endtrans %}"> Feature Media {% endtrans %}">
@ -29,7 +29,7 @@ Feature Media {% endtrans %}">
{% else %} {% else %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.media_unfeature', 'mediagoblin.user_pages.media_unfeature',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}" media=media.slug_or_id) }}"
class="button_action" id="button_unfeaturemedia" title="{% trans %} class="button_action" id="button_unfeaturemedia" title="{% trans %}
Unfeature Media {% endtrans %}"> Unfeature Media {% endtrans %}">
@ -37,7 +37,7 @@ Unfeature Media {% endtrans %}">
{% if not media_feature.display_type == 'primary' %} {% if not media_feature.display_type == 'primary' %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.feature_promote', 'mediagoblin.user_pages.feature_promote',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}" media=media.slug_or_id) }}"
class="button_action" id="button_promotefeature" title="{% trans %} class="button_action" id="button_promotefeature" title="{% trans %}
Promote Feature {% endtrans %}"> Promote Feature {% endtrans %}">
@ -45,7 +45,7 @@ Promote Feature {% endtrans %}">
{% endif %}{% if not media_feature.display_type == 'tertiary' %} {% endif %}{% if not media_feature.display_type == 'tertiary' %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.feature_demote', 'mediagoblin.user_pages.feature_demote',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}" media=media.slug_or_id) }}"
class="button_action" id="button_demotefeature" title="{% trans %} class="button_action" id="button_demotefeature" title="{% trans %}
Demote Feature {% endtrans %}"> Demote Feature {% endtrans %}">

View File

@ -38,7 +38,7 @@ def get_media_entry_from_uploader_slug(uploader_username, slug):
LocalUser.username==uploader_username LocalUser.username==uploader_username
).first() ).first()
media = MediaEntry.query.filter( media = MediaEntry.query.filter(
MediaEntry.get_uploader == uploader ).filter( MediaEntry.get_actor == uploader ).filter(
MediaEntry.slug == slug).first() MediaEntry.slug == slug).first()
return media return media
@ -141,7 +141,7 @@ def create_featured_media_textbox():
for feature in feature_list: for feature in feature_list:
media_entry = feature.media_entry media_entry = feature.media_entry
output_text += u'/u/{uploader_username}/m/{media_slug}/\n'.format( 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) media_slug = media_entry.slug)

View File

@ -35,7 +35,7 @@
{% endif %} {% endif %}
{% if request.user and request.user.has_privilege('admin') %} {% if request.user and request.user.has_privilege('admin') %}
<a href="{{ request.urlgen('mediagoblin.edit.metadata', <a href="{{ request.urlgen('mediagoblin.edit.metadata',
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) }}"> media_id=media.id) }}">
{% trans %}Edit Metadata{% endtrans %}</a> {% trans %}Edit Metadata{% endtrans %}</a>
{% endif %} {% endif %}

View File

@ -82,7 +82,7 @@ def pwg_categories_getList(request):
if request.user: if request.user:
collections = Collection.query.filter_by( 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: for c in collections:
catlist.append({'id': c.id, catlist.append({'id': c.id,
@ -142,7 +142,7 @@ def pwg_images_addSimple(request):
collection_id = form.category.data collection_id = form.category.data
if collection_id > 0: if collection_id > 0:
collection = Collection.query.get(collection_id) 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, "") add_media_to_collection(collection, entry, "")
return { return {

View File

@ -52,7 +52,7 @@ def new_upload_entry(user):
Create a new MediaEntry for uploading Create a new MediaEntry for uploading
""" """
entry = MediaEntry() entry = MediaEntry()
entry.uploader = user.id entry.actor = user.id
entry.license = user.license_preference entry.license = user.license_preference
return entry return entry
@ -198,7 +198,7 @@ def submit_media(mg_app, user, submitted_file, filename,
add_comment_subscription(user, entry) add_comment_subscription(user, entry)
# Create activity # Create activity
create_activity("post", entry, entry.uploader) create_activity("post", entry, entry.actor)
entry.save() entry.save()
# Pass off to processing # Pass off to processing
@ -297,7 +297,7 @@ def api_add_to_feed(request, entry):
activity = create_activity( activity = create_activity(
verb="post", verb="post",
obj=entry, obj=entry,
actor=entry.uploader, actor=entry.actor,
generator=create_generator(request) generator=create_generator(request)
) )
entry.save() entry.save()

View File

@ -27,7 +27,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.edit.attachments', <form action="{{ request.urlgen('mediagoblin.edit.attachments',
user= media.get_uploader.username, user= media.get_actor.username,
media_id=media.id) }}" media_id=media.id) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box"> <div class="form_box">

View File

@ -28,7 +28,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.edit.edit_media', <form action="{{ request.urlgen('mediagoblin.edit.edit_media',
user= media.get_uploader.username, user= media.get_actor.username,
media_id=media.id) }}" media_id=media.id) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box_xl edit_box"> <div class="form_box_xl edit_box">

View File

@ -22,7 +22,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.edit.edit_collection', <form action="{{ request.urlgen('mediagoblin.edit.edit_collection',
user= collection.get_creator.username, user= collection.get_actor.username,
collection= collection.slug) }}" collection= collection.slug) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box_xl edit_box"> <div class="form_box_xl edit_box">
@ -36,4 +36,4 @@
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -5,7 +5,7 @@
<ul> <ul>
{% for notification in notifications %} {% for notification in notifications %}
{% set comment = notification.subject %} {% set comment = notification.subject %}
{% set comment_author = comment.get_author %} {% set comment_author = comment.get_actor %}
{% set media = comment.get_entry %} {% set media = comment.get_entry %}
<li class="comment_wrapper"> <li class="comment_wrapper">
<div class="comment_author"> <div class="comment_author">
@ -17,7 +17,7 @@
</a> </a>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, comment=comment.id,
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}#comment" media=media.slug_or_id) }}#comment"
class="comment_whenlink"> class="comment_whenlink">
<span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'> <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
@ -36,7 +36,7 @@
</li> </li>
{% endfor %} {% endfor %}
</ul> </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"> request.base_url|urlencode }}" id="mark_all_comments_seen">
{% trans %}Mark all read{% endtrans %} {% trans %}Mark all read{% endtrans %}
</a> </a>

View File

@ -44,7 +44,7 @@
{% for media_entry in processing_entries %} {% for media_entry in processing_entries %}
<tr> <tr>
<td>{{ media_entry.id }}</td> <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.title }}</td>
<td>{{ media_entry.created.strftime("%F %R") }}</td> <td>{{ media_entry.created.strftime("%F %R") }}</td>
{% if media_entry.transcoding_progress %} {% if media_entry.transcoding_progress %}
@ -74,7 +74,7 @@
{% for media_entry in failed_entries %} {% for media_entry in failed_entries %}
<tr> <tr>
<td>{{ media_entry.id }}</td> <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.title }}</td>
<td>{{ media_entry.created.strftime("%F %R") }}</td> <td>{{ media_entry.created.strftime("%F %R") }}</td>
{% if media_entry.get_fail_exception() %} {% if media_entry.get_fail_exception() %}
@ -103,7 +103,7 @@
{% for media_entry in processed_entries %} {% for media_entry in processed_entries %}
<tr> <tr>
<td>{{ media_entry.id }}</td> <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><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> <td><span title='{{ media_entry.created.strftime("%F %R") }}'>{{ timesince(media_entry.created) }}</span></td>
</tr> </tr>

View File

@ -37,20 +37,20 @@
{% trans %}Reported comment{% endtrans %}: {% trans %}Reported comment{% endtrans %}:
{% set comment = report.comment %} {% set comment = report.comment %}
{% set reported_user = comment.get_author %} {% set reported_user = comment.get_actor %}
<div id="comment-{{ comment.id }}" <div id="comment-{{ comment.id }}"
class="comment_wrapper"> class="comment_wrapper">
<div class="comment_author"> <div class="comment_author">
<img src="{{ request.staticdirect('/images/icon_comment.png') }}" /> <img src="{{ request.staticdirect('/images/icon_comment.png') }}" />
<a href="{{ request.urlgen('mediagoblin.moderation.users_detail', <a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
user=comment.get_author.username) }}" user=comment.get_actor.username) }}"
class="comment_authorlink"> class="comment_authorlink">
{{- reported_user.username -}} {{- reported_user.username -}}
</a> </a>
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.media_home.view_comment', 'mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, 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" media=comment.get_media_entry.slug_or_id) }}#comment"
class="comment_whenlink"> class="comment_whenlink">
<span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'> <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
@ -70,11 +70,11 @@
{% set media_entry = report.media_entry %} {% set media_entry = report.media_entry %}
<div class="three columns media_thumbnail"> <div class="three columns media_thumbnail">
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home', <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) }}"> media=media_entry.slug_or_id) }}">
<img src="{{ media_entry.thumb_url}}"/></a> <img src="{{ media_entry.thumb_url}}"/></a>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home', <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=media_entry.slug_or_id) }}" class=thumb_entry_title>
{{ media_entry.title }}</a> {{ media_entry.title }}</a>
</div> </div>
@ -127,8 +127,8 @@
{{ report.report_content }} {{ report.report_content }}
</div> </div>
</div> </div>
{% if not report.is_archived_report() and {% if not report.is_archived_report() and
not (report.reported_user.has_privilege('admin') and not (report.reported_user.has_privilege('admin') and
not request.user.has_privilege('admin')) %} not request.user.has_privilege('admin')) %}
<input type=button class="button_action" value="{% trans %}Resolve{% endtrans %}" id=open_resolution_form /> <input type=button class="button_action" value="{% trans %}Resolve{% endtrans %}" id=open_resolution_form />
<form action="" method="POST" id=resolution_form> <form action="" method="POST" id=resolution_form>

View File

@ -70,8 +70,8 @@
{% if request.user and {% if request.user and
(media.uploader == request.user.id or (media.uploader == request.user.id or
request.user.has_privilege('admin')) %} request.user.has_privilege('admin')) %}
{% set edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit', {% set edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit',
blog_slug=media.media_manager.get_blog_by_blogpost().slug, blog_slug=media.media_manager.get_blog_by_blogpost().slug,
user=request.user.username, blog_post_slug=media.slug) %} user=request.user.username, blog_post_slug=media.slug) %}
<a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a> <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', {% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
@ -107,7 +107,7 @@
{% endif %} {% endif %}
<ul style="list-style:none"> <ul style="list-style:none">
{% for comment in comments %} {% for comment in comments %}
{% set comment_author = comment.get_author %} {% set comment_author = comment.get_actor %}
<li id="comment-{{ comment.id }}" <li id="comment-{{ comment.id }}"
{%- if pagination.active_id == comment.id %} {%- if pagination.active_id == comment.id %}
class="comment_wrapper comment_active"> class="comment_wrapper comment_active">
@ -148,7 +148,7 @@
<div class="media_sidebar"> <div class="media_sidebar">
<h3>{% trans %}Added{% endtrans %}</h3> <h3>{% trans %}Added{% endtrans %}</h3>
<p><span title="{{ media.created.strftime("%I:%M%p %Y-%m-%d") }}"> <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 {{ formatted_time }} ago
{%- endtrans -%} {%- endtrans -%}
</span></p> </span></p>

View File

@ -44,14 +44,14 @@
{{ collection_title }} by <a href="{{ user_url }}">{{ username }}</a> {{ collection_title }} by <a href="{{ user_url }}">{{ username }}</a>
{%- endtrans %} {%- endtrans %}
</h1> </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')) %} request.user.has_privilege('admin')) %}
{% set edit_url = request.urlgen('mediagoblin.edit.edit_collection', {% set edit_url = request.urlgen('mediagoblin.edit.edit_collection',
user=collection.get_creator.username, user=collection.get_actor.username,
collection=collection.slug) %} collection=collection.slug) %}
<a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a> <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
{% set delete_url = request.urlgen('mediagoblin.user_pages.collection_confirm_delete', {% set delete_url = request.urlgen('mediagoblin.user_pages.collection_confirm_delete',
user=collection.get_creator.username, user=collection.get_actor.username,
collection=collection.slug) %} collection=collection.slug) %}
<a class="button_action" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a> <a class="button_action" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a>
{% endif %} {% endif %}

View File

@ -30,7 +30,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.user_pages.collection_confirm_delete', <form action="{{ request.urlgen('mediagoblin.user_pages.collection_confirm_delete',
user=collection.get_creator.username, user=collection.get_actor.username,
collection=collection.slug) }}" collection=collection.slug) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box"> <div class="form_box">
@ -39,9 +39,9 @@
Really delete collection: {{ title }}? Really delete collection: {{ title }}?
{%- endtrans %} {%- endtrans %}
</h1> </h1>
<br /> <br />
<p class="delete_checkbox_box"> <p class="delete_checkbox_box">
{{ form.confirm }} {{ form.confirm }}
{{ wtforms_util.render_label(form.confirm) }} {{ wtforms_util.render_label(form.confirm) }}
@ -58,4 +58,4 @@
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -20,7 +20,7 @@
{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} {% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
{% block title %} {% 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 -%} collection_title=collection_item.in_collection.title -%}
Remove {{ media_title }} from {{ collection_title }} Remove {{ media_title }} from {{ collection_title }}
{%- endtrans %} &mdash; {{ super() }} {%- endtrans %} &mdash; {{ super() }}
@ -30,20 +30,20 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.user_pages.collection_item_confirm_remove', <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=collection_item.in_collection.slug,
collection_item=collection_item.id) }}" collection_item=collection_item.id) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box"> <div class="form_box">
<h1> <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 -%} collection_title=collection_item.in_collection.title -%}
Really remove {{ media_title }} from {{ collection_title }}? Really remove {{ media_title }} from {{ collection_title }}?
{%- endtrans %} {%- endtrans %}
</h1> </h1>
<div style="text-align: center;" > <div style="text-align: center;" >
<img src="{{ collection_item.get_media_entry.thumb_url }}" /> <img src="{{ collection_item.get_object().thumb_url }}" />
</div> </div>
<br /> <br />
@ -64,4 +64,4 @@
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -38,8 +38,8 @@
<p class="eleven columns context"> <p class="eleven columns context">
{%- trans user_url=request.urlgen( {%- trans user_url=request.urlgen(
'mediagoblin.user_pages.user_home', 'mediagoblin.user_pages.user_home',
user=media.get_uploader.username), user=media.get_actor.username),
username=media.get_uploader.username -%} username=media.get_actor.username -%}
❖ Browsing media by <a href="{{user_url}}">{{username}}</a> ❖ Browsing media by <a href="{{user_url}}">{{username}}</a>
{%- endtrans -%} {%- endtrans -%}
</p> </p>
@ -76,15 +76,15 @@
{{ media.title }} {{ media.title }}
</h2> </h2>
{% if request.user and {% if request.user and
(media.uploader == request.user.id or (media.actor == request.user.id or
request.user.has_privilege('admin')) %} request.user.has_privilege('admin')) %}
<div class="pull-right" style="padding-top:20px;"> <div class="pull-right" style="padding-top:20px;">
{% set edit_url = request.urlgen('mediagoblin.edit.edit_media', {% set edit_url = request.urlgen('mediagoblin.edit.edit_media',
user= media.get_uploader.username, user= media.get_actor.username,
media_id=media.id) %} media_id=media.id) %}
<a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a> <a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete', {% 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) %} media_id=media.id) %}
<a class="button_action button_warning" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a> <a class="button_action button_warning" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a>
</div> </div>
@ -109,7 +109,7 @@
{% endif %} {% endif %}
{% if request.user %} {% if request.user %}
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment', <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"> media_id=media.id) }}" method="POST" id="form_comment">
{{ wtforms_util.render_divs(comment_form) }} {{ wtforms_util.render_divs(comment_form) }}
<div class="form_submit_buttons"> <div class="form_submit_buttons">
@ -123,7 +123,7 @@
{% endif %} {% endif %}
<ul style="list-style:none"> <ul style="list-style:none">
{% for comment in comments %} {% for comment in comments %}
{% set comment_author = comment.get_author %} {% set comment_author = comment.get_actor %}
<li id="comment-{{ comment.id }}" <li id="comment-{{ comment.id }}"
{%- if pagination.active_id == comment.id %} {%- if pagination.active_id == comment.id %}
class="comment_wrapper comment_active"> class="comment_wrapper comment_active">
@ -140,7 +140,7 @@
</a> </a>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment', <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, comment=comment.id,
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}#comment" media=media.slug_or_id) }}#comment"
class="comment_whenlink"> class="comment_whenlink">
<span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'> <span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
@ -157,7 +157,7 @@
<div> <div>
{% if app_config.allow_reporting %} {% if app_config.allow_reporting %}
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.report_comment', <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, media=media.slug_or_id,
comment=comment.id) }}"> comment=comment.id) }}">
{% trans %}Report{% endtrans %}</a> {% trans %}Report{% endtrans %}</a>
@ -215,14 +215,14 @@
{%- endif %} {%- endif %}
{%- if app_config['allow_attachments'] {%- if app_config['allow_attachments']
and request.user and request.user
and (media.uploader == request.user.id and (media.actor == request.user.id
or request.user.has_privilege('admin')) %} or request.user.has_privilege('admin')) %}
{%- if not media.attachment_files|count %} {%- if not media.attachment_files|count %}
<h3>{% trans %}Attachments{% endtrans %}</h3> <h3>{% trans %}Attachments{% endtrans %}</h3>
{%- endif %} {%- endif %}
<p> <p>
<a href="{{ request.urlgen('mediagoblin.edit.attachments', <a href="{{ request.urlgen('mediagoblin.edit.attachments',
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) }}"> media_id=media.id) }}">
{%- trans %}Add attachment{% endtrans -%} {%- trans %}Add attachment{% endtrans -%}
</a> </a>

View File

@ -32,7 +32,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.user_pages.media_collect', <form action="{{ request.urlgen('mediagoblin.user_pages.media_collect',
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) }}" media_id=media.id) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box"> <div class="form_box">
@ -70,4 +70,4 @@
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -22,7 +22,7 @@
{% block mediagoblin_content %} {% block mediagoblin_content %}
<form action="{{ request.urlgen('mediagoblin.user_pages.media_confirm_delete', <form action="{{ request.urlgen('mediagoblin.user_pages.media_confirm_delete',
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) }}" media_id=media.id) }}"
method="POST" enctype="multipart/form-data"> method="POST" enctype="multipart/form-data">
<div class="form_box"> <div class="form_box">
@ -51,4 +51,4 @@
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -22,14 +22,14 @@
<form action="" method=POST > <form action="" method=POST >
{% if comment is defined %} {% if comment is defined %}
<h3>{% trans %}Reporting this Comment{% endtrans %}</h3> <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( {%- set comment_author_url = request.urlgen(
'mediagoblin.user_pages.user_home', 'mediagoblin.user_pages.user_home',
user=comment_author.username) %} user=comment_author.username) %}
{%- set comment_url = request.urlgen( {%- set comment_url = request.urlgen(
'mediagoblin.user_pages.media_home.view_comment', 'mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, comment=comment.id,
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) %} media=media.slug_or_id) %}
<div id="comment-{{ comment.id }}" <div id="comment-{{ comment.id }}"
class="comment_wrapper"> class="comment_wrapper">
@ -60,17 +60,17 @@
<h3>{% trans %}Reporting this Media Entry{% endtrans %}</h3> <h3>{% trans %}Reporting this Media Entry{% endtrans %}</h3>
<div class="media_thumbnail"> <div class="media_thumbnail">
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home', <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}"> media=media.slug_or_id) }}">
<img src="{{ media.thumb_url }}"/></a> <img src="{{ media.thumb_url }}"/></a>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home', <a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) }}" media=media.slug_or_id) }}"
class=thumb_entry_title>{{ media.title }}</a> class=thumb_entry_title>{{ media.title }}</a>
</div> </div>
<div class=clear></div> <div class=clear></div>
{%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_uploader.username), {%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_actor.username),
username = media.get_uploader.username %} username = media.get_actor.username %}
❖ Published by <a href="{{ user_url }}" ❖ Published by <a href="{{ user_url }}"
class="comment_authorlink">{{ username }}</a> class="comment_authorlink">{{ username }}</a>
{% endtrans %} {% endtrans %}

View File

@ -25,24 +25,24 @@
{%- if loop.first %} thumb_row_first {%- if loop.first %} thumb_row_first
{%- elif loop.last %} thumb_row_last{% endif %}"> {%- elif loop.last %} thumb_row_last{% endif %}">
{% for item in row %} {% for item in row %}
{% set media_entry = item.get_media_entry %} {% set obj = item.get_object() %}
{% set entry_url = media_entry.url_for_self(request.urlgen) %} {% set obj_url = obj.url_for_self(request.urlgen) %}
<div class="three columns media_thumbnail thumb_entry <div class="three columns media_thumbnail thumb_entry
{%- if loop.first %} thumb_entry_first {%- if loop.first %} thumb_entry_first
{%- elif loop.last %} thumb_entry_last{% endif %}"> {%- elif loop.last %} thumb_entry_last{% endif %}">
<a href="{{ entry_url }}"> <a href="{{ obj_url }}">
<img src="{{ media_entry.thumb_url }}" /> <img src="{{ obj.thumb_url }}" />
</a> </a>
{% if item.note %} {% if item.note %}
<a href="{{ entry_url }}">{{ item.note }}</a> <a href="{{ obj_url }}">{{ item.note }}</a>
{% endif %} {% endif %}
{% if request.user and {% 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')) %} request.user.has_privilege('admin')) %}
{%- set remove_url=request.urlgen( {%- set remove_url=request.urlgen(
'mediagoblin.user_pages.collection_item_confirm_remove', '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.in_collection.slug,
collection_item=item.id) -%} collection_item=item.id) -%}
<a href="{{ remove_url }}" class="remove"> <a href="{{ remove_url }}" class="remove">

View File

@ -26,15 +26,15 @@
{%- endif %} {%- endif %}
<a href="{{ collection.url_for_self(request.urlgen) }}"> <a href="{{ collection.url_for_self(request.urlgen) }}">
{{- collection.title }} ( {{- collection.title }} (
{{- collection.get_creator.username -}} {{- collection.get_actor.username -}}
)</a> )</a>
{%- endfor %} {%- endfor %}
</p> </p>
{%- endif %} {%- endif %}
{%- if request.user %} {%- if request.user %}
<p> <p>
<a type="submit" href="{{ request.urlgen('mediagoblin.user_pages.media_collect', <a type="submit" href="{{ request.urlgen('mediagoblin.user_pages.media_collect',
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) }}" media_id=media.id) }}"
class="button_action"> class="button_action">
{% trans %}Add to a collection{% endtrans %} {% trans %}Add to a collection{% endtrans %}

View File

@ -19,13 +19,13 @@
{% set subscription = get_comment_subscription(request.user.id, media.id) %} {% set subscription = get_comment_subscription(request.user.id, media.id) %}
{% if not subscription or not subscription.notify %} {% if not subscription or not subscription.notify %}
<a type="submit" href="{{ request.urlgen('mediagoblin.notifications.subscribe_comments', <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)}}" media=media.slug_or_id)}}"
class="button_action">{% trans %}Subscribe to comments{% endtrans %} class="button_action">{% trans %}Subscribe to comments{% endtrans %}
</a> </a>
{% else %} {% else %}
<a type="submit" href="{{ request.urlgen('mediagoblin.notifications.silence_comments', <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)}}" media=media.slug_or_id)}}"
class="button_action">{% trans %}Silence comments{% endtrans %} class="button_action">{% trans %}Silence comments{% endtrans %}
</a> </a>

View File

@ -19,7 +19,7 @@
{% block report_content -%} {% block report_content -%}
<p> <p>
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.report_media', <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) }}" media=media.slug_or_id) }}"
class="button_action" id="button_reportmedia" title="Report media"> class="button_action" id="button_reportmedia" title="Report media">
{% trans %}Report media{% endtrans %} {% trans %}Report media{% endtrans %}

View File

@ -28,17 +28,17 @@
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.user_tag_gallery', 'mediagoblin.user_pages.user_tag_gallery',
tag=tag['slug'], tag=tag['slug'],
user=media.get_uploader.username) }}">{{ tag['name'] }}</a> user=media.get_actor.username) }}">{{ tag['name'] }}</a>
{% elif loop.revindex == 2 %} {% elif loop.revindex == 2 %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.user_tag_gallery', 'mediagoblin.user_pages.user_tag_gallery',
tag=tag['slug'], tag=tag['slug'],
user=media.get_uploader.username) }}">{{ tag['name'] }}</a> user=media.get_actor.username) }}">{{ tag['name'] }}</a>
{% else %} {% else %}
<a href="{{ request.urlgen( <a href="{{ request.urlgen(
'mediagoblin.user_pages.user_tag_gallery', 'mediagoblin.user_pages.user_tag_gallery',
tag=tag['slug'], tag=tag['slug'],
user=media.get_uploader.username) }}">{{ tag['name'] }}</a> user=media.get_actor.username) }}">{{ tag['name'] }}</a>
&middot; &middot;
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View File

@ -190,7 +190,7 @@ class TestAPI(object):
# and self._upload_image. # and self._upload_image.
id = int(data["object"]["id"].split("/")[-2]) id = int(data["object"]["id"].split("/")[-2])
media = MediaEntry.query.filter_by(id=id).first() media = MediaEntry.query.filter_by(id=id).first()
media.uploader = self.other_user.id media.actor = self.other_user.id
media.save() media.save()
# Now lets try and edit the image as self.user, this should produce a 403 error. # 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] comment = media.get_comments()[0]
# Tests that it matches in the database # Tests that it matches in the database
assert comment.author == self.user.id assert comment.actor == self.user.id
assert comment.content == content assert comment.content == content
# Test that the response is what we should be given # 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 # change who uploaded the comment as it's easier than changing
comment_id = int(comment_data["object"]["id"].split("/")[-2]) comment_id = int(comment_data["object"]["id"].split("/")[-2])
comment = MediaComment.query.filter_by(id=comment_id).first() comment = MediaComment.query.filter_by(id=comment_id).first()
comment.author = self.other_user.id comment.actor = self.other_user.id
comment.save() comment.save()
# Update the comment as someone else. # Update the comment as someone else.
@ -597,4 +597,3 @@ class TestAPI(object):
model = MediaComment.query.filter_by(id=comment_id).first() model = MediaComment.query.filter_by(id=comment_id).first()
assert model.content == activity["object"]["content"] assert model.content == activity["object"]["content"]

View File

@ -50,7 +50,7 @@ def test_user_deletes_other_comments(test_app):
for m_id in (media_a.id, media_b.id): for m_id in (media_a.id, media_b.id):
cmt = MediaComment() cmt = MediaComment()
cmt.media_entry = m_id cmt.media_entry = m_id
cmt.author = u_id cmt.actor = u_id
cmt.content = u"Some Comment" cmt.content = u"Some Comment"
Session.add(cmt) Session.add(cmt)

View File

@ -56,7 +56,7 @@ class TestMediaEntrySlugs(object):
entry.title = title or u"Some title" entry.title = title or u"Some title"
entry.slug = slug entry.slug = slug
entry.id = this_id 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' entry.media_type = u'image'
if save: if save:

View File

@ -158,7 +158,7 @@ VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
fixture_add_comment(author=self.user.id, fixture_add_comment(author=self.user.id,
comment=u'Comment will be removed') comment=u'Comment will be removed')
test_comment = MediaComment.query.filter( test_comment = MediaComment.query.filter(
MediaComment.author==self.user.id).first() MediaComment.actor==self.user.id).first()
fixture_add_comment_report(comment=test_comment, fixture_add_comment_report(comment=test_comment,
reported_user=self.user) reported_user=self.user)
comment_report = CommentReport.query.filter( comment_report = CommentReport.query.filter(
@ -177,7 +177,7 @@ VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
UserBan.user_id == self.user.id).first() UserBan.user_id == self.user.id).first()
assert test_user_ban is not None assert test_user_ban is not None
test_comment = MediaComment.query.filter( test_comment = MediaComment.query.filter(
MediaComment.author==self.user.id).first() MediaComment.actor==self.user.id).first()
assert test_comment is None assert test_comment is None
# Then, test what happens when a moderator attempts to punish an admin # Then, test what happens when a moderator attempts to punish an admin

View File

@ -112,7 +112,7 @@ class TestNotifications:
assert type(notification) == CommentNotification assert type(notification) == CommentNotification
assert notification.seen == False assert notification.seen == False
assert notification.user_id == user.id 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' assert notification.subject.content == u'Test comment #42'
if wants_email == True: if wants_email == True:

View File

@ -133,7 +133,7 @@ class TestReportFiling:
fixture_add_comment(author=allie_user.id, fixture_add_comment(author=allie_user.id,
comment=u'Comment will be removed') comment=u'Comment will be removed')
test_comment = MediaComment.query.filter( test_comment = MediaComment.query.filter(
MediaComment.author==allie_user.id).first() MediaComment.actor==allie_user.id).first()
fixture_add_comment_report(comment=test_comment, fixture_add_comment_report(comment=test_comment,
reported_user=allie_user, reported_user=allie_user,
report_content=u'Testing Archived Reports #1', report_content=u'Testing Archived Reports #1',
@ -165,4 +165,3 @@ class TestReportFiling:
natalie banned user allie indefinitely. natalie banned user allie indefinitely.
natalie deleted the comment.''' natalie deleted the comment.'''
assert archived_report.discriminator == 'comment_report' assert archived_report.discriminator == 'comment_report'

View 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): def fixture_comment_subscription(entry, notify=True, send_email=None):
if send_email is None: if send_email is None:
uploader = LocalUser.query.filter_by(id=entry.uploader).first() actor = LocalUser.query.filter_by(id=entry.actor).first()
send_email = uploader.wants_comment_notification send_email = actor.wants_comment_notification
cs = CommentSubscription( cs = CommentSubscription(
media_entry_id=entry.id, media_entry_id=entry.id,
user_id=entry.uploader, user_id=entry.actor,
notify=notify, notify=notify,
send_email=send_email) send_email=send_email)
@ -254,7 +254,7 @@ def fixture_media_entry(title=u"Some title", slug=None,
entry = MediaEntry() entry = MediaEntry()
entry.title = title entry.title = title
entry.slug = slug entry.slug = slug
entry.uploader = uploader entry.actor = uploader
entry.media_type = u'image' entry.media_type = u'image'
entry.state = state entry.state = state
@ -278,15 +278,21 @@ def fixture_media_entry(title=u"Some title", slug=None,
return entry 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: if user is None:
user = fixture_add_user() 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: if coll is not None:
return coll return coll
coll = Collection() coll = Collection()
coll.creator = user.id coll.actor = user.id
coll.title = name coll.title = name
coll.type = collection_type
coll.generate_slug() coll.generate_slug()
coll.save() 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( 'Auto-generated test comment by user #{0} on media #{0}'.format(
author, media_entry) author, media_entry)
comment = MediaComment(author=author, comment = MediaComment(actor=author,
media_entry=media_entry, media_entry=media_entry,
content=comment) content=comment)
@ -373,4 +379,4 @@ def fixture_add_activity(obj, verb="post", target=None, generator=None, actor=No
activity.set_target(target) activity.set_target(target)
activity.save() activity.save()
return activity return activity

View File

@ -38,11 +38,11 @@ def send_comment_email(user, comment, media, request):
comment_url = request.urlgen( comment_url = request.urlgen(
'mediagoblin.user_pages.media_home.view_comment', 'mediagoblin.user_pages.media_home.view_comment',
comment=comment.id, comment=comment.id,
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id, media=media.slug_or_id,
qualified=True) + '#comment' qualified=True) + '#comment'
comment_author = comment.get_author.username comment_author = comment.get_actor.username
rendered_email = render_template( rendered_email = render_template(
request, 'mediagoblin/user_pages/comment_email.txt', 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): def add_media_to_collection(collection, media, note=None, commit=True):
collection_item = CollectionItem() collection_item = CollectionItem()
collection_item.collection = collection.id collection_item.collection = collection.id
collection_item.media_entry = media.id collection_item.get_object = media
if note: if note:
collection_item.note = note collection_item.note = note
Session.add(collection_item) Session.add(collection_item)
collection.items = collection.items + 1 collection.num_items = collection.num_items + 1
Session.add(collection) Session.add(collection)
Session.add(media) Session.add(media)
@ -106,12 +106,12 @@ def build_report_object(report_form, media_entry=None, comment=None):
report_object = CommentReport() report_object = CommentReport()
report_object.comment_id = comment.id report_object.comment_id = comment.id
report_object.reported_user_id = MediaComment.query.get( 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: elif report_form.validate() and media_entry is not None:
report_object = MediaReport() report_object = MediaReport()
report_object.media_entry_id = media_entry.id report_object.media_entry_id = media_entry.id
report_object.reported_user_id = MediaEntry.query.get( report_object.reported_user_id = MediaEntry.query.get(
media_entry.id).get_uploader.id media_entry.id).get_actor.id
else: else:
return None return None

View File

@ -64,7 +64,7 @@ def user_home(request, page):
{'user': user}) {'user': user})
cursor = MediaEntry.query.\ cursor = MediaEntry.query.\
filter_by(uploader = user.id, filter_by(actor = user.id,
state = u'processed').order_by(MediaEntry.created.desc()) state = u'processed').order_by(MediaEntry.created.desc())
pagination = Pagination(page, cursor) pagination = Pagination(page, cursor)
@ -93,7 +93,7 @@ def user_gallery(request, page, url_user=None):
"""'Gallery' of a LocalUser()""" """'Gallery' of a LocalUser()"""
tag = request.matchdict.get('tag', None) tag = request.matchdict.get('tag', None)
cursor = MediaEntry.query.filter_by( cursor = MediaEntry.query.filter_by(
uploader=url_user.id, actor=url_user.id,
state=u'processed').order_by(MediaEntry.created.desc()) state=u'processed').order_by(MediaEntry.created.desc())
# Filter potentially by tag too: # Filter potentially by tag too:
@ -180,7 +180,7 @@ def media_post_comment(request, media):
comment = request.db.MediaComment() comment = request.db.MediaComment()
comment.media_entry = media.id comment.media_entry = media.id
comment.author = request.user.id comment.actor = request.user.id
comment.content = six.text_type(request.form['comment_content']) comment.content = six.text_type(request.form['comment_content'])
# Show error message if commenting is disabled. # Show error message if commenting is disabled.
@ -195,7 +195,7 @@ def media_post_comment(request, media):
messages.ERROR, messages.ERROR,
_("Oops, your comment was empty.")) _("Oops, your comment was empty."))
else: else:
create_activity("post", comment, comment.author, target=media) create_activity("post", comment, comment.actor, target=media)
add_comment_subscription(request.user, media) add_comment_subscription(request.user, media)
comment.save() comment.save()
@ -228,7 +228,9 @@ def media_collect(request, media):
form = user_forms.MediaCollectForm(request.form) form = user_forms.MediaCollectForm(request.form)
# A user's own collections: # A user's own collections:
form.collection.query = Collection.query.filter_by( 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(): if request.method != 'POST' or not form.validate():
# No POST submission, or invalid form # No POST submission, or invalid form
@ -247,44 +249,50 @@ def media_collect(request, media):
if form.collection_title.data: if form.collection_title.data:
# Make sure this user isn't duplicating an existing collection # Make sure this user isn't duplicating an existing collection
existing_collection = Collection.query.filter_by( existing_collection = Collection.query.filter_by(
creator=request.user.id, actor=request.user.id,
title=form.collection_title.data).first() title=form.collection_title.data,
type=Collection.USER_DEFINED_TYPE
).first()
if existing_collection: if existing_collection:
messages.add_message(request, messages.ERROR, messages.add_message(request, messages.ERROR,
_('You already have a collection called "%s"!') _('You already have a collection called "%s"!')
% existing_collection.title) % existing_collection.title)
return redirect(request, "mediagoblin.user_pages.media_home", return redirect(request, "mediagoblin.user_pages.media_home",
user=media.get_uploader.username, user=media.get_actor.username,
media=media.slug_or_id) media=media.slug_or_id)
collection = Collection() collection = Collection()
collection.title = form.collection_title.data collection.title = form.collection_title.data
collection.description = form.collection_description.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() collection.generate_slug()
create_activity("create", collection, collection.creator) create_activity("create", collection, collection.actor)
collection.save() collection.save()
# Otherwise, use the collection selected from the drop-down # Otherwise, use the collection selected from the drop-down
else: else:
collection = form.collection.data collection = form.collection.data
if collection and collection.creator != request.user.id: if collection and collection.actor != request.user.id:
collection = None collection = None
# Make sure the user actually selected a collection # 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: if not collection:
messages.add_message( messages.add_message(
request, messages.ERROR, request, messages.ERROR,
_('You have to select or add a collection')) _('You have to select or add a collection'))
return redirect(request, "mediagoblin.user_pages.media_collect", return redirect(request, "mediagoblin.user_pages.media_collect",
user=media.get_uploader.username, user=media.get_actor.username,
media_id=media.id) media_id=media.id)
# Check whether media already exists in collection # Check whether media already exists in collection
elif CollectionItem.query.filter_by( elif item is not None:
media_entry=media.id,
collection=collection.id).first():
messages.add_message(request, messages.ERROR, messages.add_message(request, messages.ERROR,
_('"%s" already in collection "%s"') _('"%s" already in collection "%s"')
% (media.title, collection.title)) % (media.title, collection.title))
@ -308,11 +316,11 @@ def media_confirm_delete(request, media):
if request.method == 'POST' and form.validate(): if request.method == 'POST' and form.validate():
if form.confirm.data is True: 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.file_size
media.get_uploader.save() media.get_actor.save()
# Delete MediaEntry and all related files, comments etc. # Delete MediaEntry and all related files, comments etc.
media.delete() media.delete()
@ -333,7 +341,7 @@ def media_confirm_delete(request, media):
return redirect_obj(request, media) return redirect_obj(request, media)
if ((request.user.has_privilege(u'admin') and if ((request.user.has_privilege(u'admin') and
request.user.id != media.uploader)): request.user.id != media.actor)):
messages.add_message( messages.add_message(
request, messages.WARNING, request, messages.WARNING,
_("You are about to delete another user's media. " _("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): def user_collection(request, page, url_user=None):
"""A User-defined Collection""" """A User-defined Collection"""
collection = Collection.query.filter_by( collection = Collection.query.filter_by(
get_creator=url_user, get_actor=url_user,
slug=request.matchdict['collection']).first() slug=request.matchdict['collection']).first()
if not collection: if not collection:
@ -380,7 +388,7 @@ def user_collection(request, page, url_user=None):
def collection_list(request, url_user=None): def collection_list(request, url_user=None):
"""A User-defined Collection""" """A User-defined Collection"""
collections = Collection.query.filter_by( collections = Collection.query.filter_by(
get_creator=url_user) get_actor=url_user)
return render_to_response( return render_to_response(
request, request,
@ -397,15 +405,15 @@ def collection_item_confirm_remove(request, collection_item):
form = user_forms.ConfirmCollectionItemRemoveForm(request.form) form = user_forms.ConfirmCollectionItemRemoveForm(request.form)
if request.method == 'POST' and form.validate(): 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 collection = collection_item.in_collection
if form.confirm.data is True: if form.confirm.data is True:
entry = collection_item.get_media_entry obj = collection_item.get_object()
entry.save() obj.save()
collection_item.delete() collection_item.delete()
collection.items = collection.items - 1 collection.num_items = collection.num_items - 1
collection.save() collection.save()
messages.add_message( messages.add_message(
@ -418,7 +426,7 @@ def collection_item_confirm_remove(request, collection_item):
return redirect_obj(request, collection) return redirect_obj(request, collection)
if ((request.user.has_privilege(u'admin') and 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( messages.add_message(
request, messages.WARNING, request, messages.WARNING,
_("You are about to delete an item from another user's collection. " _("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(): if request.method == 'POST' and form.validate():
username = collection.get_creator.username username = collection.get_actor.username
if form.confirm.data is True: if form.confirm.data is True:
collection_title = collection.title collection_title = collection.title
# Delete all the associated collection items # Delete all the associated collection items
for item in collection.get_collection_items(): for item in collection.get_collection_items():
entry = item.get_media_entry obj = item.get_object()
entry.save() obj.save()
item.delete() item.delete()
collection.delete() collection.delete()
@ -465,7 +473,7 @@ def collection_confirm_delete(request, collection):
return redirect_obj(request, collection) return redirect_obj(request, collection)
if ((request.user.has_privilege(u'admin') and if ((request.user.has_privilege(u'admin') and
request.user.id != collection.creator)): request.user.id != collection.actor)):
messages.add_message( messages.add_message(
request, messages.WARNING, request, messages.WARNING,
_("You are about to delete another user's collection. " _("You are about to delete another user's collection. "
@ -491,7 +499,7 @@ def atom_feed(request):
return render_404(request) return render_404(request)
cursor = MediaEntry.query.filter_by( cursor = MediaEntry.query.filter_by(
uploader = user.id, actor = user.id,
state = u'processed').\ state = u'processed').\
order_by(MediaEntry.created.desc()).\ order_by(MediaEntry.created.desc()).\
limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS) limit(ATOM_DEFAULT_NR_OF_UPDATED_ITEMS)
@ -523,15 +531,16 @@ def atom_feed(request):
links=atomlinks) links=atomlinks)
for entry in cursor: for entry in cursor:
feed.add(entry.get('title'), feed.add(
entry.get('title'),
entry.description_html, entry.description_html,
id=entry.url_for_self(request.urlgen, qualified=True), id=entry.url_for_self(request.urlgen, qualified=True),
content_type='html', content_type='html',
author={ author={
'name': entry.get_uploader.username, 'name': entry.get_actor.username,
'uri': request.urlgen( 'uri': request.urlgen(
'mediagoblin.user_pages.user_home', 'mediagoblin.user_pages.user_home',
qualified=True, user=entry.get_uploader.username)}, qualified=True, user=entry.get_actor.username)},
updated=entry.get('created'), updated=entry.get('created'),
links=[{ links=[{
'href': entry.url_for_self( 'href': entry.url_for_self(
@ -553,7 +562,7 @@ def collection_atom_feed(request):
return render_404(request) return render_404(request)
collection = Collection.query.filter_by( collection = Collection.query.filter_by(
creator=user.id, actor=user.id,
slug=request.matchdict['collection']).first() slug=request.matchdict['collection']).first()
if not collection: if not collection:
return render_404(request) return render_404(request)
@ -591,19 +600,20 @@ def collection_atom_feed(request):
links=atomlinks) links=atomlinks)
for item in cursor: for item in cursor:
entry = item.get_media_entry obj = item.get_object()
feed.add(entry.get('title'), feed.add(
obj.get('title'),
item.note_html, item.note_html,
id=entry.url_for_self(request.urlgen, qualified=True), id=obj.url_for_self(request.urlgen, qualified=True),
content_type='html', content_type='html',
author={ author={
'name': entry.get_uploader.username, 'name': obj.get_actor().username,
'uri': request.urlgen( 'uri': request.urlgen(
'mediagoblin.user_pages.user_home', 'mediagoblin.user_pages.user_home',
qualified=True, user=entry.get_uploader.username)}, qualified=True, user=obj.get_actor().username)},
updated=item.get('added'), updated=item.get('added'),
links=[{ links=[{
'href': entry.url_for_self( 'href': obj.url_for_self(
request.urlgen, request.urlgen,
qualified=True), qualified=True),
'rel': 'alternate', 'rel': 'alternate',
@ -630,18 +640,18 @@ def processing_panel(request):
# Get media entries which are in-processing # Get media entries which are in-processing
processing_entries = MediaEntry.query.\ processing_entries = MediaEntry.query.\
filter_by(uploader = user.id, filter_by(actor = user.id,
state = u'processing').\ state = u'processing').\
order_by(MediaEntry.created.desc()) order_by(MediaEntry.created.desc())
# Get media entries which have failed to process # Get media entries which have failed to process
failed_entries = MediaEntry.query.\ failed_entries = MediaEntry.query.\
filter_by(uploader = user.id, filter_by(actor = user.id,
state = u'failed').\ state = u'failed').\
order_by(MediaEntry.created.desc()) order_by(MediaEntry.created.desc())
processed_entries = MediaEntry.query.\ processed_entries = MediaEntry.query.\
filter_by(uploader = user.id, filter_by(actor = user.id,
state = u'processed').\ state = u'processed').\
order_by(MediaEntry.created.desc()).\ order_by(MediaEntry.created.desc()).\
limit(10) limit(10)
@ -725,4 +735,3 @@ def activity_view(request):
"mediagoblin/api/activity.html", "mediagoblin/api/activity.html",
{"activity": activity} {"activity": activity}
) )