aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/devel
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/devel')
-rw-r--r--docs/source/devel/codebase.rst148
-rw-r--r--docs/source/devel/migrations.rst62
-rw-r--r--docs/source/devel/storage.rst94
3 files changed, 226 insertions, 78 deletions
diff --git a/docs/source/devel/codebase.rst b/docs/source/devel/codebase.rst
index 5e8cbcc6..122a3297 100644
--- a/docs/source/devel/codebase.rst
+++ b/docs/source/devel/codebase.rst
@@ -34,78 +34,11 @@ various recipes for getting things done.
for where we hang out.
For more information on how to get started hacking on GNU MediaGoblin,
-see `the wiki <http://wiki.mediagoblin.org/>`_.
-
-
-Software Stack
-==============
-
-* Project infrastructure
-
- * `Python <http://python.org/>`_: the language we're using to write
- this
-
- * `Nose <http://somethingaboutorange.com/mrl/projects/nose/>`_:
- for unit tests
-
- * `virtualenv <http://www.virtualenv.org/>`_: for setting up an
- isolated environment to keep mediagoblin and related packages
- (potentially not required if MediaGoblin is packaged for your
- distro)
-
-* Data storage
-
- * `SQLAlchemy <http://sqlalchemy.org/>`_: SQL ORM and database
- interaction library for Python. Currently we support sqlite and
- postgress as backends.
-
-* Web application
-
- * `Paste Deploy <http://pythonpaste.org/deploy/>`_ and
- `Paste Script <http://pythonpaste.org/script/>`_: we'll use this for
- configuring and launching the application
-
- * `werkzeug <http://werkzeug.pocoo.org/>`_: nice abstraction layer
- from HTTP requests, responses and WSGI bits
-
- * `Beaker <http://beaker.groovie.org/>`_: for handling sessions and
- caching
-
- * `Jinja2 <http://jinja.pocoo.org/docs/>`_: the templating engine
-
- * `WTForms <http://wtforms.simplecodes.com/>`_: for handling,
- validation, and abstraction from HTML forms
-
- * `Celery <http://celeryproject.org/>`_: for task queuing (resizing
- images, encoding video, ...)
-
- * `Babel <http://babel.edgewall.org>`_: Used to extract and compile
- translations.
-
- * `Markdown (for python) <http://pypi.python.org/pypi/Markdown>`_:
- implementation of `Markdown <http://daringfireball.net/projects/markdown/>`_
- text-to-html tool to make it easy for people to write richtext
- comments, descriptions, and etc.
-
- * `lxml <http://lxml.de/>`_: nice xml and html processing for
- python.
-
-* Media processing libraries
-
- * `Python Imaging Library <http://www.pythonware.com/products/pil/>`_:
- used to resize and otherwise convert images for display.
-
- * `GStreamer <http://gstreamer.freedesktop.org/>`_: (Optional, for
- video hosting sites only) Used to transcode video, and in the
- future, probably audio too.
-
- * `chardet <http://pypi.python.org/pypi/chardet>`_: (Optional, for
- ascii art hosting sites only) Used to make ascii art thumbnails.
-
-* Front end
-
- * `JQuery <http://jquery.com/>`_: for groovy JavaScript things
-
+see `the wiki <http://wiki.mediagoblin.org/>`_, and specifically, go
+through the
+`Hacking HOWTO <http://wiki.mediagoblin.org/HackingHowto>`_
+which explains generally how to get going with running an instance for
+development.
What's where
@@ -177,3 +110,74 @@ including the following:
:migrations.py: When creating a new migration (a change to the
database structure), we put it here
+
+Software Stack
+==============
+
+* Project infrastructure
+
+ * `Python <http://python.org/>`_: the language we're using to write
+ this
+
+ * `Py.Test <http://pytest.org/>`_:
+ for unit tests
+
+ * `virtualenv <http://www.virtualenv.org/>`_: for setting up an
+ isolated environment to keep mediagoblin and related packages
+ (potentially not required if MediaGoblin is packaged for your
+ distro)
+
+* Data storage
+
+ * `SQLAlchemy <http://sqlalchemy.org/>`_: SQL ORM and database
+ interaction library for Python. Currently we support sqlite and
+ postgress as backends.
+
+* Web application
+
+ * `Paste Deploy <http://pythonpaste.org/deploy/>`_ and
+ `Paste Script <http://pythonpaste.org/script/>`_: we'll use this for
+ configuring and launching the application
+
+ * `werkzeug <http://werkzeug.pocoo.org/>`_: nice abstraction layer
+ from HTTP requests, responses and WSGI bits
+
+ * `itsdangerous <http://pythonhosted.org/itsdangerous/>`_:
+ for handling sessions
+
+ * `Jinja2 <http://jinja.pocoo.org/docs/>`_: the templating engine
+
+ * `WTForms <http://wtforms.simplecodes.com/>`_: for handling,
+ validation, and abstraction from HTML forms
+
+ * `Celery <http://celeryproject.org/>`_: for task queuing (resizing
+ images, encoding video, ...)
+
+ * `Babel <http://babel.edgewall.org>`_: Used to extract and compile
+ translations.
+
+ * `Markdown (for python) <http://pypi.python.org/pypi/Markdown>`_:
+ implementation of `Markdown <http://daringfireball.net/projects/markdown/>`_
+ text-to-html tool to make it easy for people to write richtext
+ comments, descriptions, and etc.
+
+ * `lxml <http://lxml.de/>`_: nice xml and html processing for
+ python.
+
+* Media processing libraries
+
+ * `Python Imaging Library <http://www.pythonware.com/products/pil/>`_:
+ used to resize and otherwise convert images for display.
+
+ * `GStreamer <http://gstreamer.freedesktop.org/>`_: (Optional, for
+ video hosting sites only) Used to transcode video, and in the
+ future, probably audio too.
+
+ * `chardet <http://pypi.python.org/pypi/chardet>`_: (Optional, for
+ ascii art hosting sites only) Used to make ascii art thumbnails.
+
+* Front end
+
+ * `JQuery <http://jquery.com/>`_: for groovy JavaScript things
+
+
diff --git a/docs/source/devel/migrations.rst b/docs/source/devel/migrations.rst
new file mode 100644
index 00000000..16c02b04
--- /dev/null
+++ b/docs/source/devel/migrations.rst
@@ -0,0 +1,62 @@
+.. MediaGoblin Documentation
+
+ Written in 2011, 2012 by MediaGoblin contributors
+
+ To the extent possible under law, the author(s) have dedicated all
+ copyright and related and neighboring rights to this software to
+ the public domain worldwide. This software is distributed without
+ any warranty.
+
+ You should have received a copy of the CC0 Public Domain
+ Dedication along with this software. If not, see
+ <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+==========
+Migrations
+==========
+
+So, about migrations. Every time we change the way the database
+structure works, we need to add a migration so that people running
+older codebases can have their databases updated to the new structure
+when they run `./bin/gmg dbupdate`.
+
+The first time `./bin/gmg dbupdate` is run by a user, it creates the
+tables at the current state that they're defined in models.py and sets
+the migration number to the current migration... after all, migrations
+only exist to get things to the current state of the db. After that,
+every migration is run with dbupdate.
+
+There's a few things you need to know:
+
+- We use `sqlalchemy-migrate
+ <http://code.google.com/p/sqlalchemy-migrate/>`_.
+ See `their docs <https://sqlalchemy-migrate.readthedocs.org/>`_.
+- `Alembic <https://bitbucket.org/zzzeek/alembic>`_ might be a better
+ choice than sqlalchemy-migrate now or in the future, but we
+ originally decided not to use it because it didn't have sqlite
+ support. It's not clear if that's changed.
+- SQLAlchemy has two parts to it, the ORM and the "core" interface.
+ We DO NOT use the ORM when running migrations. Think about it: the
+ ORM is set up with an expectation that the models already reflect a
+ certain pattern. But if a person is moving from their old patern
+ and are running tools to *get to* the current pattern, of course
+ their current database structure doesn't match the state of the ORM!
+- How to write migrations? Maybe there will be a tutorial here in the
+ future... in the meanwhile, look at existing migrations in
+ `mediagoblin/db/migrations.py` and look in
+ `mediagoblin/tests/test_sql_migrations.py` for examples.
+- Common pattern: use `inspect_table` to get the current state
+ of the table before we run alterations on it.
+- Make sure you set the RegisterMigration to be the next migration in
+ order.
+- What happens if you're adding a *totally new* table? In this case,
+ you should copy the table in entirety as it exists into
+ migrations.py then create the tables based off of that... see
+ add_collection_tables. This is easier than reproducing the SQL by
+ hand.
+- If you're writing a feature branch, you don't need to keep adding
+ migrations every time you change things around if your database
+ structure is in flux. Just alter your migrations so that they're
+ correct for the merge into master.
+
+That's it for now! Good luck!
diff --git a/docs/source/devel/storage.rst b/docs/source/devel/storage.rst
index 52406c4e..215f9579 100644
--- a/docs/source/devel/storage.rst
+++ b/docs/source/devel/storage.rst
@@ -2,18 +2,28 @@
Storage
=========
-
-See for now: http://wiki.mediagoblin.org/Storage
-
-Things get moved here.
-
-
The storage systems attached to your app
----------------------------------------
Dynamic content: queue_store and public_store
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Two instances of the StorageInterface come attached to your app. These
+are:
+
++ **queue_store:** When a user submits a fresh piece of media for
+ their gallery, before the Processing stage, that piece of media sits
+ here in the queue_store. (It's possible that we'll rename this to
+ "private_store" and start storing more non-publicly-stored stuff in
+ the future...). This is a StorageInterface implementation
+ instance. Visitors to your site probably cannot see it... it isn't
+ designed to be seen, anyway.
+
++ **public_store:** After your media goes through processing it gets
+ moved to the public store. This is also a StorageInterface
+ implelementation, and is for stuff that's intended to be seen by
+ site visitors.
+
The workbench
~~~~~~~~~~~~~
@@ -32,6 +42,28 @@ See the workbench module documentation for more.
Static assets / staticdirect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+On top of all that, there is some static media that comes bundled with your
+application. This stuff is kept in:
+
+ mediagoblin/static/
+
+These files are for mediagoblin base assets. Things like the CSS files,
+logos, etc. You can mount these at whatever location is appropriate to you
+(see the direct_remote_path option in the config file) so if your users
+are keeping their static assets at http://static.mgoblin.example.org/ but
+their actual site is at http://mgoblin.example.org/, you need to be able
+to get your static files in a where-it's-mounted agnostic way. There's a
+"staticdirector" attached to the request object. It's pretty easy to use;
+just look at this bit taken from the
+mediagoblin/templates/mediagoblin/base.html main template:
+
+ <link rel="stylesheet" type="text/css"
+ href="Template:Request.staticdirect('/css/extlib/text.css')"/>
+
+see? Not too hard. As expected, if you configured direct_remote_path to be
+http://static.mgoblin.example.org/ you'll get back
+http://static.mgoblin.example.org/css/extlib/text.css just as you'd
+probably expect.
StorageInterface and implementations
------------------------------------
@@ -39,5 +71,55 @@ StorageInterface and implementations
The guts of StorageInterface and friends
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+So, the StorageInterface!
+
+So, the public and queue stores both use StorageInterface implementations
+... but what does that mean? It's not too hard.
+
+Open up:
+
+ mediagoblin/storage.py
+
+In here you'll see a couple of things. First of all, there's the
+StorageInterface class. What you'll see is that this is just a very simple
+python class. A few of the methods actually implement things, but for the
+most part, they don't. What really matters about this class is the
+docstrings. Each expected method is documented as to how it should be
+constructed. Want to make a new StorageInterface? Simply subclass it. Want
+to know how to use the methods of your storage system? Read these docs,
+they span all implementations.
+
+There are a couple of implementations of these classes bundled in
+storage.py as well. The most simple of these is BasicFileStorage, which is
+also the default storage system used. As expected, this stores files
+locally on your machine.
+
+There's also a CloudFileStorage system. This provides a mapping to
+[OpenStack's swift http://swift.openstack.org/] storage system (used by
+RackSpace Cloud files and etc).
+
+Between these two examples you should be able to get a pretty good idea of
+how to write your own storage systems, for storing data across your
+beowulf cluster of radioactive monkey brains, whatever.
+
Writing code to store stuff
~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+So what does coding for StorageInterface implementations actually look
+like? It's pretty simple, really. For one thing, the design is fairly
+inspired by [Django's file storage API
+https://docs.djangoproject.com/en/dev/ref/files/storage/]... with some
+differences.
+
+Basically, you access files on "file paths", which aren't exactly like
+unix file paths, but are close. If you wanted to store a file on a path
+like dir1/dir2/filename.jpg you'd actually write that file path like:
+
+['dir1', 'dir2', 'filename.jpg']
+
+This way we can be *sure* that each component is actually a component of
+the path that's expected... we do some filename cleaning on each component.
+
+Your StorageInterface should pass in and out "file like objects". In other
+words, they should provide .read() and .write() at minimum, and probably
+also .seek() and .close().