saved searches is going awesome. Partial work on adding them as galleries
authorNick Retallack <nickretallack@gmil.com>
Tue, 6 Oct 2009 05:22:22 +0000 (22:22 -0700)
committerNick Retallack <nickretallack@gmil.com>
Tue, 6 Oct 2009 05:22:22 +0000 (22:22 -0700)
13 files changed:
floof/config/routing.py
floof/controllers/art.py
floof/controllers/search.py
floof/lib/search.py [new file with mode: 0644]
floof/model/__init__.py
floof/model/art.py
floof/model/search.py [new file with mode: 0644]
floof/model/users.py
floof/public/layout.css
floof/templates/art/show.mako
floof/templates/base.mako
floof/templates/index.mako
floof/templates/searches.mako [new file with mode: 0644]

index c8b94b9..969376a 100644 (file)
@@ -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.
index 7378f7a..6c5e454 100644 (file)
@@ -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)
index abedd16..3b6faef 100644 (file)
@@ -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 (file)
index 0000000..3acb248
--- /dev/null
@@ -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')
index 9cacd18..1a81770 100644 (file)
@@ -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
index 6fd2036..c3fba3a 100644 (file)
@@ -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 (file)
index 0000000..011468c
--- /dev/null
@@ -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
index 6b06048..5c9783e 100644 (file)
@@ -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))
index 74a3c05..25737d0 100644 (file)
@@ -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; }
index 2ac5305..715b9d1 100644 (file)
@@ -2,8 +2,9 @@
 
 <%! from floof.model.art import Rating %>
 
-<h1>View Art</h1>
+<h1>Viewing Art</h1>
 
+% 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()}
 <a href="${url(controller='search', action='index', query=tag)}">${tag}</a>
 % endfor
 
-What do you think?
+<h2>What do you think?</h2>
 % for score,text in sorted(Rating.options.items()):
 <a href="${h.url_for(controller='art', action='rate', id=c.art.id)}?score=${score}" \
 % if c.your_score == score:
@@ -22,6 +23,7 @@ class="selected" \
 % endif
 >${text}</a> 
 % endfor
+% endif
 
 <img class="full" src="${c.art.get_path()}">
 
index f50f56a..f15b0c6 100644 (file)
 <div id="header">
 <a href="${h.url_for("/")}">Home</a>
 
+% if c.user:
+| <a href="${h.url_for(controller="art", action="new")}">Add Art</a>
+| <a href="${h.url_for(controller="search", action="list")}">Your Searches</a>
+## | <a href="${h.url_for("/users/"+c.user}">Your Page</a>
+% endif
+
 ${h.form(h.url_for(controller='search'), method='GET')}
-${h.text('query')} ${h.submit(None, 'Search')}
+${h.text('query', c.query)} 
+${h.submit('button', 'Search')} 
+
+% if c.user:
+${h.submit('button', 'Save')}
+% endif
+
+## Note: should probably only display "save" when we're on a results page
+## Also, what if we had it save a hidden form containing the search result that was
+## actually rendered?  Might be confusing though.
 ${h.end_form()}
 
     <div id="user">
index e9abdfa..af95f7a 100644 (file)
@@ -1,6 +1,5 @@
 <%inherit file="base.mako" />
 
-<a href="${h.url_for(controller="art", action="new")}">Add New Art!</a>
 
 <ul class="artwork-grid">
     % for artwork in c.artwork:
diff --git a/floof/templates/searches.mako b/floof/templates/searches.mako
new file mode 100644 (file)
index 0000000..cdfbfea
--- /dev/null
@@ -0,0 +1,8 @@
+<%inherit file="base.mako" />
+
+<ul>
+% for search in c.searches:
+<li><a href="${h.url_for(controller="search", action="index")}?query=${search}">${search}</a>
+    - <a href="${h.url_for(controller="search", action="display", id=search.id)}">(display on your page)</a>
+% endfor
+</ul>
\ No newline at end of file