Changeset - 83e235ba0d01
[Not reviewed]
Merge
3 47 6
Goblin Refuge (GoblinRefuge) - 10 months ago 2018-07-08 16:44:13
mediagoblin@goblinrefuge.com
Merge branch 'master' into gr-updates
44 files changed with 318 insertions and 205 deletions:
0 comments (0 inline, 0 general)
.gitignore
Show inline comments
...
 
@@ -50,6 +50,7 @@
 
*~
 
*.swp
 
*.mo
 
*.patch
 

	
 
# The legacy of buildout
 
.installed.cfg
.gitmodules
Show inline comments
 
[submodule "pdf.js"]
 
	path = pdf.js
 
	url = git://github.com/mozilla/pdf.js.git
 
	url = https://github.com/mozilla/pdf.js.git
 
[submodule "extlib/pdf.js"]
 
	path = extlib/pdf.js
 
	url = git://github.com/mozilla/pdf.js.git
 
	url = https://github.com/mozilla/pdf.js.git
 
[submodule "extlib/skeleton"]
 
	path = extlib/skeleton
 
	url = git://github.com/dhg/Skeleton.git
 
	url = https://github.com/dhg/Skeleton.git
 
[submodule "extlib/sandyseventiesspeedboat"]
 
	path = extlib/sandyseventiesspeedboat
 
	url = https://github.com/jpope777/sandyseventiesspeedboat-mg.git
AUTHORS
Show inline comments
...
 
@@ -32,6 +32,7 @@ Thank you!
 
* Corey Farwell
 
* Chris Moylan
 
* Christopher Allan Webber
 
* chrysn
 
* Dan Callahan
 
* David Thompson
 
* Daniel Krol
...
 
@@ -94,6 +95,7 @@ Thank you!
 
* Robert Smith
 
* Rodney Ewing
 
* Rodrigo Rodrigues da Silva
 
* Romain Porte
 
* Runar Petursson
 
* Sacha De'Angeli
 
* Sam Clegg
...
 
@@ -105,6 +107,7 @@ Thank you!
 
* Shawn Khan
 
* Simon Fondrie-Teitler
 
* Stefano Zacchiroli
 
* Stéphane Péchard
 
* thallian
 
* Tiberiu C. Turbureanu
 
* Tom Fay
MANIFEST.in
Show inline comments
...
 
@@ -3,8 +3,17 @@ recursive-include mediagoblin *.js *.css *.png *.svg *.ico
 
recursive-include mediagoblin *.ini
 
recursive-include mediagoblin *.html *.txt
 
recursive-include docs *.rst *.html
 
recursive-include mediagoblin/db/migrations/versions *.py
 
recursive-include mediagoblin/media_types/ascii/migrations *.py
 
recursive-include mediagoblin/media_types/audio/migrations *.py
 
recursive-include mediagoblin/media_types/blog/migrations *.py
 
recursive-include mediagoblin/media_types/image/migrations *.py
 
recursive-include mediagoblin/media_types/pdf/migrations *.py
 
recursive-include mediagoblin/media_types/stl/migrations *.py
 
recursive-include mediagoblin/media_types/video/migrations *.py
 
include mediagoblin.example.ini mediagoblin/config_spec.ini paste.ini
 
include mediagoblin/config_spec.ini
 
include mediagoblin/db/migrations/alembic.ini
 
graft extlib
 
graft licenses
 
graft devtools
docs/source/siteadmin/commandline-upload.rst
Show inline comments
...
 
@@ -37,6 +37,7 @@ Here's a longer example that makes use of more options::
 
  ./bin/gmg addmedia aveyah awesome_spaceship.png \
 
      --title "My awesome spaceship" \
 
      --description "Flying my awesome spaceship, since I'm an awesome pilot" \
 
      --collection-slug i-m-an-awesome-pilot \
 
      --license "http://creativecommons.org/licenses/by-sa/3.0/" \
 
      --tags "spaceships, pilots, awesome" \
 
      --slug "awesome-spaceship"
...
 
@@ -57,7 +58,7 @@ it is a bit more complex.
 
This is an example of what a script may look like. The important part here is
 
that you have to create the 'metadata.csv' file.::
 

	
 
  media:location,dcterms:title,dcterms:creator,dcterms:type
 
  location,dcterms:title,dcterms:creator,dcterms:type
 
  "http://www.example.net/path/to/nap.png","Goblin taking a nap",,"Image"
 
  "http://www.example.net/path/to/snore.ogg","Goblin Snoring","Me","Audio"
 

	
...
 
@@ -86,6 +87,7 @@ just as easy to provide this information through the correct metadata columns.
 
- **license** is used to set a license for your piece a media for MediaGoblin's use. This must be a URI.
 
- **title** will set the title displayed to MediaGoblin users.
 
- **description** will set a description of your media.
 
- **collection-slug** will add the media to a collection, if a collection with the given slug exists.
 

	
 
Metadata columns
 
----------------
docs/source/siteadmin/configuration.rst
Show inline comments
...
 
@@ -54,30 +54,6 @@ mediagoblin/config_spec.ini
 
  option that we didn't tell you about. :)
 

	
 

	
 
Making local copies
 
===================
 

	
 
Let's assume you're doing the virtualenv setup described elsewhere in this
 
manual, and you need to make local tweaks to the config files. How do you do 
 
that? Let's see.
 

	
 
To make changes to mediagoblin.ini ::
 

	
 
    cp mediagoblin.ini mediagoblin_local.ini
 

	
 
To make changes to paste.ini ::
 

	
 
    cp paste.ini paste_local.ini
 

	
 
From here you should be able to make direct adjustments to the files,
 
and most of the commands described elsewhere in this manual will "notice"
 
your local config files and use those instead of the non-local version.
 

	
 
.. note::
 

	
 
   Note that all commands provide a way to pass in a specific config
 
   file also, usually by a ``-cf`` flag.
 

	
 

	
 
Common changes
 
==============
docs/source/siteadmin/deploying.rst
Show inline comments
...
 
@@ -70,20 +70,25 @@ derivatives) issue the following command::
 

	
 
    sudo apt-get install git-core python python-dev python-lxml \
 
        python-imaging python-virtualenv npm nodejs-legacy automake \
 
        nginx
 
        nginx rabbitmq-server
 

	
 
On a RPM-based system (e.g. Fedora, RedHat, and derivatives) issue the
 
following command::
 

	
 
    sudo yum install python-paste-deploy python-paste-script \
 
        git-core python python-devel python-lxml python-imaging \
 
        python-virtualenv npm automake nginx
 
        python-virtualenv npm automake nginx rabbitmq-server
 

	
 
(Note: MediaGoblin now officially supports Python 3.  You may instead
 
substitute from "python" to "python3" for most package names in the
 
Debian instructions and this should cover dependency installation.
 
These instructions have not yet been tested on Fedora.)
 

	
 
(Note: you might have to include additional repositories to a RPM-
 
based system, because rabbitmq-server might be not included in
 
official repositories. As an alternative, you can try installing
 
redis-server and configure it as celery broker)
 

	
 
Configure PostgreSQL
 
~~~~~~~~~~~~~~~~~~~~
 

	
...
 
