sub.connect('create_art', '/art/create', action="create")
sub.connect('rate_art', '/art/{id}/rate', action="rate")
sub.connect('show_art', '/art/{id}', action="show")
-
+
with map.submapper(controller='tag') as sub:
sub.connect('delete_tag', '/art/{art_id}/tag/{id}')
sub.connect('create_tag', '/art/{art_id}/tag')
parent_resource=dict(member_name='art', collection_name='art'))
# Yeah, parent resources are specified kinda dumb-ly. Would be better if you could pass in the
# real parent resource instead of mocking it up with a silly dict. We should file a feature request.
-
+
# I think resources is the right way to go for most things. It ensures all of our actions have the right
# methods on them, at least. It does require the use of silly _method="delete" post parameters though.
-
+
# One sticking point though is, it'll happily allow you to add any formatting string you want, like art/1.json
# I wonder if there's a way to place requirements on that, or disable it until we actually have formats.
# It just serves the same action as usual but with a format argument in the context.
-
+
# map.connect('/art/new', controller='art', action='new')
# map.connect('/art/upload', controller='art', action='upload')
# map.connect('show_art', '/art/{id}', controller='art', action='show')
if c.user:
c.your_score = c.art.user_score(c.user)
return render("/art/show.mako")
-
+
# TODO: login required
def rate(self, id):
score = int(score)
else:
score = Rating.reverse_options.get(score)
-
+
c.art.rate(score, c.user)
elixir.session.commit()
-
+
redirect(url('show_art', id=c.art.id))
def index(self):
if request.params.get('button') == 'Save':
return self.save()
-
+
c.query = request.params.get('query', '')
c.artwork = do_search(c.query)
return render('/index.mako')
-
+
# TODO: login required
def save(self):
c.query = request.params.get('query', '')
elixir.session.commit()
redirect(url('saved_searches'))
# TODO: do something better than this.
-
-
+
+
# TODO: login required
def list(self):
c.searches = c.user.searches
return render('/searches.mako')
-
+
# TODO: login required
def display(self, id):
c.search = h.get_object_or_404(SavedSearch, id=id)
c.gallery = GalleryWidget(search=c.search, page=c.user.primary_page)
elixir.session.commit()
redirect(url(controller="users", action="view", name=c.user.name))
-
-
-
\ No newline at end of file
+
+
elixir.session.delete(tag)
elixir.session.commit()
redirect(url('show_art', id=art_id))
-
+
# TODO: login required
def create(self, art_id):
c.art = h.get_object_or_404(Art, id=art_id)
if not instance:
instance = model(**kwargs)
return instance
-
+
def update_or_create(model, get_by, update_with):
instance = model.get_by(**get_by)
if instance:
if tag:
elixir.session.delete(tag)
- else:
+ else:
if len(text) > 50:
raise "Long Tag!" # can we handle this more gracefully?
# sqlite seems happy to store strings much longer than the supplied limit...
def rate(self, score, user):
return update_or_create(Rating, {"rater":user, "art":self}, {"score":score})
-
+
def user_score(self, user):
rating = Rating.get_by(rater=user, art=self)
if rating:
def __unicode__(self):
return self.text
-
+
class Rating(Entity):
art = ManyToOne('Art', ondelete='cascade')
rater = ManyToOne('User', ondelete='cascade')
score = Field(Integer)
-
+
# @score.setter
- # def score(self, value):
-
+ # def score(self, value):
+
options = {-1:"sucks", 0:"undecided", 1:"good", 2:"great"}
default = 0
# options = ["sucks","neutral","good","great"]
-
+
Rating.reverse_options = dict (zip(Rating.options.values(), Rating.options.keys()))
\ No newline at end of file
class SavedSearch(Entity):
string = Field(Unicode) # I tried calling this query, but it broke elixir
author = ManyToOne('User')
-
+
def __unicode__(self):
return self.string
-
+
@property
def results(self):
return do_search(self.string)
# NOTE: no longer needed now that we have pages, I guess.
# displayer = ManyToOne('User') # determines whose page should it should show up on
# # Could be no-ones, if it's just a template.
-
+
# Needs some fields for position on your page
@property
def string(self):
return self.search
-
+
@string.setter
def string(self, value):
# TODO: should we delete the possibly orphaned saved search?
# if not self.displayer:
# # TODO: may have to refactor this into an init if the key ordering is inconvenienc
# raise "Oh no! This gallery needs a displayer to set on the saved search."
-
+
self.search = SavedSearch(author=getattr(self,"author",None), string=value)
-
\ No newline at end of file
pages = OneToMany('UserPage', inverse="owner")
primary_page = OneToOne('UserPage', inverse="owner")
-
+
def __unicode__(self):
return self.name
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
-
-
-
+
+
+
# TODO: have this clone a standard starter page
self.primary_page = UserPage(owner=self, title="default", visible=True)
-
+
# a starter gallery, just for fun
gallery = GalleryWidget(owner=self, string="awesome")
self.primary_page.galleries.append(gallery)
Page templates that provide familiar interfaces will also be UserPage records. Users will
see a panel full of them, and they can choose to clone those template pages to their own page list.
If more than one is set to visible, there would be tabs.
-
+
"""
-
+
owner = ManyToOne('User', inverse="pages")
title = Field(String)
-
+
visible = Field(Boolean)
galleries = OneToMany('GalleryWidget')
\ No newline at end of file
% endif
${h.form(h.url_for('search'), method='GET')}
-${h.text('query', c.query)}
-${h.submit('button', 'Search')}
+${h.text('query', c.query)}
+${h.submit('button', 'Search')}
% if c.user:
${h.submit('button', 'Save')}