600 Commits

Author SHA1 Message Date
Elrond
139c6c099f Drop media_data_table property.
Only when creating a new media_data row, we need the table.
So load that locally in media_data_init().
2013-02-01 22:02:35 +01:00
Elrond
57f8d263e1 Rewrite media_data handling to use relationships
Instead of doing query by hand, use the relationships on
the models to find the media_data. Is is made possible by
the BACKREF_NAME in each models.py, which lets us know the
local attr to ask for.

Also initialize the relationship attribute on new
media_data instead of the media_id. Also do not add it to
the session. This gives us:
- This automatically initializes the other side of the
  relationship, which will allow later acces via that way.
- If the media_data is too early in the session, when the
  (new) media_entry is not yet in there, this could get
  conflicts. Avoid those by not adding to session.
- Uses cascading to commit media_data together with the
  media_entry.
2013-02-01 22:02:35 +01:00
Elrond
ff68ca9fc2 Fix issue 611: Proper (back)relationship on MediaComment.
well, fix the relationship on the comments.
2013-01-29 21:23:21 +01:00
Christopher Allan Webber
c7d135b6ea Merge branch '216_cwebber_style_unique_slugs' 2013-01-25 12:03:40 -06:00
Christopher Allan Webber
a81082fcaf New mediaentry slug tests now pass!
- fixed some issues with "whacking uuid junk on the slug"
 - uuid4() -> uuid.uuid4() so that mock will work right
 - added all the tests!
2013-01-23 16:49:54 -06:00
Christopher Allan Webber
b0118957ff We don't want any empty string slugs, so make "" -> None 2013-01-23 16:40:39 -06:00
Christopher Allan Webber
266b42b3dc Switching uuid4()[1:4] -> uuid4().hex[:4]
.hex is what we need to access to get at the ascii (hex) version
anyway.  Also, not sure why the previous version grabbed starting at
the index of 1... just grab the first characters instead.
2013-01-23 15:15:22 -06:00
Elrond
6194344bf9 Use better relationships to delete collections.
When deleting a User, his/her collections can be deleted by
sqlalchemy: Collections do not need any special code to be
executed on deletion.
2013-01-23 17:36:03 +01:00
Elrond
0c871f8122 Use inspect_table; default user license==None.
Use inspect_table in the new migration. Makes code more
readable, really.

And make the default for the preferred license be None.
This is a userspace thing, so we can even change the
migration here. Changing the migration means, that people
running the migration before this commit get a "" in
User.license_preference, while people running the migration
now get a None. Both values are okay.

None has been designated as "Use the site's default". We're
not actually having a site default right now. Which means
no license is selected in the dropdown.

While "" means "All rights reserved" being chosen by the
user.

Side note: Having no license being selected in the submit
dropdown is as "worse" as before and does not really hurt
much. MediaEntry.license==None means "All rights reserved"
as does "" also do.
2013-01-22 23:10:30 +01:00
Christopher Allan Webber
79f7cfd900 Merge remote-tracking branch 'refs/remotes/spaetz/521_license_preference' into mergetest 2013-01-22 13:43:02 -06:00
Elrond
afbfd40578 Enable foreign key checking on sqlite.
sqlite normally does not check foreign key referential
integrity. But it can do so.
So let's use it. Better safe than sorry.
2013-01-18 18:42:52 +01:00
Mark Holmquist
dc4dfbde35 Add a license preference field
This feature is absolutely necessary. Now a user can simply define
their default license and quickly go through a form, as opposed to
stopping to click on the select and choosing the same option over
and over again.

Also added DB migration for the field, so that's working now, too.

Rebased by Sebastian and made the default value to be unicode.