@@ -235,7 +240,7 @@ Change to the MediaGoblin directory that you just created::
 

	
 
Clone the MediaGoblin repository and set up the git submodules::
 

	
 
    $ git clone git://git.savannah.gnu.org/mediagoblin.git -b stable
 
    $ git clone https://git.savannah.gnu.org/git/mediagoblin.git -b stable
 
    $ cd mediagoblin
 
    $ git submodule init && git submodule update
 

	
...
 
@@ -245,7 +250,7 @@ Clone the MediaGoblin repository and set up the git submodules::
 
   gitorious.org shut down, we had to move.  We are presently on
 
   Savannah.  You may need to update your git repository location::
 

	
 
    $ git remote set-url origin git://git.savannah.gnu.org/mediagoblin.git
 
    $ git remote set-url origin https://git.savannah.gnu.org/git/mediagoblin.git
 

	
 
Set up the hacking environment::
 

	
...
 
@@ -314,13 +319,16 @@ Edit site configuration
 
~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
A few basic properties must be set before MediaGoblin will work. First
 
make a copy of ``mediagoblin.ini`` and ``paste.ini`` for editing so the original
 
make a copy of ``paste.ini`` for editing so the original
 
config files aren't lost (you likely won't need to edit the paste configuration,
 
but we'll make a local copy of it just in case)::
 

	
 
    $ cp -av mediagoblin.ini mediagoblin_local.ini && cp -av paste.ini paste_local.ini
 
    $ cp -av paste.ini paste_local.ini
 

	
 
``mediagoblin.ini`` does not need to be copied, because original config is
 
stored in ``mediagoblin.example.ini``.
 

	
 
Then edit mediagoblin_local.ini:
 
Then edit ``mediagoblin.ini``:
 
 - Set ``email_sender_address`` to the address you wish to be used as
 
   the sender for system-generated emails
 
 - Edit ``direct_remote_path``, ``base_dir``, and ``base_url`` if
...
 
@@ -332,7 +340,7 @@ Configure MediaGoblin to use the PostgreSQL database
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
If you are using PostgreSQL, edit the ``[mediagoblin]`` section in your
 
``mediagoblin_local.ini`` and put in::
 
``mediagoblin.ini`` and put in::
 

	
 
    sql_engine = postgresql:///mediagoblin
 

	
docs/source/siteadmin/media-types.rst
Show inline comments
...
 
@@ -30,17 +30,14 @@ Enabling Media Types
 
.. note::
 
    Media types are now plugins
 

	
 
Media types are enabled in your MediaGoblin configuration file, typically it is
 
created by copying ``mediagoblin.ini`` to ``mediagoblin_local.ini`` and then
 
applying your changes to ``mediagoblin_local.ini``. If you don't already have a
 
``mediagoblin_local.ini``, create one in the way described.
 
Media types are enabled in your MediaGoblin configuration file.
 

	
 
Most media types have additional dependencies that you will have to install.
 
You will find descriptions on how to satisfy the requirements of each media type
 
on this page.
 

	
 
To enable a media type, add the the media type under the ``[plugins]`` section
 
in you ``mediagoblin_local.ini``. For example, if your system supported image
 
in you ``mediagoblin.ini``. For example, if your system supported image
 
and video media types, then it would look like this::
 

	
 
    [plugins]
...
 
@@ -99,7 +96,7 @@ good/bad/ugly).  On Debianoid systems
 

	
 

	
 
Add ``[[mediagoblin.media_types.video]]`` under the ``[plugins]`` section in
 
your ``mediagoblin_local.ini`` and restart MediaGoblin.
 
your ``mediagoblin.ini`` and restart MediaGoblin.
 

	
 
Run
 

	
...
 
@@ -139,7 +136,7 @@ Then install ``scikits.audiolab`` for the spectrograms::
 
    ./bin/pip install scikits.audiolab
 

	
 
Add ``[[mediagoblin.media_types.audio]]`` under the ``[plugins]`` section in your
 
``mediagoblin_local.ini`` and restart MediaGoblin.
 
``mediagoblin.ini`` and restart MediaGoblin.
 

	
 
Run
 

	
...
 
@@ -160,7 +157,7 @@ To enable raw image you need to install pyexiv2.  On Debianoid systems
 
    sudo apt-get install python-pyexiv2
 

	
 
Add ``[[mediagoblin.media_types.raw_image]]`` under the ``[plugins]``
 
section in your ``mediagoblin_local.ini`` and restart MediaGoblin.
 
section in your ``mediagoblin.ini`` and restart MediaGoblin.
 

	
 
Run
 

	
...
 
@@ -184,8 +181,7 @@ library, which is necessary for creating thumbnails of ASCII art
 
    ./bin/easy_install chardet
 

	
 

	
 
Next, modify (and possibly copy over from ``mediagoblin.ini``) your
 
``mediagoblin_local.ini``.  In the ``[plugins]`` section, add
 
Next, modify your ``mediagoblin.ini``.  In the ``[plugins]`` section, add
 
``[[mediagoblin.media_types.ascii]]``.
 

	
 
Run
...
 
@@ -207,7 +203,7 @@ It may work on some earlier versions, but that is not guaranteed (and
 
is surely not to work prior to Blender 2.5X).
 

	
 
Add ``[[mediagoblin.media_types.stl]]`` under the ``[plugins]`` section in your
 
``mediagoblin_local.ini`` and restart MediaGoblin.
 
``mediagoblin.ini`` and restart MediaGoblin.
 

	
 
Run
 

	
...
 
@@ -256,7 +252,7 @@ This feature has been tested on Fedora with:
 
It may work on some earlier versions, but that is not guaranteed.
 

	
 
Add ``[[mediagoblin.media_types.pdf]]`` under the ``[plugins]`` section in your
 
``mediagoblin_local.ini`` and restart MediaGoblin.
 
``mediagoblin.ini`` and restart MediaGoblin.
 

	
 
Run
 

	
docs/source/siteadmin/production-deployments.rst
Show inline comments
...
 
@@ -76,7 +76,7 @@ modify it to suit your environment's setup:
 
    ExecStartPre=/bin/mkdir -p /run/mediagoblin
 
    ExecStartPre=/bin/chown -hR mediagoblin:mediagoblin /run/mediagoblin
 
    # Celery process will run as the `mediagoblin` user after start.
 
    Environment=MEDIAGOBLIN_CONFIG=/srv/mediagoblin.example.org/mediagoblin/mediagoblin_local.ini \
 
    Environment=MEDIAGOBLIN_CONFIG=/srv/mediagoblin.example.org/mediagoblin/mediagoblin.ini \
 
                CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery
 
    ExecStart=/srv/mediagoblin.example.org/mediagoblin/bin/celery worker \
 
                  --logfile=/var/log/mediagoblin/celery.log \
docs/source/siteadmin/relnotes.rst
Show inline comments
...
 
@@ -36,7 +36,7 @@ carefully, or at least skim over it.
 
   gitorious.org shut down, we had to move.  We are presently on
 
   Savannah.  You may need to update your git repository location::
 

	
 
       git remote set-url origin git://git.savannah.gnu.org/mediagoblin.git
 
       git remote set-url origin https://git.savannah.gnu.org/git/mediagoblin.git
 

	
 

	
 
