aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Allan Webber <cwebber@dustycloud.org>2012-01-10 08:12:30 -0600
committerChristopher Allan Webber <cwebber@dustycloud.org>2012-01-10 08:12:30 -0600
commit73079ac4b8a8b3b355867a1e98aca63313597ad0 (patch)
tree614424e7222f81a29f82e580f5dc97baebffb1f6
parent1df68a3524d92caee5601a8acc011ac8e1fe16d4 (diff)
parent914b8bcde3e01c2dd3e5679fb7733fc194b34d68 (diff)
downloadmediagoblin-73079ac4b8a8b3b355867a1e98aca63313597ad0.tar.lz
mediagoblin-73079ac4b8a8b3b355867a1e98aca63313597ad0.tar.xz
mediagoblin-73079ac4b8a8b3b355867a1e98aca63313597ad0.zip
Merge branch 'master' of gitorious.org:mediagoblin/mediagoblin
Conflicts: mediagoblin/db/mongo/models.py
-rw-r--r--mediagoblin/db/mixin.py90
-rw-r--r--mediagoblin/db/mongo/models.py44
-rw-r--r--mediagoblin/db/sql/models.py5
-rw-r--r--mediagoblin/staticdirect.py11
-rw-r--r--mediagoblin/templates/mediagoblin/base.html4
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/media.html1
-rw-r--r--mediagoblin/tests/test_mgoblin_app.ini3
-rw-r--r--mediagoblin/tests/test_submission.py14
-rw-r--r--paste.ini22
9 files changed, 145 insertions, 49 deletions
diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py
new file mode 100644
index 00000000..4fb325d2
--- /dev/null
+++ b/mediagoblin/db/mixin.py
@@ -0,0 +1,90 @@
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011,2012 MediaGoblin contributors. See AUTHORS.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# 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/>.
+
+"""
+This module contains some Mixin classes for the db objects.
+
+A bunch of functions on the db objects are really more like
+"utility functions": They could live outside the classes
+and be called "by hand" passing the appropiate reference.
+They usually only use the public API of the object and
+rarely use database related stuff.
+
+These functions now live here and get "mixed in" into the
+real objects.
+"""
+
+from mediagoblin.auth import lib as auth_lib
+from mediagoblin.tools import common
+
+
+class UserMixin(object):
+ def check_login(self, password):
+ """
+ See if a user can login with this password
+ """
+ return auth_lib.bcrypt_check_password(
+ password, self.pw_hash)
+
+
+class MediaEntryMixin(object):
+ def get_display_media(self, media_map,
+ fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER):
+ """
+ Find the best media for display.
+
+ Args:
+ - media_map: a dict like
+ {u'image_size': [u'dir1', u'dir2', u'image.jpg']}
+ - fetch_order: the order we should try fetching images in
+
+ Returns:
+ (media_size, media_path)
+ """
+ media_sizes = media_map.keys()
+
+ for media_size in common.DISPLAY_IMAGE_FETCHING_ORDER:
+ if media_size in media_sizes:
+ return media_map[media_size]
+
+ def main_mediafile(self):
+ pass
+
+ def url_for_self(self, urlgen):
+ """
+ Generate an appropriate url for ourselves
+
+ Use a slug if we have one, else use our '_id'.
+ """
+ uploader = self.get_uploader
+
+ if self.get('slug'):
+ return urlgen(
+ 'mediagoblin.user_pages.media_home',
+ user=uploader.username,
+ media=self.slug)
+ else:
+ return urlgen(
+ 'mediagoblin.user_pages.media_home',
+ user=uploader.username,
+ media=unicode(self._id))
+
+ def get_fail_exception(self):
+ """
+ Get the exception that's appropriate for this error
+ """
+ if self['fail_error']:
+ return common.import_component(self['fail_error'])
diff --git a/mediagoblin/db/mongo/models.py b/mediagoblin/db/mongo/models.py
index f1e8eae6..d9b5a570 100644
--- a/mediagoblin/db/mongo/models.py
+++ b/mediagoblin/db/mongo/models.py
@@ -18,12 +18,12 @@ import datetime
from mongokit import Document
-from mediagoblin.auth import lib as auth_lib
from mediagoblin import mg_globals
from mediagoblin.db.mongo import migrations
from mediagoblin.db.mongo.util import ASCENDING, DESCENDING, ObjectId
from mediagoblin.tools.pagination import Pagination
-from mediagoblin.tools import url, common
+from mediagoblin.tools import url
+from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
###################
# Custom validators
@@ -34,7 +34,7 @@ from mediagoblin.tools import url, common
########
-class User(Document):
+class User(Document, UserMixin):
"""
A user of MediaGoblin.
@@ -89,15 +89,8 @@ class User(Document):
'status': u'needs_email_verification',
'is_admin': False}
- def check_login(self, password):
- """
- See if a user can login with this password
- """
- return auth_lib.bcrypt_check_password(
- password, self.pw_hash)
-
-class MediaEntry(Document):
+class MediaEntry(Document, MediaEntryMixin):
"""
Record of a piece of media.
@@ -224,28 +217,6 @@ class MediaEntry(Document):
return self.db.MediaComment.find({
'media_entry': self._id}).sort('created', order)
- def get_display_media(self, media_map,
- fetch_order=common.DISPLAY_IMAGE_FETCHING_ORDER):
- """
- Find the best media for display.
-
- Args:
- - media_map: a dict like
- {u'image_size': [u'dir1', u'dir2', u'image.jpg']}
- - fetch_order: the order we should try fetching images in
-
- Returns:
- (media_size, media_path)
- """
- media_sizes = media_map.keys()
-
- for media_size in common.DISPLAY_IMAGE_FETCHING_ORDER:
- if media_size in media_sizes:
- return media_map[media_size]
-
- def main_mediafile(self):
- pass
-
def generate_slug(self):
self.slug = url.slugify(self.title)
@@ -303,13 +274,6 @@ class MediaEntry(Document):
def get_uploader(self):
return self.db.User.find_one({'_id': self.uploader})
- def get_fail_exception(self):
- """
- Get the exception that's appropriate for this error
- """
- if self['fail_error']:
- return common.import_component(self['fail_error'])
-
class MediaComment(Document):
"""
diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py
index 31a6ed3b..95821b4f 100644
--- a/mediagoblin/db/sql/models.py
+++ b/mediagoblin/db/sql/models.py
@@ -7,6 +7,7 @@ from sqlalchemy import (
from sqlalchemy.orm import relationship
from mediagoblin.db.sql.base import GMGTableBase
+from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
Base = declarative_base(cls=GMGTableBase)
@@ -24,7 +25,7 @@ class SimpleFieldAlias(object):
setattr(instance, self.fieldname, val)
-class User(Base):
+class User(Base, UserMixin):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
@@ -48,7 +49,7 @@ class User(Base):
_id = SimpleFieldAlias("id")
-class MediaEntry(Base):
+class MediaEntry(Base, MediaEntryMixin):
__tablename__ = "media_entries"
id = Column(Integer, primary_key=True)
diff --git a/mediagoblin/staticdirect.py b/mediagoblin/staticdirect.py
index c6d2b374..2bddb160 100644
--- a/mediagoblin/staticdirect.py
+++ b/mediagoblin/staticdirect.py
@@ -14,9 +14,6 @@
# 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/>.
-import pkg_resources
-import urlparse
-
####################################
# Staticdirect infrastructure.
# Borrowed largely from cc.engine
@@ -26,7 +23,9 @@ import urlparse
####################################
import pkg_resources
-import urlparse
+import logging
+
+_log = logging.getLogger(__name__)
class StaticDirect(object):
@@ -37,6 +36,10 @@ class StaticDirect(object):
if filepath in self.cache:
return self.cache[filepath]
+ if not pkg_resources.resource_exists('mediagoblin',
+ 'static' + filepath):
+ _log.info("StaticDirect resource %r not found locally",
+ filepath)
static_direction = self.cache[filepath] = self.get(filepath)
return static_direction
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index 82ee41b7..5335ebe3 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -22,11 +22,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>{% block title %}{{ app_config['html_title'] }}{% endblock %}</title>
<link rel="stylesheet" type="text/css"
- href="{{ request.staticdirect('/css/reset.css') }}"/>
+ href="{{ request.staticdirect('/css/extlib/reset.css') }}"/>
<link rel="stylesheet" type="text/css"
href="{{ request.staticdirect('/css/base.css') }}"/>
- <link rel="stylesheet" type="text/css"
- href="{{ request.staticdirect('/css/video-js.css') }}"/>
<link rel="shortcut icon"
href="{{ request.staticdirect('/images/goblin.ico') }}" />
<script src="{{ request.staticdirect('/js/extlib/jquery.js') }}"></script>
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html
index 10525f4c..583e4ebd 100644
--- a/mediagoblin/templates/mediagoblin/user_pages/media.html
+++ b/mediagoblin/templates/mediagoblin/user_pages/media.html
@@ -158,6 +158,7 @@
</ul>
{% endif %}
{% if app_config['allow_attachments']
+ and request.user
and (media.uploader == request.user._id
or request.user.is_admin) %}
<p>
diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini
index 2525a4f9..c91ed92b 100644
--- a/mediagoblin/tests/test_mgoblin_app.ini
+++ b/mediagoblin/tests/test_mgoblin_app.ini
@@ -7,6 +7,9 @@ db_name = __mediagoblin_tests__
# tag parsing
tags_max_length = 50
+# So we can start to test attachments:
+allow_attachments = True
+
# Celery shouldn't be set up by the application as it's setup via
# mediagoblin.init.celery.from_celery
celery_setup_elsewhere = true
diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py
index 2b17c515..b3c11249 100644
--- a/mediagoblin/tests/test_submission.py
+++ b/mediagoblin/tests/test_submission.py
@@ -51,11 +51,17 @@ class TestSubmission:
self.test_user = test_user
+ self.login()
+
+ def login(self):
self.test_app.post(
'/auth/login/', {
'username': u'chris',
'password': 'toast'})
+ def logout(self):
+ self.test_app.get('/auth/logout/')
+
def test_missing_fields(self):
# Test blank form
# ---------------
@@ -95,6 +101,14 @@ class TestSubmission:
assert template.TEMPLATE_TEST_CONTEXT.has_key(
'mediagoblin/user_pages/user.html')
+ # Make sure the media view is at least reachable, logged in...
+ self.test_app.get('/u/chris/m/normal-upload-1/')
+ # ... and logged out too.
+ self.logout()
+ self.test_app.get('/u/chris/m/normal-upload-1/')
+ # Log back in for the remaining tests.
+ self.login()
+
# Test PNG
# --------
template.clear_test_template_context()
diff --git a/paste.ini b/paste.ini
index c729e41d..13c15209 100644
--- a/paste.ini
+++ b/paste.ini
@@ -19,6 +19,28 @@ use = egg:mediagoblin#app
filter-with = beaker
config = %(here)s/mediagoblin_local.ini %(here)s/mediagoblin.ini
+[loggers]
+keys = root
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = INFO
+handlers = console
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(asctime)s %(levelname)-7.7s [%(name)s] %(message)s
+
[app:publicstore_serve]
use = egg:Paste#static
document_root = %(here)s/user_dev/media/public/