From 1aff1b3694ca46bb0eb80192cc0815223b812240 Mon Sep 17 00:00:00 2001
From: srudolph <Stephen.Rudolph@gmail.com>
Date: Sat, 21 Feb 2015 17:57:41 -0600
Subject: [PATCH] This feature would add a mediagoblin.ini configuration
variable named 'most_recent_media_view' that, by default, shows the main
landing page the way it is always shown now: with a paginated and reverse
chronological list of media entries. It could be changed to 'Collection' to
instead show a reverse chronological list of non-empty collections.
For now, a random media entry from the collection will be shown to represent the collection. In the future, this could be improved to allow the collection's creator to select a key entry to always show.
Some benefits of this change:
-Default behavior remains as-is
-Discoverability of collections is enhanced
-Allows increased customizability
---
mediagoblin.example.ini | 4 ++++
mediagoblin/config_spec.ini | 3 +++
mediagoblin/db/mixin.py | 18 ++++++++++++++++++
mediagoblin/db/models.py | 6 +++++-
mediagoblin/views.py | 10 +++++++---
5 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/mediagoblin.example.ini b/mediagoblin.example.ini
index 17b123f..06b788a 100644
a
|
b
|
allow_registration = true
|
29 | 29 | # Set to false to disable the ability for users to report offensive content |
30 | 30 | allow_reporting = true |
31 | 31 | |
| 32 | ## Uncomment this to change the main page's most recent media display from |
| 33 | ## MediaEntry to Collection |
| 34 | # most_recent_media_view = "Collection" |
| 35 | |
32 | 36 | ## Uncomment this to put some user-overriding templates here |
33 | 37 | # local_templates = %(data_basedir)s/templates/ |
34 | 38 | |
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index f769e4e..0db803d 100644
a
|
b
|
theme_web_path = string(default="/theme_static/")
|
98 | 98 | theme_linked_assets_dir = string(default="%(data_basedir)s/theme_static/") |
99 | 99 | theme = string() |
100 | 100 | |
| 101 | # Main page, most recent media display |
| 102 | most_recent_media_view = string(default="MediaEntry") |
| 103 | |
101 | 104 | # plugin default assets directory |
102 | 105 | plugin_web_path = string(default="/plugin_static/") |
103 | 106 | plugin_linked_assets_dir = string(default="%(data_basedir)s/plugin_static/") |
diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py
index 4602c70..a753915 100644
a
|
b
|
real objects.
|
29 | 29 | |
30 | 30 | import uuid |
31 | 31 | import re |
| 32 | import random |
32 | 33 | from datetime import datetime |
33 | 34 | |
34 | 35 | from pytz import UTC |
… |
… |
class CollectionMixin(GenerateSlugMixin):
|
369 | 370 | collection=self.slug_or_id, |
370 | 371 | **extra_args) |
371 | 372 | |
| 373 | @property |
| 374 | def thumb_url(self): |
| 375 | """Return the thumbnail URL (for usage in templates) |
| 376 | Will return either the real thumbnail or a default fallback icon.""" |
| 377 | # TODO: implement generic fallback in case MEDIA_MANAGER does |
| 378 | # not specify one? |
| 379 | item = random.choice(self.collection_items).get_media_entry |
| 380 | if u'thumb' in item.media_files: |
| 381 | thumb_url = item._app.public_store.file_url( |
| 382 | item.media_files[u'thumb']) |
| 383 | else: |
| 384 | # No thumbnail in media available. Get the media's |
| 385 | # MEDIA_MANAGER for the fallback icon and return static URL |
| 386 | # Raises FileTypeNotSupported in case no such manager is enabled |
| 387 | manager = item.media_manager |
| 388 | thumb_url = item._app.staticdirector(manager[u'default_thumb']) |
| 389 | return thumb_url |
372 | 390 | |
373 | 391 | class CollectionItemMixin(object): |
374 | 392 | @property |
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index e8fb17a..bff1415 100644
a
|
b
|
class CollectionItem(Base, CollectionItemMixin):
|
907 | 907 | "collection_items", |
908 | 908 | cascade="all, delete-orphan")) |
909 | 909 | |
910 | | get_media_entry = relationship(MediaEntry) |
| 910 | get_media_entry = relationship(MediaEntry, |
| 911 | backref=backref( |
| 912 | "collection_items", |
| 913 | lazy="dynamic", |
| 914 | cascade="all, delete-orphan")) |
911 | 915 | |
912 | 916 | __table_args__ = ( |
913 | 917 | UniqueConstraint('collection', 'media_entry'), |
diff --git a/mediagoblin/views.py b/mediagoblin/views.py
index 9e893d5..d849fb3 100644
a
|
b
|
|
15 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 | from mediagoblin import mg_globals |
18 | | from mediagoblin.db.models import MediaEntry |
| 18 | from mediagoblin.db.models import (MediaEntry, Collection) |
19 | 19 | from mediagoblin.tools.pagination import Pagination |
20 | 20 | from mediagoblin.tools.pluginapi import hook_handle |
21 | 21 | from mediagoblin.tools.response import render_to_response, render_404 |
… |
… |
from mediagoblin.decorators import uses_pagination, user_not_banned
|
25 | 25 | @user_not_banned |
26 | 26 | @uses_pagination |
27 | 27 | def default_root_view(request, page): |
28 | | cursor = request.db.query(MediaEntry).filter_by(state=u'processed').\ |
29 | | order_by(MediaEntry.created.desc()) |
| 28 | if mg_globals.app_config['most_recent_media_view'] == 'Collection': |
| 29 | cursor = Collection.query.filter(Collection.items > 0).\ |
| 30 | order_by(Collection.created.desc()) |
| 31 | else: |
| 32 | cursor = request.db.query(MediaEntry).filter_by(state=u'processed').\ |
| 33 | order_by(MediaEntry.created.desc()) |
30 | 34 | |
31 | 35 | pagination = Pagination(page, cursor) |
32 | 36 | media_entries = pagination() |