0.9.0
...
 
@@ -49,7 +49,7 @@ Python 3, which is pretty cool!
 
**Do this to upgrade**
 

	
 
0. If you haven't already, switch the git remote URL:
 
   ``git remote set-url origin git://git.savannah.gnu.org/mediagoblin.git``
 
   ``git remote set-url origin https://git.savannah.gnu.org/git/mediagoblin.git``
 
1. Update to the latest release.  If checked out from git, run:
 
   ``git fetch && git checkout -q v0.9.0``
 
2. Run
...
 
@@ -89,7 +89,7 @@ soon as possible.
 
**Do this to upgrade**
 

	
 
0. If you haven't already, switch the git remote URL:
 
   ``git remote set-url origin git://git.savannah.gnu.org/mediagoblin.git``
 
   ``git remote set-url origin https://git.savannah.gnu.org/git/mediagoblin.git``
 
1. Update to the latest release.  If checked out from git, run:
 
   ``git fetch && git checkout -q v0.8.1``
 
2. Run
...
 
@@ -143,7 +143,7 @@ trouble, consider pinging the MediaGoblin list or IRC channel.
 
**Do this to upgrade**
 

	
 
0. If you haven't already, switch the git remote URL:
 
   ``git remote set-url origin git://git.savannah.gnu.org/mediagoblin.git``
 
   ``git remote set-url origin https://git.savannah.gnu.org/git/mediagoblin.git``
 
1. If you don't have node.js installed, you'll need it for handling
 
   MediaGoblin's static web dependencies.  Install this via your
 
   distribution!  (In the glorious future MediaGoblin will be simply
docs/source/siteadmin/theming.rst
Show inline comments
...
 
@@ -43,7 +43,7 @@ want to install this theme!  Don't worry, it's fairly painless.
 
3. ``tar -xzvf <tar-archive>``
 

	
 
4. Open your configuration file (probably named
 
   ``mediagoblin_local.ini``) and set the theme name::
 
   ``mediagoblin.ini``) and set the theme name::
 

	
 
       [mediagoblin]
 
       # ...
lazystarter.sh
Show inline comments
...
 
@@ -25,7 +25,7 @@ case "$selfname" in
 
        ini_prefix=paste
 
        ;;
 
    lazycelery.sh)
 
        starter_cmd=celeryd
 
        starter_cmd=celery
 
        ini_prefix=mediagoblin
 
        ;;
 
    *)
...
 
@@ -87,7 +87,7 @@ case "$selfname" in
 
    lazycelery.sh)
 
        MEDIAGOBLIN_CONFIG="${ini_file}" \
 
            CELERY_CONFIG_MODULE=mediagoblin.init.celery.from_celery \
 
            $starter -B "$@"
 
            $starter worker -B "$@"
 
        ;;
 
    *) exit 1 ;;
 
esac
mediagoblin/api/views.py
Show inline comments
...
 
@@ -115,8 +115,13 @@ def uploads_endpoint(request):
 
            )
 

	
 
        mimetype = request.headers["Content-Type"]
 
        filename = mimetypes.guess_all_extensions(mimetype)
 
        filename = 'unknown' + filename[0] if filename else filename
 

	
 
        if "X-File-Name" in request.headers:
 
            filename = request.headers["X-File-Name"]
 
        else:
 
            filename = mimetypes.guess_all_extensions(mimetype)
 
            filename = 'unknown' + filename[0] if filename else filename
 

	
 
        file_data = FileStorage(
 
            stream=io.BytesIO(request.data),
 
            filename=filename,
mediagoblin/auth/views.py
Show inline comments
...
 
@@ -14,6 +14,8 @@
 
# 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 logging
 

	
 
import six
 

	
 
from itsdangerous import BadSignature
...
 
@@ -29,6 +31,8 @@ from mediagoblin.tools.pluginapi import hook_handle
 
from mediagoblin.auth.tools import (send_verification_email, register_user,
 
                                    check_login_simple)
 

	
 
_log = logging.getLogger(__name__)
 

	
 

	
 
@allow_registration
 
@auth_enabled
...
 
@@ -105,6 +109,8 @@ def login(request):
 
                    return redirect(request, "index")
 

	
 
            login_failed = True
 
            remote_addr = request.access_route[-1] or request.remote_addr
 
            _log.warn("Failed login attempt from %r", remote_addr)
 

	
 
    return render_to_response(
 
        request,
mediagoblin/config_spec.ini
Show inline comments
...
 
@@ -153,8 +153,7 @@ CELERY_RESULT_BACKEND = string(default="database")
 
CELERY_RESULT_DBURI = string(default="sqlite:///%(here)s/celery.db")
 

	
 
# default kombu stuff
 
BROKER_TRANSPORT = string(default="sqlalchemy")
 
BROKER_URL = string(default="sqlite:///%(here)s/kombu.db")
 
BROKER_URL = string(default="amqp://")
 

	
 
# known booleans
 
CELERY_RESULT_PERSISTENT = boolean()
mediagoblin/db/migration_tools.py
Show inline comments
...
 
@@ -365,9 +365,8 @@ def build_alembic_config(global_config, cmd_options, session):
 
    configuration.  Initialize the database session appropriately
 
    as well.
 
    """
 
    root_dir = os.path.abspath(os.path.dirname(os.path.dirname(
 
        os.path.dirname(__file__))))
 
    alembic_cfg_path = os.path.join(root_dir, 'alembic.ini')
 
    alembic_dir = os.path.join(os.path.dirname(__file__), 'migrations')
 
    alembic_cfg_path = os.path.join(alembic_dir, 'alembic.ini')
 
    cfg = Config(alembic_cfg_path,
 
                 cmd_opts=cmd_options)
 
    cfg.attributes["session"] = session
mediagoblin/db/migrations/alembic.ini
Show inline comments
 
file renamed from alembic.ini to mediagoblin/db/migrations/alembic.ini
...
 
@@ -2,7 +2,7 @@
 

	
 
[alembic]
 
# path to migration scripts
 
script_location = %(here)s/mediagoblin/db/migrations
 
script_location = %(here)s
 

	
 
# template used to generate migration files
 
# file_template = %%(rev)s_%%(slug)s
mediagoblin/db/migrations/env.py
Show inline comments
...
 
@@ -48,7 +48,7 @@ def run_migrations_online():
 
    and associate a connection with the context.
 

	
 
    """
 
    connection = config.attributes["session"].get_bind()
 
    connection = config.attributes["session"].connection()
 
    context.configure(
 
                connection=connection,
 
                target_metadata=target_metadata
...
 
@@ -61,4 +61,3 @@ if context.is_offline_mode():
 
    run_migrations_offline()
 
else:
 
    run_migrations_online()
 

	
mediagoblin/db/models.py
Show inline comments
...
 
@@ -43,6 +43,7 @@ from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, \
 
from mediagoblin.tools.files import delete_media_files
 
from mediagoblin.tools.common import import_component
 
from mediagoblin.tools.routing import extract_url_arguments
 
from mediagoblin.tools.text import convert_to_tag_list_of_dicts
 

	
 
import six
 
from six.moves.urllib.parse import urljoin
...
 
@@ -770,7 +771,6 @@ class MediaEntry(Base, MediaEntryMixin, CommentingMixin):
 
                "self": {
 
                    "href": public_id,
 
                },
 

	
 
            }
 
        }
 

	
...
 
@@ -786,6 +786,12 @@ class MediaEntry(Base, MediaEntryMixin, CommentingMixin):
 
        if self.location:
 
            context["location"] = self.get_location.serialize(request)
 

	
 
        # Always show tags, even if empty list
 
        if self.tags:
 
            context["tags"] = [tag['name'] for tag in self.tags]
 
        else:
 
            context["tags"] = []
 

	
 
        if show_comments:
 
            comments = [
 
                l.comment().serialize(request) for l in self.get_comments()]
...
 
@@ -833,6 +839,9 @@ class MediaEntry(Base, MediaEntryMixin, CommentingMixin):
 
        if "location" in data:
 
            License.create(data["location"], self)
 

	
 
        if "tags" in data:
 
            self.tags = convert_to_tag_list_of_dicts(', '.join(data["tags"]))
 

	
 
        return True
 

	
 
class FileKeynames(Base):
mediagoblin/edit/views.py
Show inline comments
 
# 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
...
 
@@ -70,7 +70,7 @@ def edit_media(request, media):
 
        license=media.license)
 

	
 
    form = forms.EditForm(
 
        request.form,
 
        request.method=='POST' and request.form or None,
 
        **defaults)
 

	
 
    if request.method == 'POST' and form.validate():
