From b07336c562d537ea3407d6a1c9fcb280dae7f514 Mon Sep 17 00:00:00 2001 From: Eevee Date: Fri, 4 Dec 2009 18:46:38 -0800 Subject: [PATCH 1/1] Rearranged user/art relations. Got rid of the base class monkey-patching. That's frightening. Added some accessors to Art to get lists of certain types of relationed users. Removed the user-list field from the upload page; for now, we assume the uploader is also the artist. --- floof/controllers/art.py | 41 +++++------------------------------------ floof/model/art.py | 36 ++++++++++++++++++++++++++++++------ floof/model/relations.py | 34 ---------------------------------- floof/public/layout.css | 1 + floof/templates/art/new.mako | 9 +-------- floof/templates/art/show.mako | 8 ++++++-- 6 files changed, 43 insertions(+), 86 deletions(-) delete mode 100644 floof/model/relations.py diff --git a/floof/controllers/art.py b/floof/controllers/art.py index 5b347b3..ee1e4ad 100644 --- a/floof/controllers/art.py +++ b/floof/controllers/art.py @@ -8,8 +8,8 @@ from floof.lib.base import BaseController, render log = logging.getLogger(__name__) from floof.lib import file_storage as storage -from floof.model.users import User -from floof.model import Art, Rating, UserRelation +from floof.model import Art, Rating, ArtUser +from floof.model.art import ArtUserType from floof.model.comments import Discussion from floof.model.users import User, UserRelationship @@ -35,38 +35,6 @@ class ArtUploadForm(Form): if field.data == u'': raise ValidationError('File is required') - # Also make this into a general User List field validator - """ PLEASE NOTE! I just realized that I need to have a __str__ method on User - to get it to write the usernames back in the form when it redisplays them, since - this validator turns them into user objects instead. This fact actually sounds dangerous - to me in the future, since it means I proably shouldn't be changing the data input - by the user right here in the validator, or the user will see the post-mangled data instead - of what they actually typed. Hm. - - One solution to this could be to only look up the users after normal validation is over, - and then manually add validation errors to the form if that fails. But I think that kind of - sucks. Perhaps the ideology in Formish, where they keep Validation and Conversion as - separate tasks, is a better way of doing it? That way there is less risk of changing the user's - input -- you do that at the conversiot stage -- yet it is still encapsulated in the form workflow. - Hm. But that means I'd have to query for the users in the validation step and throw them away, - or something equally stupid. Guess there's no perfect solution here, but I thought it was - worth discussing. - - Btw, this is meant to be used by a field with multi user autocompletion on it (like on stackoverflow tags), - so the user should never actually submit anything invalid unless they disable javascript and force it. - """ - def validate_by(self, field): - if not field.data: - raise ValidationError("Needs at least one creator") - user_names = field.data.split() - users = [] - # TODO: Could totally do a filter__in here instead of picking them out individually - for user_name in user_names: - user = User.get_by(name=user_name) - if not user: - raise ValidationError("Couldn't find user %s" % user_name) - users.append(user) - field.data = users class ArtController(BaseController): def __before__(self, id=None): @@ -127,8 +95,9 @@ class ArtController(BaseController): ) c.art.discussion = Discussion(count=0) - for artist in c.form.by.data: - UserRelation(user=artist, kind="by", creator=c.user, art=c.art) + # For the moment, cheerfully assume that people are uploading their own + # art + ArtUser(art=c.art, user=c.user, type=ArtUserType.BY) try: diff --git a/floof/model/art.py b/floof/model/art.py index 8989e8f..ea6d6ee 100644 --- a/floof/model/art.py +++ b/floof/model/art.py @@ -4,7 +4,6 @@ # Copyright (c) 2009 Scribblr # -# from elixir import Entity, Field, Integer, Unicode from elixir import * import elixir @@ -12,12 +11,9 @@ from pylons import config from floof.lib.file_storage import get_path, save_file from floof.lib.dbhelpers import find_or_create, update_or_create -import floof.model.comments +from floof.model.users import User -# Note: Art is the most important class. To keep its size down, and to better organize the source code, -# other modules will mix into it automatically by adding to its __bases__. - class Art(Entity): title = Field(Unicode(120)) original_filename = Field(Unicode(120)) @@ -28,8 +24,36 @@ class Art(Entity): tags = OneToMany('Tag') discussion = ManyToOne('Discussion') - user_relations = OneToMany('UserRelation') + art_users = OneToMany('ArtUser') @property def file_path(self): return get_path("art", self.hash) + + # Associated users + # XXX ok these could stand to do the filtering sql-side + @property + def artists(self): + return (au.user for au in self.art_users if au.type == ArtUserType.BY) + + @property + def recipients(self): + return (au.user for au in self.art_users if au.type == ArtUserType.FOR) + + @property + def participants(self): + return (au.user for au in self.art_users if au.type == ArtUserType.OF) + + +class ArtUserType(object): + BY = 1 + FOR = 2 + OF = 3 + +class ArtUser(Entity): + art = ManyToOne('Art', required=True) + user = ManyToOne('User', required=True) + type = Field(Integer, required=True) # ArtUserType + + # TODO: admin log ought to remember who confirmed the relation. + # (tag history will remember who proposed it) diff --git a/floof/model/relations.py b/floof/model/relations.py deleted file mode 100644 index a6fe020..0000000 --- a/floof/model/relations.py +++ /dev/null @@ -1,34 +0,0 @@ -from elixir import * -from art import Art - - -class UserRelation(Entity): - user = ManyToOne("User") - art = ManyToOne("Art") - kind = Field(String) # by for of - creator = ManyToOne("User") - confirmed_by_related_user = Field(Boolean) - - # it is useful to record which authority figure on a given artwork - # confirmed the validity of this relation. - confirmed_by_authority = ManyToOne("User") - - def __init__(self, **kwargs): - super(UserRelation, self).__init__(**kwargs) - assert self.user and self.art and self.kind and self.creator - - if self.creator == self.user: - self.confirmed_by_related_user = True - # TODO: implement authorities - # if self.creator in self.art.authorities - # self.confirmed_by_authority = self.creator - - def __unicode__(self): - return "%s: %s" % (self.kind, self.related_user) - - -class RelationMixin(object): - def add_relation(creator, kind, user): - return UserRelation(art=self, creator=creator, kind=kind, user=user) - -Art.__bases__ += (RelationMixin,) diff --git a/floof/public/layout.css b/floof/public/layout.css index bc7056e..7a7308b 100644 --- a/floof/public/layout.css +++ b/floof/public/layout.css @@ -16,6 +16,7 @@ body { font-family: sans-serif; font-size: 12px; } /*** Common bits and pieces ***/ h1 { margin: 0.5em 0 0.25em; font-size: 2em; border-bottom: 1px solid #404040; text-shadow: #a0a0a0 1px 1px 1px; } +h2 { margin: 0.5em 0 0.25em; font-size: 1.5em; border-bottom: 1px dotted #606060; text-shadow: #a0a0a0 1px 1px 1px; } a { color: #647cc4; font-weight: bold; text-decoration: none; pointer: cursor; } a:visited { color: #48598e; } diff --git a/floof/templates/art/new.mako b/floof/templates/art/new.mako index 4204700..2b18b42 100644 --- a/floof/templates/art/new.mako +++ b/floof/templates/art/new.mako @@ -1,18 +1,11 @@ <%inherit file="/base.mako" />

Add New Art

-

Now: Upload a file. Later: Supply a link? Not exclusive to uploading.

- -## Todo: write some macros to make outputting form fields easier. - ${h.form(h.url('create_art'), multipart=True)} -${normal_field(c.form.by)} +## Todo: write some macros to make outputting form fields easier. ${normal_field(c.form.file)} - -##Artist: ${h.text('artist')} -##${h.file('file')} ${h.submit(None, 'Upload!')} ${h.end_form()} diff --git a/floof/templates/art/show.mako b/floof/templates/art/show.mako index a38806d..bf14dff 100644 --- a/floof/templates/art/show.mako +++ b/floof/templates/art/show.mako @@ -34,8 +34,12 @@ ${h.end_form()}

Relations

-- 2.7.4