aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin')
-rw-r--r--mediagoblin/db/sql/base.py6
-rw-r--r--mediagoblin/db/sql/migrations.py78
-rw-r--r--mediagoblin/db/sql/util.py10
-rw-r--r--mediagoblin/plugins/oauth/migrations.py92
-rw-r--r--mediagoblin/static/css/base.css4
-rw-r--r--mediagoblin/static/js/geolocation-map.js10
-rw-r--r--mediagoblin/templates/mediagoblin/auth/register.html2
-rw-r--r--mediagoblin/templates/mediagoblin/edit/attachments.html4
-rw-r--r--mediagoblin/templates/mediagoblin/root.html30
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/media.html4
-rw-r--r--mediagoblin/templates/mediagoblin/utils/geolocation_map.html15
-rw-r--r--mediagoblin/tools/text.py26
12 files changed, 203 insertions, 78 deletions
diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py
index 838080b0..e10e7739 100644
--- a/mediagoblin/db/sql/base.py
+++ b/mediagoblin/db/sql/base.py
@@ -79,11 +79,13 @@ class GMGTableBase(object):
sess.add(self)
sess.commit()
- def delete(self):
+ def delete(self, commit=True):
+ """Delete the object and commit the change immediately by default"""
sess = object_session(self)
assert sess is not None, "Not going to delete detached %r" % self
sess.delete(self)
- sess.commit()
+ if commit:
+ sess.commit()
Base = declarative_base(cls=GMGTableBase)
diff --git a/mediagoblin/db/sql/migrations.py b/mediagoblin/db/sql/migrations.py
index 1d822cd9..bc68caa3 100644
--- a/mediagoblin/db/sql/migrations.py
+++ b/mediagoblin/db/sql/migrations.py
@@ -17,11 +17,12 @@
import datetime
from sqlalchemy import (MetaData, Table, Column, Boolean, SmallInteger,
- Integer, Unicode, UnicodeText, DateTime, ForeignKey)
+ Integer, Unicode, UnicodeText, DateTime,
+ ForeignKey, UniqueConstraint)
+from sqlalchemy.ext.declarative import declarative_base
from mediagoblin.db.sql.util import RegisterMigration
-from mediagoblin.db.sql.models import MediaEntry, Collection, User, \
- ProcessingMetaData
+from mediagoblin.db.sql.models import MediaEntry, Collection, User
MIGRATIONS = {}
@@ -65,29 +66,40 @@ def add_transcoding_progress(db_conn):
db_conn.commit()
+class Collection_v0(declarative_base()):
+ __tablename__ = "core__collections"
+
+ id = Column(Integer, primary_key=True)
+ title = Column(Unicode, nullable=False)
+ slug = Column(Unicode)
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now,
+ index=True)
+ description = Column(UnicodeText)
+ creator = Column(Integer, ForeignKey(User.id), nullable=False)
+ items = Column(Integer, default=0)
+
+class CollectionItem_v0(declarative_base()):
+ __tablename__ = "core__collection_items"
+
+ id = Column(Integer, primary_key=True)
+ media_entry = Column(
+ Integer, ForeignKey(MediaEntry.id), nullable=False, index=True)
+ collection = Column(Integer, ForeignKey(Collection.id), nullable=False)
+ note = Column(UnicodeText, nullable=True)
+ added = Column(DateTime, nullable=False, default=datetime.datetime.now)
+ position = Column(Integer)
+
+ ## This should be activated, normally.
+ ## But this would change the way the next migration used to work.
+ ## So it's commented for now.
+ # __table_args__ = (
+ # UniqueConstraint('collection', 'media_entry'),
+ # {})
+
@RegisterMigration(4, MIGRATIONS)
def add_collection_tables(db_conn):
- metadata = MetaData(bind=db_conn.bind)
-
- collection = Table('core__collections', metadata,
- Column('id', Integer, primary_key=True),
- Column('title', Unicode, nullable=False),
- Column('slug', Unicode),
- Column('created', DateTime, nullable=False, default=datetime.datetime.now, index=True),
- Column('description', UnicodeText),
- Column('creator', Integer, ForeignKey(User.id), nullable=False),
- Column('items', Integer, default=0))
-
- collection_item = Table('core__collection_items', metadata,
- Column('id', Integer, primary_key=True),
- Column('media_entry', Integer, ForeignKey(MediaEntry.id), nullable=False, index=True),
- Column('collection', Integer, ForeignKey(Collection.id), nullable=False),
- Column('note', UnicodeText, nullable=True),
- Column('added', DateTime, nullable=False, default=datetime.datetime.now),
- Column('position', Integer))
-
- collection.create()
- collection_item.create()
+ Collection_v0.__table__.create(db_conn.bind)
+ CollectionItem_v0.__table__.create(db_conn.bind)
db_conn.commit()
@@ -104,15 +116,15 @@ def add_mediaentry_collected(db_conn):
db_conn.commit()
-@RegisterMigration(6, MIGRATIONS)
-def create_processing_metadata_table(db):
- metadata = MetaData(bind=db.bind)
+class ProcessingMetaData_v0(declarative_base()):
+ __tablename__ = 'core__processing_metadata'
- metadata_table = Table('core__processing_metadata', metadata,
- Column('id', Integer, primary_key=True),
- Column('media_entry_id', Integer, ForeignKey(MediaEntry.id),
- nullable=False, index=True),
- Column('callback_url', Unicode))
+ id = Column(Integer, primary_key=True)
+ media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False,
+ index=True)
+ callback_url = Column(Unicode)
- metadata_table.create()
+@RegisterMigration(6, MIGRATIONS)
+def create_processing_metadata_table(db):
+ ProcessingMetaData_v0.__table__.create(db.bind)
db.commit()
diff --git a/mediagoblin/db/sql/util.py b/mediagoblin/db/sql/util.py
index 74b5d73e..c6d8562e 100644
--- a/mediagoblin/db/sql/util.py
+++ b/mediagoblin/db/sql/util.py
@@ -39,7 +39,7 @@ class MigrationManager(object):
- migration_registry: where we should find all migrations to
run
"""
- self.name = name
+ self.name = unicode(name)
self.models = models
self.session = session
self.migration_registry = migration_registry
@@ -297,17 +297,17 @@ def media_entries_for_tag_slug(dummy_db, tag_slug):
& (Tag.slug == tag_slug))
-def clean_orphan_tags():
+def clean_orphan_tags(commit=True):
+ """Search for unused MediaTags and delete them"""
q1 = Session.query(Tag).outerjoin(MediaTag).filter(MediaTag.id==None)
for t in q1:
Session.delete(t)
-
# The "let the db do all the work" version:
# q1 = Session.query(Tag.id).outerjoin(MediaTag).filter(MediaTag.id==None)
# q2 = Session.query(Tag).filter(Tag.id.in_(q1))
# q2.delete(synchronize_session = False)
-
- Session.commit()
+ if commit:
+ Session.commit()
def check_collection_slug_used(dummy_db, creator_id, slug, ignore_c_id):
diff --git a/mediagoblin/plugins/oauth/migrations.py b/mediagoblin/plugins/oauth/migrations.py
index f2af3907..797e7585 100644
--- a/mediagoblin/plugins/oauth/migrations.py
+++ b/mediagoblin/plugins/oauth/migrations.py
@@ -14,16 +14,94 @@
# 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/>.
-from sqlalchemy import MetaData, Table
+from datetime import datetime, timedelta
+from sqlalchemy import (MetaData, Table, Column,
+ Integer, Unicode, Enum, DateTime, ForeignKey)
+from sqlalchemy.ext.declarative import declarative_base
from mediagoblin.db.sql.util import RegisterMigration
+from mediagoblin.db.sql.models import User
-from mediagoblin.plugins.oauth.models import OAuthClient, OAuthToken, \
- OAuthUserClient, OAuthCode
MIGRATIONS = {}
+class OAuthClient_v0(declarative_base()):
+ __tablename__ = 'oauth__client'
+
+ id = Column(Integer, primary_key=True)
+ created = Column(DateTime, nullable=False,
+ default=datetime.now)
+
+ name = Column(Unicode)
+ description = Column(Unicode)
+
+ identifier = Column(Unicode, unique=True, index=True)
+ secret = Column(Unicode, index=True)
+
+ owner_id = Column(Integer, ForeignKey(User.id))
+ redirect_uri = Column(Unicode)
+
+ type = Column(Enum(
+ u'confidential',
+ u'public',
+ name=u'oauth__client_type'))
+
+
+class OAuthUserClient_v0(declarative_base()):
+ __tablename__ = 'oauth__user_client'
+ id = Column(Integer, primary_key=True)
+
+ user_id = Column(Integer, ForeignKey(User.id))
+ client_id = Column(Integer, ForeignKey(OAuthClient_v0.id))
+
+ state = Column(Enum(
+ u'approved',
+ u'rejected',
+ name=u'oauth__relation_state'))
+
+
+class OAuthToken_v0(declarative_base()):
+ __tablename__ = 'oauth__tokens'
+
+ id = Column(Integer, primary_key=True)
+ created = Column(DateTime, nullable=False,
+ default=datetime.now)
+ expires = Column(DateTime, nullable=False,
+ default=lambda: datetime.now() + timedelta(days=30))
+ token = Column(Unicode, index=True)
+ refresh_token = Column(Unicode, index=True)
+
+ user_id = Column(Integer, ForeignKey(User.id), nullable=False,
+ index=True)
+
+ client_id = Column(Integer, ForeignKey(OAuthClient_v0.id), nullable=False)
+
+ def __repr__(self):
+ return '<{0} #{1} expires {2} [{3}, {4}]>'.format(
+ self.__class__.__name__,
+ self.id,
+ self.expires.isoformat(),
+ self.user,
+ self.client)
+
+
+class OAuthCode_v0(declarative_base()):
+ __tablename__ = 'oauth__codes'
+
+ id = Column(Integer, primary_key=True)
+ created = Column(DateTime, nullable=False,
+ default=datetime.now)
+ expires = Column(DateTime, nullable=False,
+ default=lambda: datetime.now() + timedelta(minutes=5))
+ code = Column(Unicode, index=True)
+
+ user_id = Column(Integer, ForeignKey(User.id), nullable=False,
+ index=True)
+
+ client_id = Column(Integer, ForeignKey(OAuthClient_v0.id), nullable=False)
+
+
@RegisterMigration(1, MIGRATIONS)
def remove_and_replace_token_and_code(db):
metadata = MetaData(bind=db.bind)
@@ -38,9 +116,9 @@ def remove_and_replace_token_and_code(db):
code_table.drop()
- OAuthClient.__table__.create(db.bind)
- OAuthUserClient.__table__.create(db.bind)
- OAuthToken.__table__.create(db.bind)
- OAuthCode.__table__.create(db.bind)
+ OAuthClient_v0.__table__.create(db.bind)
+ OAuthUserClient_v0.__table__.create(db.bind)
+ OAuthToken_v0.__table__.create(db.bind)
+ OAuthCode_v0.__table__.create(db.bind)
db.commit()
diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css
index 4120f965..f8a9e014 100644
--- a/mediagoblin/static/css/base.css
+++ b/mediagoblin/static/css/base.css
@@ -259,6 +259,10 @@ text-align: center;
height: 0;
}
+.hidden {
+ display: none;
+}
+
.media_sidebar h3 {
font-size: 1em;
margin: 0 0 5px;
diff --git a/mediagoblin/static/js/geolocation-map.js b/mediagoblin/static/js/geolocation-map.js
index de49a37d..26d94c5d 100644
--- a/mediagoblin/static/js/geolocation-map.js
+++ b/mediagoblin/static/js/geolocation-map.js
@@ -31,19 +31,15 @@ $(document).ready(function () {
var map = new L.Map('tile-map');
var mqtileUrl = 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg';
- var mqtileAttrib = 'Map data &copy; '
- + String(new Date().getFullYear())
- + ' OpenStreetMap contributors, CC-BY-SA.'
- + ' Imaging &copy; '
- + String(new Date().getFullYear())
- + ' <a target="_blank" href="http://mapquest.com">MapQuest</a>.';
+ var mqtileAttrib = '<a id="osm_license_link">see map license</a>';
var mqtile = new L.TileLayer(
mqtileUrl,
{maxZoom: 18,
attribution: mqtileAttrib,
subdomains: '1234'});
- var location = new L.LatLng(latitude, longitude);
+ map.attributionControl.setPrefix('');
+ var location = new L.LatLng(latitude, longitude);
map.setView(location, 13).addLayer(mqtile);
var marker = new L.Marker(location);
diff --git a/mediagoblin/templates/mediagoblin/auth/register.html b/mediagoblin/templates/mediagoblin/auth/register.html
index a2505cb9..6dff0207 100644
--- a/mediagoblin/templates/mediagoblin/auth/register.html
+++ b/mediagoblin/templates/mediagoblin/auth/register.html
@@ -42,4 +42,6 @@
</div>
</div>
</form>
+<!-- Focus the username field by default -->
+<script>$(document).ready(function(){$("#username").focus();});</script>
{% endblock %}
diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html
index 976b1619..641306e8 100644
--- a/mediagoblin/templates/mediagoblin/edit/attachments.html
+++ b/mediagoblin/templates/mediagoblin/edit/attachments.html
@@ -40,7 +40,7 @@
</div>
{% if media.attachment_files|count %}
- <h2>Attachments</h2>
+ <h2>{% trans %}Attachments{% endtrans %}</h2>
<ul>
{% for attachment in media.attachment_files %}
<li>
@@ -53,7 +53,7 @@
</ul>
{% endif %}
- <h2>Add attachment</h2>
+ <h2>{% trans %]Add attachment{% endtrans %}</h2>
{{ wtforms_util.render_divs(form) }}
<div class="form_submit_buttons">
<a href="{{ media.url_for_self(request.urlgen) }}">Cancel</a>
diff --git a/mediagoblin/templates/mediagoblin/root.html b/mediagoblin/templates/mediagoblin/root.html
index 99d3269f..047dd2bb 100644
--- a/mediagoblin/templates/mediagoblin/root.html
+++ b/mediagoblin/templates/mediagoblin/root.html
@@ -23,12 +23,30 @@
{% if request.user %}
{% if request.user.status == 'active' %}
<h1>{% trans %}Actions{% endtrans %}</h1>
- <p><a href="{{ request.urlgen('mediagoblin.submit.collection') }}">
- {% trans %}Create new collection{% endtrans %}
- </a></p>
- <p><a href="{{ request.urlgen('mediagoblin.edit.account') }}">
- {%- trans %}Change account settings{% endtrans -%}
- </a></p>
+ <ul>
+ <li><a href="{{ request.urlgen('mediagoblin.submit.start') }}">
+ {%- trans %}Add media{% endtrans -%}
+ </a></li>
+ <li><a href="{{ request.urlgen('mediagoblin.submit.collection') }}">
+ {%- trans %}Create new collection{% endtrans -%}
+ </a></li>
+ <li><a href="{{ request.urlgen('mediagoblin.edit.account') }}">
+ {%- trans %}Change account settings{% endtrans -%}
+ </a></li>
+ <li><a href="{{ request.urlgen('mediagoblin.user_pages.processing_panel',
+ user=request.user.username) }}">
+ {%- trans %}Media processing panel{% endtrans -%}
+ </a></li>
+ {% if request.user.is_admin %}
+ <li>Admin:
+ <ul>
+ <li><a href="{{ request.urlgen('mediagoblin.admin.panel') }}">
+ {%- trans %}Media processing panel{% endtrans -%}
+ </a></li>
+ </ul>
+ </li>
+ {% endif %}
+ </ul>
{% endif %}
<h1>{% trans %}Explore{% endtrans %}</h1>
{% else %}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html
index ac15dd2f..b870a8ae 100644
--- a/mediagoblin/templates/mediagoblin/user_pages/media.html
+++ b/mediagoblin/templates/mediagoblin/user_pages/media.html
@@ -197,7 +197,9 @@
<p>
<a type="submit" href="{{ request.urlgen('mediagoblin.user_pages.media_collect',
user=media.get_uploader.username,
- media=media._id) }}" class="button_action button_collect" >
+ media=media._id) }}"
+ class="button_action button_collect"
+ title="{% trans %}Add media to collection{% endtrans %}">
</a>
</p>
{% endif %}
diff --git a/mediagoblin/templates/mediagoblin/utils/geolocation_map.html b/mediagoblin/templates/mediagoblin/utils/geolocation_map.html
index cd57d1f8..b48678bb 100644
--- a/mediagoblin/templates/mediagoblin/utils/geolocation_map.html
+++ b/mediagoblin/templates/mediagoblin/utils/geolocation_map.html
@@ -33,6 +33,21 @@
<input type="hidden" id="gps-latitude"
value="{{ lat }}" />
</div>
+ <script> <!-- pop up full OSM license when clicked -->
+ $(document).ready(function(){
+ $("#osm_license_link").click(function () {
+ $("#osm_attrib").slideToggle("slow");
+ });
+ });
+ </script>
+ <div id="osm_attrib" class="hidden"><ul><li>
+ Data &copy;<a
+ href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>
+ contributors
+ </li><li>Imaging &copy;<a
+ href="http://mapquest.com">MapQuest</a></li><li>Maps powered by
+ <a href="http://leafletjs.com/"> Leaflet</a></li></ul>
+ </div>
<p>
<small>
{% trans -%}
diff --git a/mediagoblin/tools/text.py b/mediagoblin/tools/text.py
index ea231244..96df49d2 100644
--- a/mediagoblin/tools/text.py
+++ b/mediagoblin/tools/text.py
@@ -38,13 +38,12 @@ HTML_CLEANER = Cleaner(
allow_tags=[
'div', 'b', 'i', 'em', 'strong', 'p', 'ul', 'ol', 'li', 'a', 'br',
'pre', 'code'],
- remove_unknown_tags=False, # can't be used with allow_tags
+ remove_unknown_tags=False, # can't be used with allow_tags
safe_attrs_only=True,
- add_nofollow=True, # for now
+ add_nofollow=True, # for now
host_whitelist=(),
whitelist_tags=set([]))
-TAGS_DELIMITER=',';
def clean_html(html):
# clean_html barfs on an empty string
@@ -68,14 +67,12 @@ def convert_to_tag_list_of_dicts(tag_string):
stripped_tag_string = u' '.join(tag_string.strip().split())
# Split the tag string into a list of tags
- for tag in stripped_tag_string.split(
- TAGS_DELIMITER):
-
+ for tag in stripped_tag_string.split(','):
+ tag = tag.strip()
# Ignore empty or duplicate tags
- if tag.strip() and tag.strip() not in [t['name'] for t in taglist]:
-
- taglist.append({'name': tag.strip(),
- 'slug': url.slugify(tag.strip())})
+ if tag and tag not in [t['name'] for t in taglist]:
+ taglist.append({'name': tag,
+ 'slug': url.slugify(tag)})
return taglist
@@ -85,11 +82,10 @@ def media_tags_as_string(media_entry_tags):
This is the opposite of convert_to_tag_list_of_dicts
"""
- media_tag_string = ''
+ tags_string = ''
if media_entry_tags:
- media_tag_string = (TAGS_DELIMITER+u' ').join(
- [tag['name'] for tag in media_entry_tags])
- return media_tag_string
+ tags_string = u', '.join([tag['name'] for tag in media_entry_tags])
+ return tags_string
TOO_LONG_TAG_WARNING = \
@@ -107,7 +103,7 @@ def tag_length_validator(form, field):
if too_long_tags:
raise wtforms.ValidationError(
- TOO_LONG_TAG_WARNING % (mg_globals.app_config['tags_max_length'], \
+ TOO_LONG_TAG_WARNING % (mg_globals.app_config['tags_max_length'],
', '.join(too_long_tags)))