...
 
@@ -219,7 +219,8 @@ def edit_profile(request, url_user=None):
 
    else:
 
        location = user.get_location.name
 

	
 
    form = forms.EditProfileForm(request.form,
 
    form = forms.EditProfileForm(
 
        request.method == 'POST' and request.form or None,
 
        url=user.url,
 
        bio=user.bio,
 
        location=location)
...
 
@@ -235,6 +236,8 @@ def edit_profile(request, url_user=None):
 
            location = user.get_location
 
            location.name = six.text_type(form.location.data)
 
            location.save()
 
        else:
 
            user.location = None
 

	
 
        user.save()
 

	
...
 
@@ -260,7 +263,8 @@ EMAIL_VERIFICATION_TEMPLATE = (
 
@require_active_login
 
def edit_account(request):
 
    user = request.user
 
    form = forms.EditAccountForm(request.form,
 
    form = forms.EditAccountForm(
 
        request.method == 'POST' and request.form or None,
 
        wants_comment_notification=user.wants_comment_notification,
 
        license_preference=user.license_preference,
 
        wants_notifications=user.wants_notifications)
...
 
@@ -358,7 +362,7 @@ def edit_collection(request, collection):
 
        description=collection.description)
 

	
 
    form = forms.EditCollectionForm(
 
        request.form,
 
        request.method == 'POST' and request.form or None,
 
        **defaults)
 

	
 
    if request.method == 'POST' and form.validate():
...
 
@@ -454,7 +458,8 @@ def verify_email(request):
 
@require_active_login
 
def change_email(request):
 
    """ View to change the user's email """
 
    form = forms.ChangeEmailForm(request.form)
 
    form = forms.ChangeEmailForm(
 
        request.method == 'POST' and request.form or None)
 
    user = request.user
 

	
 
    # If no password authentication, no need to enter a password
...
 
@@ -511,7 +516,8 @@ def edit_metadata(request, media):
 
    if not media.state == u'processed':
 
        return render_404(request)
 

	
 
    form = forms.EditMetaDataForm(request.form)
 
    form = forms.EditMetaDataForm(
 
        request.method == 'POST' and request.form or None)
 
    if request.method == "POST" and form.validate():
 
        metadata_dict = dict([(row['identifier'],row['value'])
 
                            for row in form.media_metadata.data])
mediagoblin/gmg_commands/addmedia.py
Show inline comments
...
 
@@ -56,6 +56,11 @@ def parser_setup(subparser):
 
        help=(
 
            "Slug for this media entry. "
 
            "Will be autogenerated if unspecified."))
 
    subparser.add_argument(
 
        "-c", "--collection-slug",
 
        help=(
 
            "Slug of the collection for this media entry. "
 
            "Should already exist."))
 

	
 
    subparser.add_argument(
 
        '--celery',
...
 
@@ -100,6 +105,7 @@ def addmedia(args):
 
            submitted_file=open(abs_filename, 'rb'), filename=filename,
 
            title=maybe_unicodeify(args.title),
 
            description=maybe_unicodeify(args.description),
 
            collection_slug=args.collection_slug,
 
            license=maybe_unicodeify(args.license),
 
            tags_string=maybe_unicodeify(args.tags) or u"")
 
    except FileUploadLimit:
mediagoblin/gmg_commands/batchaddmedia.py
Show inline comments
...
 
@@ -19,6 +19,7 @@ from __future__ import print_function
 
import codecs
 
import csv
 
import os
 
import sys
 

	
 
import requests
 
import six
...
 
@@ -28,8 +29,7 @@ from six.moves.urllib.parse import urlparse
 
from mediagoblin.db.models import LocalUser
 
from mediagoblin.gmg_commands import util as commands_util
 
from mediagoblin.submit.lib import (
 
    submit_media, get_upload_file_limits,
 
    FileUploadLimit, UserUploadLimit, UserPastUploadLimit)
 
    submit_media, FileUploadLimit, UserUploadLimit, UserPastUploadLimit)
 
from mediagoblin.tools.metadata import compact_and_validate
 
from mediagoblin.tools.translate import pass_to_ugettext as _
 
from jsonschema.exceptions import ValidationError
...
 
@@ -73,8 +73,6 @@ def batchaddmedia(args):
 
                    username=args.username)))
 
        return
 

	
 
    temp_files = []
 

	
 
    if os.path.isfile(args.metadata_path):
 
        metadata_path = args.metadata_path
 

	
...
 
@@ -99,7 +97,7 @@ def batchaddmedia(args):
 
        contents = all_metadata.read()
 
        media_metadata = parse_csv_file(contents)
 

	
 
    for media_id, file_metadata in media_metadata.iteritems():
 
    for media_id, file_metadata in media_metadata.items():
 
        files_attempted += 1
 
        # In case the metadata was not uploaded initialize an empty dictionary.
 
        json_ld_metadata = compact_and_validate({})
...
 
@@ -113,6 +111,7 @@ def batchaddmedia(args):
 
        title = file_metadata.get('title') or file_metadata.get('dc:title')
 
        description = (file_metadata.get('description') or
 
            file_metadata.get('dc:description'))
 
        collection_slug = file_metadata.get('collection-slug')
 

	
 
        license = file_metadata.get('license')
 
        try:
...
 
@@ -141,7 +140,7 @@ Metadata was not uploaded.""".format(
 
                file_path = os.path.join(abs_metadata_dir, path)
 
                file_abs_path = os.path.abspath(file_path)
 
            try:
 
                media_file = file(file_abs_path, 'r')
 
                media_file = open(file_abs_path, 'rb')
 
            except IOError:
 
                print(_(u"""\
 
FAIL: Local file {filename} could not be accessed.
...
 