Reviewed-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-17 21:34:04 +01:00
Sebastian Spaeth
3809a8b8e2 import db.sql.util -> db.util
Merging an old branch, I reintroduced an import of db.sql.util rather than
db.util. Fixing the glitch.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-17 12:19:33 +01:00
Sebastian Spaeth
03b4fc500c Implement User.delete() (#540)
Set User.collections to her Collections using the backref feature.
This way we can iterate a user's collections and delete them all.

Delete all MediaEntries/Files/attachments/comments/collections etc
before finally deleting the User object. This is the backend work for
issue 302 (allow a user to delete ones own account)
2013-01-17 11:48:49 +01:00
Sebastian Spaeth
242776e363 Implement Collection.delete()
Deleting a Collection should automatically delete all containing items.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-17 11:48:49 +01:00
Sebastian Spaeth
fdc34b8ba7 Implement MediaEntry().delete() (#540)
Deleting a MediaEntry instance will automatically
delete all related comments and files/attachments. This moves
implementation logic out of views.py and allows to make use of this
functionality when e.g. deleting a User() account.

Whenever a MediaEntry entry is deleted, this will also sql-delete
the corresponding MediaFile entry.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-17 11:48:07 +01:00
Christopher Allan Webber
985871095e Simplifying string concatenation in generate_slug and fixing docstring
- made the mistake of copying some commit message things into the
   docstring.  Fixed.
 - elrond points out that += is nicer and we don't need u"" in this
   case since we're not concatenating a variable, we're concatenating
   a known ascii string.
2013-01-15 16:11:15 -06:00
Christopher Allan Webber
88de830fcf A revised algorithm for generating slugs.
This one does not *force* slugs, but usually it will probably result
in a niceish one.

The end *result* of the algorithm will (presumably, I have not tested
it) result in these resolutions for these situations:
 - If we have a slug, make sure it's clean and sanitized, and if it's
   unique, we'll use that.
 - If we have a title, slugify it, and if it's unique, we'll use that.
 - If we can't get any sort of thing that looks like it'll be a useful
   slug out of a title or an existing slug, bail, and don't set the
   slug at all.  Don't try to create something just because.  Make
   sure we have a reasonable basis for a slug first.
 - If we have a reasonable basis for a slug (either based on existing
   slug or slugified title) but it's not unique, first try appending
   the entry's id, if that exists
 - If that doesn't result in something unique, tack on some randomly
   generated bits until it's unique.  That'll be a little bit of junk,
   but at least it has the *basis* of a nice slug!
2013-01-15 15:48:19 -06:00
Christopher Allan Webber
72bb46c7c8 Need to import uuid4 for generate_slug to totally work 2013-01-15 14:34:13 -06:00
Sebastian Spaeth
66d9f1b2a0 Make generate_slug assign a slug in any case
generate_slug could assign "none" as slug. Make sure it assigns a unique
slug in any case. We now try based on:

a) existing slug values
b) media.title
c) media.id
d) random garbage

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-15 20:08:21 +01:00
Sebastian Spaeth
65969d3fb7 Simplify check_media_slug_used
Remove the unused dummy_db argument and generally make the function
readable.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-15 14:49:50 +01:00
Elrond
c130e3ee79 Move db.sql.migration_tools to db.migration_tools.
Follow the new trend.
2013-01-08 22:50:01 +01:00
Elrond
c4466cb4dc Add inspect_table.
In our current scheme of migrations, we reflect the current
sql schema into an SQLAlchemy schema. So let's have a tool
function for this.
2013-01-08 22:50:01 +01:00
Elrond
a050e776c6 Move all the migration tools into new migration_tools.py
Factor all the migration related stuff out into a new
.db.sql.migration_tools.
First we don't have to load this module for our normal
server.
Second it makes all the import dependencies a little more
cleaner.
2013-01-08 22:50:01 +01:00
Sebastian Spaeth
20be9bb77d Remove custom GMQuery class
We provided a custom GMQuery class that offered a .sort() method for
compatibility with the Mongo syntax. Now that we have settled for sqlalchemy
which uses the order_by() method, we can safely remove this custom class
and move a little closer to "pure" and native sqlalchemy usage.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-07 13:52:37 +01:00
Sebastian Spaeth
39dc3bf8db Mv db.sql.base to db.base
This concludes the db.sql.* -> db.* move. Our db abstraction layer is
sqlalchemy, so there is no need to a separate db.sql.* hierarchy.

All tests have been run for each of the commit series to make sure
everything works at every step.
2013-01-07 13:42:32 +01:00
Sebastian Spaeth
a5acfe23fa Move mediagoblin.db.sql.extratypes to mediagoblin.db.extratypes
No other functional changes.
2013-01-07 13:10:02 +01:00
Sebastian Spaeth
b0c8328e54 Move db.sql.models* to db.models* 2013-01-07 11:44:29 +01:00
Sebastian Spaeth
1e46dc2537 Move db.sql.util to db.util
Now that sqlalchemy is providing the database abstractions, there is no
need to hide everything in db.sql. sub-modules. It complicates the code
and provides a futher layer of indirection.

Move the db.sql.util.py to db.util.py and adapt the importers.
2013-01-07 11:31:56 +01:00
Sebastian Spaeth
0efe9e2796 Remove mediagoblin.db.sql.fake.DESCENDING
This is the last remnant that requires us to keep db.sql.fake.py. Use
ModelName.desc() or sqlalchemy.sql.expression.desc(column) to achieve
descending sorts.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2013-01-07 11:15:04 +01:00
Sebastian Spaeth
71717fd531 Remove ObjectId from the tree
This was one of the last remaining Mongo holdouts and has been removed from
the tree herewith. Good bye, ObjectId.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-25 20:52:25 +01:00
Sebastian Spaeth
7c029a1f33 Remove InvalidId
It was a NoOp in our Non-mongo world. So it is safe to remove.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-25 20:28:19 +01:00
Sebastian Spaeth
9536988425 Move db.sql.migrations to db.migrations 2012-12-25 20:12:16 +01:00
Sebastian Spaeth
6eddc3b75e Move db.sql.open to db.open
Now that mongo has been ripped out and sqlalchemy is already providing
the database abstraction, there is no need to hide everything in the sql
module. Transition db.sql.open to db.open and adapt all direct importers.
2012-12-25 20:09:43 +01:00
Sebastian Spaeth
bc142abc55 RIP out mongo
Since sqlalchemy is providing our database abstraction and we have
moved away from Mongo as the underlying database, it is now time to
simplify things and rip out mongo. This provides the bulk of the
changes, and can stand on its own. There are some followup tasks
that can be done, such as removing now unneeded abstraction layers,
e.g. db.sql.fake.py
2012-12-25 20:06:03 +01:00
Elrond
b39d1f2351 Mongo removal: Remove the validate=True arg to obj.save()
all callers were forced to use validate=True anyway. So
remove this useless stuff.
2012-12-24 00:07:24 +01:00
Sebastian Spaeth
10f1f2f56b Remove Mongoism query.skip()
sqlalchemy supports slice() or [n:m] just fine.

