From 6fb3ad2a578aa2e0eced735187a02a79a8907668 Mon Sep 17 00:00:00 2001 From: Nick Retallack Date: Mon, 5 Oct 2009 22:22:22 -0700 Subject: [PATCH] saved searches is going awesome. Partial work on adding them as galleries --- floof/config/routing.py | 2 ++ floof/controllers/art.py | 22 ++++++++++++---------- floof/controllers/search.py | 37 ++++++++++++++++++++++++++++++++----- floof/lib/search.py | 33 +++++++++++++++++++++++++++++++++ floof/model/__init__.py | 3 +-- floof/model/art.py | 2 +- floof/model/search.py | 30 ++++++++++++++++++++++++++++++ floof/model/users.py | 4 ++++ floof/public/layout.css | 2 ++ floof/templates/art/show.mako | 6 ++++-- floof/templates/base.mako | 17 ++++++++++++++++- floof/templates/index.mako | 1 - floof/templates/searches.mako | 8 ++++++++ 13 files changed, 145 insertions(+), 22 deletions(-) create mode 100644 floof/lib/search.py create mode 100644 floof/model/search.py create mode 100644 floof/templates/searches.mako diff --git a/floof/config/routing.py b/floof/config/routing.py index c8b94b9..969376a 100644 --- a/floof/config/routing.py +++ b/floof/config/routing.py @@ -42,6 +42,8 @@ def make_map(): map.connect('/tag/{id}/delete', controller='tag', action='delete') map.connect('/search', controller='search', action='index') + map.connect('/search/list', controller='search', action='list') + # default routing is back so we can test stuff. # please don't take it away until we have some more core features in. diff --git a/floof/controllers/art.py b/floof/controllers/art.py index 7378f7a..6c5e454 100644 --- a/floof/controllers/art.py +++ b/floof/controllers/art.py @@ -1,6 +1,6 @@ import logging -from pylons import request, response, session, tmpl_context as c +from pylons import request, response, session, tmpl_context as c, h from pylons.controllers.util import abort, redirect_to from floof.lib.base import BaseController, render @@ -28,19 +28,21 @@ class ArtController(BaseController): redirect_to(controller="main", action="index") def show(self, id): - c.art = Art.get(id) - c.your_score = c.art.user_score(c.user) + c.art = h.get_object_or_404(Art, id=id) + if c.user: + c.your_score = c.art.user_score(c.user) return render("/art/show.mako") - # should force logged in on these things + # TODO: login required def tag(self, id): - art = Art.get(id) - art.add_tags(request.params["tags"], c.user) + c.art = h.get_object_or_404(Art, id=id) + c.art.add_tags(request.params["tags"], c.user) elixir.session.commit() - redirect_to(action="show", id=art.id) + redirect_to(action="show", id=c.art.id) + # TODO: login required def rate(self, id): - art = Art.get(id) - art.rate(request.params["score"], c.user) + c.art = h.get_object_or_404(Art, id=id) + c.art.rate(request.params["score"], c.user) elixir.session.commit() - redirect_to(action="show", id=art.id) + redirect_to(action="show", id=c.art.id) diff --git a/floof/controllers/search.py b/floof/controllers/search.py index abedd16..3b6faef 100644 --- a/floof/controllers/search.py +++ b/floof/controllers/search.py @@ -1,6 +1,6 @@ import logging -from pylons import request, response, session, tmpl_context as c +from pylons import request, response, session, tmpl_context as c, h from pylons.controllers.util import abort, redirect_to from floof.lib.base import BaseController, render @@ -8,14 +8,17 @@ from floof.lib.base import BaseController, render log = logging.getLogger(__name__) from floof.model.art import Art, Tag, TagText +from floof.model.search import SavedSearch import elixir class SearchController(BaseController): def index(self): - """Search, implemented the stupid way!""" - query = request.params.get('query', '') - tags = query.split() + if request.params.get('button') == 'Save': + return self.save() + + c.query = request.params.get('query', '') + tags = c.query.split() tagtexts = TagText.query.filter(TagText.text.in_(tags)) tagtext_ids = [_.id for _ in tagtexts] @@ -25,4 +28,28 @@ class SearchController(BaseController): .filter(Tag.tagtext_id.in_(tagtext_ids)) \ .all() - return render('/index.mako') \ No newline at end of file + return render('/index.mako') + + # TODO: login required + def save(self): + c.query = request.params.get('query', '') + saved_search = SavedSearch(author=c.user, string=c.query) + elixir.session.commit() + redirect_to(action="list") + # 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) + # TODO: create a gallery widget + + redirect_to(controller="users", action="view", name=c.user.name) + + + \ No newline at end of file diff --git a/floof/lib/search.py b/floof/lib/search.py new file mode 100644 index 0000000..3acb248 --- /dev/null +++ b/floof/lib/search.py @@ -0,0 +1,33 @@ +def parse(query): + words = query.split() + + tags = [] + for word in words: + components = word.split(':') + if len(components) == 1: + # tags are plain. + tags.append(word) + elif components[0] == "rating": + if components[1].isnumeric(): + score = int(components[1]) + else: + score = Rating.reverse_options.get(components[1]) + + if -1 <= score <= 3: + pass + # TODO: Find stuff that has this rating + # Rating.query.filter(Rating.s) + + + + + tagtexts = TagText.query.filter(TagText.text.in_(tags)) + tagtext_ids = map(lambda x:x.id, tagtexts) + + # TODO: this is wrong. Please fix it so it returns art that has all the tags. + art_tag_pairs = elixir.session.query(Art,Tag).filter(Art.id == Tag.art_id).\ + filter(Tag.tagtext_id.in_(tagtext_ids)).all() + + # just the art please. + c.artwork = map(lambda x: x[0], art_tag_pairs) + return render('/index.mako') diff --git a/floof/model/__init__.py b/floof/model/__init__.py index 9cacd18..1a81770 100644 --- a/floof/model/__init__.py +++ b/floof/model/__init__.py @@ -22,8 +22,7 @@ if elixir.options_defaults.get('autoload', False) \ # # import other entities here, e.g. # from floof.model.blog import BlogEntry, BlogComment -from floof.model.art import Art -from floof.model.users import User, IdentityURL +from floof.model import art, users, search # Finally, call elixir to set up the tables. # but not if using reflected tables diff --git a/floof/model/art.py b/floof/model/art.py index 6fd2036..c3fba3a 100644 --- a/floof/model/art.py +++ b/floof/model/art.py @@ -18,7 +18,7 @@ class Art(Entity): original_filename = Field(Unicode(120)) hash = Field(String) - uploaded_by = ManyToOne('User') + uploader = ManyToOne('User') tags = OneToMany('Tag') # def __init__(self, **kwargs): diff --git a/floof/model/search.py b/floof/model/search.py new file mode 100644 index 0000000..011468c --- /dev/null +++ b/floof/model/search.py @@ -0,0 +1,30 @@ +from elixir import * +from users import User + +class SavedSearch(Entity): + string = Field(Unicode) # I tried calling this query, but it broke elixir + author = ManyToOne(User) + + def __unicode__(self): + return self.string + + +class GalleryWidget(Entity): + search = ManyToOne(SavedSearch) + 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 query(self): + return self.search.query + + @query.setter + def query(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=self.displayer, query=value) \ No newline at end of file diff --git a/floof/model/users.py b/floof/model/users.py index 6b06048..5c9783e 100644 --- a/floof/model/users.py +++ b/floof/model/users.py @@ -11,6 +11,10 @@ class User(Entity): name = Field(Unicode(20)) uploads = OneToMany('Art') has_many('identity_urls', of_kind='IdentityURL') + searches = OneToMany('SavedSearch') + + def __unicode__(self): + return self.name class IdentityURL(Entity): url = Field(Unicode(255)) diff --git a/floof/public/layout.css b/floof/public/layout.css index 74a3c05..25737d0 100644 --- a/floof/public/layout.css +++ b/floof/public/layout.css @@ -12,6 +12,8 @@ body { font-family: sans-serif; font-size: 12px; } /*** Common bits and pieces ***/ /* General form layout */ +a {color:blue; text-decoration:none; pointer:cursor;} /* Who needs visited links */ + dl.form { margin: 1em 0; padding-left: 1em; border-left: 0.5em solid gray; } dl.form dt { padding-bottom: 0.25em; font-style: italic; } dl.form dd { margin-bottom: 0.5em; } diff --git a/floof/templates/art/show.mako b/floof/templates/art/show.mako index 2ac5305..715b9d1 100644 --- a/floof/templates/art/show.mako +++ b/floof/templates/art/show.mako @@ -2,8 +2,9 @@ <%! from floof.model.art import Rating %> -

View Art

+

Viewing Art

+% if c.user: ${h.form (h.url_for (controller='art', action='tag', id=c.art.id), multipart=True)} Add Some Tags: ${h.text('tags')} ${h.submit('submit', 'Tag!')} @@ -14,7 +15,7 @@ ${h.end_form()} ${tag} % endfor -What do you think? +

What do you think?

% for score,text in sorted(Rating.options.items()): ${text} % endfor +% endif diff --git a/floof/templates/base.mako b/floof/templates/base.mako index f50f56a..f15b0c6 100644 --- a/floof/templates/base.mako +++ b/floof/templates/base.mako @@ -10,8 +10,23 @@