@@ -155,6 +154,7 @@ FAIL: Local file {filename} could not be accessed.
 
                filename=filename,
 
                title=maybe_unicodeify(title),
 
                description=maybe_unicodeify(description),
 
                collection_slug=maybe_unicodeify(collection_slug),
 
                license=maybe_unicodeify(license),
 
                metadata=json_ld_metadata,
 
                tags_string=u"")
...
 
@@ -203,7 +203,12 @@ def parse_csv_file(file_contents):
 
    # Build a dictionary
 
    for index, line in enumerate(lines):
 
        if line.isspace() or line == u'': continue
 
        values = unicode_csv_reader([line]).next()
 
        if (sys.version_info[0] == 3):
 
            # Python 3's csv.py supports Unicode out of the box.
 
            reader = csv.reader([line])
 
        else:
 
            reader = unicode_csv_reader([line])
 
        values = next(reader)
 
        line_dict = dict([(key[i], val)
 
            for i, val in enumerate(values)])
 
        media_id = line_dict.get('id') or index
mediagoblin/gmg_commands/dbupdate.py
Show inline comments
...
 
@@ -133,7 +133,9 @@ def run_alembic_migrations(db, app_config, global_config):
 
    session = Session()
 
    cfg = build_alembic_config(global_config, None, session)
 

	
 
    return command.upgrade(cfg, 'heads')
 
    res = command.upgrade(cfg, 'heads')
 
    session.commit()
 
    return res
 

	
 

	
 
def run_dbupdate(app_config, global_config):
...
 
@@ -146,7 +148,7 @@ def run_dbupdate(app_config, global_config):
 
    # Set up the database
 
    db = setup_connection_and_db_from_config(app_config, migrations=True)
 

	
 
    # Do we have migrations 
 
    # Do we have migrations
 
    should_run_sqam_migrations = db.engine.has_table("core__migrations") and \
 
                                 sqam_migrations_to_run(db, app_config,
 
                                                        global_config)
mediagoblin/init/config.py
Show inline comments
...
 
@@ -123,6 +123,7 @@ def read_mediagoblin_config(config_path, config_spec_path=CONFIG_SPEC_PATH):
 
    config = ConfigObj(
 
        config_path,
 
        configspec=config_spec,
 
        encoding="UTF8",
 
        interpolation="ConfigParser")
 

	
 
    _setup_defaults(config, config_path, mainconfig_defaults)
mediagoblin/plugins/metadata_display/templates/mediagoblin/plugins/metadata_display/metadata_table.html.orig
Show inline comments
 
deleted file
mediagoblin/processing/task.py
Show inline comments
...
 
@@ -69,6 +69,9 @@ class ProcessMedia(celery.Task):
 
    """
 
    Pass this entry off for processing.
 
    """
 

	
 
    name = 'process_media'
 

	
 
    def run(self, media_id, feed_url, reprocess_action, reprocess_info=None):
 
        """
 
        Pass the media entry off to the appropriate processing function
mediagoblin/static/css/audio.css
Show inline comments
...
 
@@ -24,10 +24,11 @@
 
    font-size: 40px;
 
    width: 50px;
 
    text-shadow: 0 0 10px black;
 
    background: none;
 
    border: none;
 
}
 
    .audio-control-play-pause.playing {
 
        color: #b71500;
 
        letter-spacing: -17px;
 
        margin-left: -7px;
 
    }
 
    .audio-control-play-pause.paused {
mediagoblin/static/js/audio.js
Show inline comments
...
 
@@ -116,6 +116,10 @@ var audioPlayer = new Object();
 
        var im = audioPlayer.imageElement;
 
        var pos = (e.offsetX || e.originalEvent.layerX) / im.width();
 

	
 
        console.log('pos', (e.offsetX || e.originalEvent.layerX) / im.width())
 
        console.log('setting current time to',
 
            pos * audioPlayer.audioElement.duration)
 

	
 
        audioPlayer.audioElement.currentTime = pos * audioPlayer.audioElement.duration;
 
        audioPlayer.audioElement.play();
 
        audioPlayer.setState(audioPlayer.PLAYING);
...
 
@@ -151,14 +155,16 @@ var audioPlayer = new Object();
 

	
 
        switch (state) {
 
            case audioPlayer.PLAYING:
 
                $('.audio-spectrogram .audio-control-play-pause')
 
                el = $('.audio-spectrogram .audio-control-play-pause')
 
                    .removeClass('paused').addClass('playing')
 
                    .text('▮▮');
 
                    .text('▮▮').attr('aria-label', 'Pause');
 
                el[0].setAttribute('aria-label', 'Pause')
 
                break;
 
            case audioPlayer.PAUSED:
 
                $('.audio-spectrogram .audio-control-play-pause')
 
                el = $('.audio-spectrogram .audio-control-play-pause')
 
                    .removeClass('playing').addClass('paused')
 
                    .text('▶');
 
                    .text('▶').attr('aria-label', 'Play');
 
                el[0].setAttribute('aria-label', 'Play')
 
                break;
 
        }
 
    };
...
 
@@ -200,19 +206,9 @@ var audioPlayer = new Object();
 
         * Attach the player to an image element
 
         */
 
        console.log(imageElement);
 

	
 
        var im = $(imageElement);
 

	
 
        audioPlayer.imageElement = im;
 

	
 
        $('<div class="playhead"></div>').appendTo(im.parent());
 
        $('<div class="buffered-indicators"></div>').appendTo(im.parent());
 
        $('<div class="seekbar"></div>').appendTo(im.parent());
 
        $('<div class="audio-control-play-pause paused">▶</div>').appendTo(im.parent());
 
        $('<div class="audio-currentTime">00:00</div>').appendTo(im.parent());
 
        $('<input type="range" class="audio-volume"'
 
                +'value="1" min="0" max="1" step="0.001" />').appendTo(im.parent());
 
        $('.audio-spectrogram').trigger('attachedControls');
 
    };
 
})(audioPlayer);
 

	
mediagoblin/static/js/post_comment.js
Show inline comments
 
new file 100644
 
/**
 
 * 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/>.
 
 */
 

	
 
$(document).ready(function(){
 
    $(function() {
 
        // Hide this button if script is enabled
 
        $('.form_submit_buttons').find('input').hide();
 

	
 
        // Include this link if script is enabled
 
        $('.form_submit_buttons').append(
 
            '<a class="button_action" id="post_comment" type="button">' +
 
            'Add this comment </a>');
 

	
 
        $('#post_comment').click(function() {
 
            $.ajax({
 
                url: $('#postCommentURL').val(),
 
                data: $('#form_comment').serialize(),
 
                type: 'POST',
 
                success: function(response) {
 
                    var message = $(response).find('.mediagoblin_messages');
 
                    var commentsInResponse = $($(response).find('.media_comments')).find('li');
 
                    var commentsInPage = $('.media_comments').find('ul');
 
                    
 
                    // Post the message
 
                    message.css({"position":"fixed", "top":"50px", "width":"100%"});
 
                    $('body').append(message);
 
                    message.delay(1500).fadeOut();
 

	
 
                    // Checking if there is new comment
 
                    if(commentsInResponse.length != $(commentsInPage).find('li').length) {
 
                        // Post comment and scroll down to it
 
                        var newComment = commentsInResponse[commentsInResponse.length - 1];
 
                        $('#form_comment').fadeOut('fast');
 
                        $('#button_addcomment').fadeIn('fast');
 
                        $('#comment_preview').replaceWith("<div id=comment_preview></div>");
 
                        $(commentsInPage).append(newComment);
 
                        $('html, body').animate({
 
                            scrollTop: $(newComment).offset().top
 
                        }, 1000);
 
                    }
 
                },
 
                error: function(error) {
 
                    console.log(error);
 
                }
 
            });
 
        });
 
    });
 
});
...
 
\ No newline at end of file
mediagoblin/submit/lib.py
Show inline comments
...
 
@@ -27,11 +27,12 @@ from mediagoblin import mg_globals
 
from mediagoblin.tools.response import json_response
 
from mediagoblin.tools.text import convert_to_tag_list_of_dicts
 
from mediagoblin.tools.federation import create_activity, create_generator
 
from mediagoblin.db.models import MediaEntry, ProcessingMetaData
 
from mediagoblin.db.models import Collection, MediaEntry, ProcessingMetaData
 
from mediagoblin.processing import mark_entry_failed
 
from mediagoblin.processing.task import ProcessMedia
 
from mediagoblin.notifications import add_comment_subscription
 
from mediagoblin.media_types import sniff_media
 
from mediagoblin.user_pages.lib import add_media_to_collection
 

	
 

	
 
_log = logging.getLogger(__name__)
...
 
@@ -101,7 +102,7 @@ class UserPastUploadLimit(UploadLimitError):
 

	
 

	
 
def submit_media(mg_app, user, submitted_file, filename,
 
                 title=None, description=None,
 
                 title=None, description=None, collection_slug=None,
 
                 license=None, metadata=None, tags_string=u"",
 
                 callback_url=None, urlgen=None,):
 
    """