Right now, it seems we cannot distinguish beween "empty" results
and out-of bound slices. It would be nice if we could distinguish
these somehow.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-21 11:30:29 +01:00
Sebastian Spaeth
30bb4109bc Remove SimpleFieldAlias
It was only used for the model._id -> model.id conversion and is not
needed anymore.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-21 00:30:48 +01:00
Sebastian Spaeth
5c2b84869f Move DBModel._id -> DBModel.id
We were refering to model._id in most of the code base as this is
what Mongo uses. However, each use of _id required a) fixup of queries:
e.g. what we did in our find() and find_one() functions moving all
'_id' to 'id'. It also required using AliasFields to make the ._id
attribute available. This all means lots of superfluous fixing and
transitioning in a SQL world.

It will also not work in the long run. Much newer code already refers
to the objects by model.id (e.g. in the oauth plugin), which will break
with Mongo. So let's be honest, rip out the _id mongoism and live with
.id as the one canonical way to address objects.

This commit modifies all users and providers of model._id to use
model.id instead. This patch works with or without Mongo removed first,
but will break Mongo usage (even more than before)

I have not bothered to fixup db.mongo.* and db.sql.convert
(which converts from Mongo to SQL)

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-21 00:30:48 +01:00
Christopher Allan Webber
78fd5581a9 Remove print statments from this migration.
The reason for wanting to give extra information to the user (this is
a very special case migration) is good, but we don't have a nice
"official" way to capture and present that information during tests,
so removing this.
2012-12-10 16:17:24 -06:00
Elrond
a64abbb10a Fix typo, disable debugging. 2012-12-10 16:17:24 -06:00
Elrond
ea91c183ff UniqueConstraing migration: Adding the explaining comments.
Add a lengthy comment explaining all the variants.
2012-12-10 16:17:24 -06:00
Elrond
0f14c362c3 Fixing our broken CollectionItem unique constraint.
This one seems to work nicely in all relevant situations.
See comments inside the source.
2012-12-10 16:17:24 -06:00
Nathan Yergler
afe0afdb88 Ensure query_dict is a dict after the contents have been modified.
_fix_query_dict modifies its argument in place. Ensure that the
argument passed in has a local name and will be passed into the
subsequent filter_by call.
2012-12-10 12:30:04 +01:00
Christopher Allan Webber
41fc4698c5 Eeek! Set the migration number to the current migration number being run! 2012-12-09 12:20:06 -06:00
Christopher Allan Webber
a4eef7fe91 Elrond's suggestion: have set_current_migration execute after each migration run. 2012-12-09 12:12:07 -06:00
Sebastian Spaeth
5f8b4ae895 make media_manager a property of MediaEntry in mixin.py
In all cases where get_media_manager(_media_type_as_string) was called in
our code base we ultimately passed in a "MediaEntry().media_type" to get
the matching MEDIA_MANAGER. It so makes sense to make this a function of
the MediaEntry rather than a global function in mediagoblin.media_types and
passing around media_entry.media_type as arguments all the time.

It saves a few import statements and arguments. I also made it so the
Media_manager property is cached for subsequent calls, although I am not too
sure that this is needed (there are other cases for which this would make
more sense)

Also add a get_media_manager test to the media submission tests. It submits
an image and checks that both media.media_type and media.media_manager
return the right thing. Not sure if these tests could not be merged with an
existing submission test, but it can't hurt to have things explicit.

TODO: Right now we iterate through all existing media_managers to find the
right one based on the string of its module name. This should be made a simple
dict lookup to avoid all the extra work.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-12-04 15:15:41 +01:00
Sebastian Spaeth
138a18fd6e Implement licenses.get_license_by_url
Rather than exploding in the user's face (for example if we custom-configure
licenses in our MG instance, and there are still media with now "unknown"
licenses in the db), simply return a License object as a fallback, where all
attributes are set to the URL we were handed.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-11-30 14:31:43 +01:00
Sebastian Spaeth
df1c497609 Use mediagoblin import machinery
Rather than manually __importing__ the MEDIA_MANAGER, we should have
been using tools.common.import_component in the first place.

But even better to use the existing get_media_manager() function that
exists for exactly our purpose. Also improve documentation of what happens
in case of failure.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-11-30 14:25:26 +01:00
Sebastian Spaeth
27886480ab Remove importlib (python2.7'ism)
importlib is cool, but only included in python2.7 which is beyond our
minimum python version that we support. So simply use plain old
__import__.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
2012-11-30 11:25:50 +01:00