...
 
@@ -115,6 +116,7 @@ def submit_media(mg_app, user, submitted_file, filename,
 
       one on disk being referenced by submitted_file.
 
     - title: title for this media entry
 
     - description: description for this media entry
 
     - collection_slug: collection for this media entry
 
     - license: license for this media entry
 
     - tags_string: comma separated string of tags to be associated
 
       with this entry
...
 
@@ -203,6 +205,13 @@ def submit_media(mg_app, user, submitted_file, filename,
 
    create_activity("post", entry, entry.actor)
 
    entry.save()
 

	
 
    # add to collection
 
    if collection_slug:
 
        collection = Collection.query.filter_by(slug=collection_slug,
 
                                                actor=user.id).first()
 
        if collection:
 
            add_media_to_collection(collection, entry)
 

	
 
    # Pass off to processing
 
    #
 
    # (... don't change entry after this point to avoid race
mediagoblin/templates/mediagoblin/api/host-meta.xml
Show inline comments
 
file renamed from mediagoblin/templates/mediagoblin/federation/host-meta.xml to mediagoblin/templates/mediagoblin/api/host-meta.xml
mediagoblin/templates/mediagoblin/media_displays/audio.html
Show inline comments
...
 
@@ -30,6 +30,12 @@
 
    <div class="audio-media">
 
      {% if 'spectrogram' in media.media_files %}
 
        <div class="audio-spectrogram">
 
          <div class="playhead"></div>
 
          <div class="buffered-indicators"></div>
 
          <div class="seekbar"></div>
 
          <button class="audio-control-play-pause paused" aria-label="Play">▶</button>
 
          <div class="audio-currentTime" aria-label="current time">00:00</div>
 
          <input type="range" class="audio-volume" value="1" min="0" max="1" step="0.001" aria-label="volume" />
 
	  <img src="{{ request.app.public_store.file_url(
 
		        media.media_files.spectrogram) }}"
 
	       alt="Spectrogram" />
mediagoblin/templates/mediagoblin/moderation/media_panel.html
Show inline comments
...
 
@@ -35,6 +35,7 @@
 
{% if processing_entries.count() %}
 
  <table class="media_panel processing">
 
    <tr>
 
      <th>{% trans %}Thumbnail{% endtrans %}</th>
 
      <th>{% trans %}ID{% endtrans %}</th>
 
      <th>{% trans %}User{% endtrans %}</th>
 
      <th>{% trans %}Title{% endtrans %}</th>
mediagoblin/templates/mediagoblin/user_pages/media.html
Show inline comments
...
 
@@ -29,6 +29,8 @@
 
          src="{{ request.staticdirect('/js/comment_show.js') }}"></script>
 
  <!-- <script type="text/javascript"
 
          src="{{ request.staticdirect('/js/keyboard_navigation.js') }}"></script> -->
 
  <script type="text/javascript"
 
          src="{{ request.staticdirect('/js/post_comment.js') }}"></script>
 

	
 
  {% template_hook("location_head") %}
 
  {% template_hook("media_head") %}
...
 
@@ -117,6 +119,7 @@
 
            <input type="submit" value="{% trans %}Add this comment{% endtrans %}" class="button_action" />
 
              {{ csrf_token }}
 
          </div>
 
          <input type="hidden" value="{{ request.urlgen('mediagoblin.user_pages.media_post_comment', user= media.get_actor.username, media_id=media.id) }}" id="postCommentURL" />
 
          <input type="hidden" value="{{ request.urlgen('mediagoblin.user_pages.media_preview_comment') }}" id="previewURL" />
 
          <input type="hidden" value="{% trans %}Comment Preview{% endtrans %}" id="previewText"/>
 
        </form>
mediagoblin/templates/mediagoblin/utils/collection_gallery.html
Show inline comments
...
 
@@ -37,8 +37,11 @@
 
              <img src="{{ obj.thumb_url }}" />
 
            </a>
 

	
 
	    {% if obj.title %}
 
	    <a href="{{ obj_url }}">{{ obj.title }}</a>
 
	    {% endif %}
 
            {% if item.note %}
 
              <a href="{{ obj_url }}">{{ item.note }}</a>
 
	      {{ item.note }}
 
            {% endif %}
 
	    {% if request.user and
 
                  (item.in_collection.actor == request.user.id or
mediagoblin/tests/.gitignore
Show inline comments
 
new file 100644
 
.cache
mediagoblin/tests/fake_carrot_conf_good.ini
Show inline comments
...
 
@@ -7,7 +7,7 @@ num_carrots = 88
 
encouragement_phrase = "I'd love it if you eat your carrots!"
 

	
 
# Something extra!
 
blah_blah = "blah!"
 
blah_blah = "blæh!"
 

	
 
[celery]
 
EAT_CELERY_WITH_CARROTS = False
mediagoblin/tests/test_api.py
Show inline comments
...
 
@@ -25,11 +25,11 @@ from webtest import AppError
 

	
 
from .resources import GOOD_JPG
 
from mediagoblin import mg_globals
 
from mediagoblin.db.models import User, Activity, MediaEntry, TextComment
 
from mediagoblin.tools.routing import extract_url_arguments
 
from mediagoblin.db.models import User, MediaEntry, TextComment
 
from mediagoblin.tests.tools import fixture_add_user
 
from mediagoblin.moderation.tools import take_away_privileges
 

	
 

	
 
class TestAPI(object):
 
    """ Test mediagoblin's pump.io complient APIs """
 

	
...
 
@@ -38,7 +38,8 @@ class TestAPI(object):
 
        self.test_app = test_app
 
        self.db = mg_globals.database
 

	
 
        self.user = fixture_add_user(privileges=[u'active', u'uploader', u'commenter'])
 
        self.user = fixture_add_user(privileges=[u'active', u'uploader',
 
                                                 u'commenter'])
 
        self.other_user = fixture_add_user(
 
            username="otheruser",
 
            privileges=[u'active', u'uploader', u'commenter']
...
 
@@ -61,7 +62,7 @@ class TestAPI(object):
 

	
 
        return response, json.loads(response.body.decode())
 

	
 
    def _upload_image(self, test_app, image):
 
    def _upload_image(self, test_app, image, custom_filename=None):
 
        """ Uploads and image to MediaGoblin via pump.io API """
 
        data = open(image, "rb").read()
 
        headers = {
...
 
@@ -69,6 +70,8 @@ class TestAPI(object):
 
            "Content-Length": str(len(data))
 
        }
 

	
 
        if custom_filename is not None:
 
            headers["X-File-Name"] = custom_filename
 

	
 
        with self.mock_oauth():
 
            response = test_app.post(
...
 
@@ -126,9 +129,48 @@ class TestAPI(object):
 
        assert image["objectType"] == "image"
 

	
 
        # Check that we got the response we're expecting
 
        response, _ = self._post_image_to_feed(test_app, image)
 
        response, data = self._post_image_to_feed(test_app, image)
 
        assert response.status_code == 200
 
        assert data["object"]["fullImage"]["url"].endswith("unknown.jpe")
 
        assert data["object"]["image"]["url"].endswith("unknown.thumbnail.jpe")
 

	
 
    def test_can_post_image_custom_filename(self, test_app):
 
        """ Tests an image can be posted to the API with custom filename """
 
        # First request we need to do is to upload the image
 
        response, image = self._upload_image(test_app, GOOD_JPG,
 
                                             custom_filename="hello.jpg")
 

	
 
        # I should have got certain things back
 
        assert response.status_code == 200
 

	
 
        assert "id" in image
 
        assert "fullImage" in image
 
        assert "url" in image["fullImage"]
 
        assert "url" in image
 
        assert "author" in image
 
        assert "published" in image
 
        assert "updated" in image
 
        assert image["objectType"] == "image"
 

	
 
        # Check that we got the response we're expecting
 
        response, data = self._post_image_to_feed(test_app, image)
 
        assert response.status_code == 200
 
        assert data["object"]["fullImage"]["url"].endswith("hello.jpg")
 
        assert data["object"]["image"]["url"].endswith("hello.thumbnail.jpg")
 

	
 
    def test_can_post_image_tags(self, test_app):
 
        """ Tests that an image can be posted to the API """
 
        # First request we need to do is to upload the image
 
        response, image = self._upload_image(test_app, GOOD_JPG)
 
        assert response.status_code == 200
 

	
 
        image["tags"] = ["hello", "world"]
 

	
 
        # Check that we got the response we're expecting
 
        response, data = self._post_image_to_feed(test_app, image)
 
        assert response.status_code == 200
 
        assert data["object"]["tags"] == ["hello", "world"]
 

	
 
    def test_unable_to_upload_as_someone_else(self, test_app):
 
        """ Test that can't upload as someoen else """
 
        data = open(GOOD_JPG, "rb").read()
...
 
@@ -172,7 +214,7 @@ class TestAPI(object):
 
            assert "403 FORBIDDEN" in excinfo.value.args[0]
 

	
 
    def test_only_able_to_update_own_image(self, test_app):
 
        """ Test's that the uploader is the only person who can update an image """
 
        """ Test uploader is the only person who can update an image """
 
        response, data = self._upload_image(test_app, GOOD_JPG)
 
        response, data = self._post_image_to_feed(test_app, data)
 

	
...
 
@@ -186,13 +228,16 @@ class TestAPI(object):
 
        }
 

	
 
        # Lets change the image uploader to be self.other_user, this is easier
 
        # than uploading the image as someone else as the way self.mocked_oauth_required
 
        # and self._upload_image.
 
        media = MediaEntry.query.filter_by(public_id=data["object"]["id"]).first()
 
        # than uploading the image as someone else as the way
 
        # self.mocked_oauth_required and self._upload_image.
 
        media = MediaEntry.query \
 
            .filter_by(public_id=data["object"]["id"]) \
 
            .first()
 
        media.actor = self.other_user.id
 
        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.
 
        with self.mock_oauth():
 
            with pytest.raises(AppError) as excinfo:
 
                test_app.post(
...
 
@@ -242,7 +287,6 @@ class TestAPI(object):
 
        assert image["content"] == description
 
        assert image["license"] == license
 

	
 

	
 
    def test_only_uploaders_post_image(self, test_app):
 
        """ Test that only uploaders can upload images """
 
        # Remove uploader permissions from user
...
 
@@ -288,12 +332,15 @@ class TestAPI(object):
 
        image = json.loads(request.body.decode())
 
        entry = MediaEntry.query.filter_by(public_id=image["id"]).first()
 

	
 
        assert entry is not None
 

	
 
        assert request.status_code == 200
 

	
 
        assert "image" in image
 
        assert "fullImage" in image
 
        assert "pump_io" in image
 
        assert "links" in image
 
        assert "tags" in image
 

	
 
    def test_post_comment(self, test_app):
 
        """ Tests that I can post an comment media """
...
 
@@ -316,7 +363,9 @@ class TestAPI(object):
 
        assert response.status_code == 200
 

	
 
        # Find the objects in the database
 
        media = MediaEntry.query.filter_by(public_id=data["object"]["id"]).first()
 
        media = MediaEntry.query \
 
            .filter_by(public_id=data["object"]["id"]) \
 
            .first()
 
        comment = media.get_comments()[0].comment()
 

	
 
        # Tests that it matches in the database
...
 
@@ -378,7 +427,9 @@ class TestAPI(object):
 
        response, comment_data = self._activity_to_feed(test_app, activity)
 

	
 
        # change who uploaded the comment as it's easier than changing
 
        comment = TextComment.query.filter_by(public_id=comment_data["object"]["id"]).first()
 
        comment = TextComment.query \
 
            .filter_by(public_id=comment_data["object"]["id"]) \
 
            .first()
 
        comment.actor = self.other_user.id
 
        comment.save()
 

	
...
 
@@ -432,7 +483,7 @@ class TestAPI(object):
 
    def test_whoami_without_login(self, test_app):
 
        """ Test that whoami endpoint returns error when not logged in """
 
        with pytest.raises(AppError) as excinfo:
 
            response = test_app.get("/api/whoami")
 
            test_app.get("/api/whoami")
 

	
 
        assert "401 UNAUTHORIZED" in excinfo.value.args[0]
 

	
...
 
@@ -621,8 +672,11 @@ class TestAPI(object):
 
        delete = self._activity_to_feed(test_app, activity)[1]
 

	
 
        # Verify the comment no longer exists
 
        assert TextComment.query.filter_by(public_id=comment["object"]["id"]).first() is None
 
        comment_id = comment["object"]["id"]
 
        assert TextComment.query \
 
            .filter_by(public_id=comment["object"]["id"]) \
 
            .first() is None
 

	
 
        assert "id" in comment["object"]
 

	
 
        # Check we've got a delete activity back
 
        assert "id" in delete
...
 
@@ -662,6 +716,8 @@ class TestAPI(object):
 
        comment = self._activity_to_feed(test_app, activity)[1]
 

	
 
        # Verify the comment reflects the changes
 
        model = TextComment.query.filter_by(public_id=comment["object"]["id"]).first()
 
        model = TextComment.query \
 
            .filter_by(public_id=comment["object"]["id"]) \
 
            .first()
 

	
 
        assert model.content == activity["object"]["content"]
mediagoblin/tests/test_auth.py
Show inline comments
...
 
@@ -101,7 +101,7 @@ def test_register_views(test_app):
 
            'password': 'iamsohappy',
 
            'email': 'easter@egg.com'})
 

	
 
    ## At this point there should on user in the database
 
    ## At this point there should be one user in the database
 
    assert User.query.count() == 1
 

	
 
    # Successful register
mediagoblin/tests/test_celery_setup.py
Show inline comments
...
 
@@ -55,7 +55,4 @@ def test_setup_celery_from_config():
 
        'sqlite:///' +
 
        pkg_resources.resource_filename('mediagoblin.tests', 'celery.db'))
 

	
 
    assert fake_celery_module.BROKER_TRANSPORT == 'sqlalchemy'
 
    assert fake_celery_module.BROKER_URL == (
 
        'sqlite:///' +
 
        pkg_resources.resource_filename('mediagoblin.tests', 'kombu.db'))
 
    assert fake_celery_module.BROKER_URL == 'amqp://'
mediagoblin/tests/test_config.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
#
 
# GNU MediaGoblin -- federated, autonomous media hosting
 
# Copyright (C) 2011, 2012 MediaGoblin contributors.  See AUTHORS.
 
#
...
 
@@ -47,7 +49,7 @@ def test_read_mediagoblin_config():
 
    assert this_conf['carrotapp']['num_carrots'] == 88
 
    assert this_conf['carrotapp']['encouragement_phrase'] == \
 
        "I'd love it if you eat your carrots!"
 
    assert this_conf['carrotapp']['blah_blah'] == "blah!"
 
    assert this_conf['carrotapp']['blah_blah'] == u"blæh!"
 
    assert this_conf['celery']['EAT_CELERY_WITH_CARROTS'] == False
 

	
 
    # A bad file
mediagoblin/themes/airy/assets/css/airy.css
Show inline comments
...
 
@@ -52,6 +52,10 @@ footer {
 
  border-top: 1px solid #E4E4E4;
 
}
 

	
 
table.admin_panel th {
 
  color: #4a4a4a;
 
}
 

	
 
.button_action, .button_action_highlight, .button_form {
 
  color: #4a4a4a;
 
  background-color: #fff;
mediagoblin/tools/licenses.py
Show inline comments
...
 
@@ -21,28 +21,27 @@ License = namedtuple("License", ["abbreviation", "name", "uri"])
 
SORTED_LICENSES = [
 
    License("All rights reserved", "No license specified", ""),
 
    License("CC BY 4.0", "Creative Commons Attribution 4.0 International",
 
           "http://creativecommons.org/licenses/by/4.0/"),
 
    License("CC BY-SA 4.0",
 
           "Creative Commons Attribution-ShareAlike 4.0 International",
 
           "http://creativecommons.org/licenses/by-sa/4.0/"),
 
            "Creative Commons Attribution-ShareAlike 4.0 International",
 
            "https://creativecommons.org/licenses/by-sa/4.0/"),
 
    License("CC BY-ND 4.0",
 
           "Creative Commons Attribution-NoDerivatives 4.0 International",
 
           "http://creativecommons.org/licenses/by-nd/4.0/"),
 
            "Creative Commons Attribution-NoDerivs 4.0 International",
 
            "https://creativecommons.org/licenses/by-nd/4.0/"),
 
    License("CC BY-NC 4.0",
 
          "Creative Commons Attribution-NonCommercial 4.0 International",
 
          "http://creativecommons.org/licenses/by-nc/4.0/"),
 
            "Creative Commons Attribution-NonCommercial 4.0 International",
 
            "https://creativecommons.org/licenses/by-nc/4.0/"),
 
    License("CC BY-NC-SA 4.0",
 
           "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International",
 
           "http://creativecommons.org/licenses/by-nc-sa/4.0/"),
 
            "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International",
 
            "https://creativecommons.org/licenses/by-nc-sa/4.0/"),
 
    License("CC BY-NC-ND 4.0",
 
           "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International",
 
           "http://creativecommons.org/licenses/by-nc-nd/4.0/"),
 
            "Creative Commons Attribution-NonCommercial-NoDerivs 4.0 International",
 
            "https://creativecommons.org/licenses/by-nc-nd/4.0/"),
 
    License("CC0 1.0",
 
           "Creative Commons CC0 1.0 Universal",
 
           "http://creativecommons.org/publicdomain/zero/1.0/"),
 
            "Creative Commons CC0 1.0 Universal",
 
            "https://creativecommons.org/publicdomain/zero/1.0/"),
 
    License("Public Domain","Public Domain",
 
           "http://creativecommons.org/publicdomain/mark/1.0/"),
 
    ]
 
            "https://creativecommons.org/publicdomain/mark/1.0/"),
 
]
 

	
 
# dict {uri: License,...} to enable fast license lookup by uri. Ideally,
 
# we'd want to use an OrderedDict (python 2.7+) here to avoid having the
setup.py
Show inline comments
...
 
@@ -56,8 +56,7 @@ install_requires = [
 
    'pytest>=2.3.1',
 
    'pytest-xdist',
 
    'werkzeug>=0.7',
 
    'celery>=3.0,<4.0a0',
 
    'kombu<4.0a0',
 
    'celery>=3.0',
 
    'jinja2',
 
    'Babel>=1.3',
 
    'WebTest>=2.0.18',
...
 
@@ -75,6 +74,7 @@ install_requires = [
 
    'PasteScript',
 
    'requests>=2.6.0',
 
    'pyld',
 
    'ExifRead>=2.0.0'
 
    # This is optional:
 
    # 'translitcodec',
 
    # For now we're expecting that users will install this from
...
 
@@ -83,10 +83,8 @@ install_requires = [
 
    # 'Pillow',
 
] + pyversion_install_requires
 

	
 
dependency_links = []
 
if not PY2:
 
    # PyPI version (1.4.2) does not have proper Python 3 support
 
    dependency_links.append('https://github.com/ianare/exif-py/zipball/develop#egg=ExifRead-2.0.0')
 
    install_requires.append('ExifRead>=2.0.0')
 

	
 
with open(READMEFILE, encoding="utf-8") as fobj:
...
 
@@ -101,7 +99,6 @@ try:
 
    include_package_data = True,
 
    # scripts and dependencies
 
    install_requires=install_requires,
 
    dependency_links=dependency_links,
 
    test_suite='nose.collector',
 
    entry_points="""\
 
        [console_scripts]
0 comments (0 inline, 0 general)