Added a watchstream page.
authorEevee <git@veekun.com>
Sun, 15 Nov 2009 08:14:17 +0000 (00:14 -0800)
committerEevee <git@veekun.com>
Sun, 15 Nov 2009 08:14:17 +0000 (00:14 -0800)
floof/config/routing.py
floof/controllers/art.py
floof/model/meta.py
floof/model/users.py
floof/templates/base.mako

index 645d138..02e597f 100644 (file)
@@ -55,12 +55,17 @@ def make_map():
         sub.connect('/*owner_url/comments/{id}/reply', action='reply')
         sub.connect('/*owner_url/comments/{id}/reply_done', action='reply_done', **require_POST)
 
+    # Art
     with map.submapper(controller="art") as sub:
         sub.connect('new_art',      '/art/new',         action="new")
         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")
 
+    # Some art pages pertain to a specific user, but still belong in the art
+    # controller
+    map.connect('/users/{name}/watchstream', controller='art', action='watchstream')
+
     with map.submapper(controller='tag') as sub:
         sub.connect('delete_tag', '/art/{art_id}/tag/{id}')
         sub.connect('create_tag', '/art/{art_id}/tag')
index d598292..b8406ed 100644 (file)
@@ -10,8 +10,11 @@ log = logging.getLogger(__name__)
 import elixir
 from floof.model.art import Art, Rating
 from floof.model.comments import Discussion
+from floof.model.users import User, UserRelationship
 
+from sqlalchemy import func
 from sqlalchemy.exceptions import IntegrityError
+from sqlalchemy.orm.exc import NoResultFound
 
 
 class ArtController(BaseController):
@@ -62,3 +65,20 @@ class ArtController(BaseController):
         elixir.session.commit()
 
         redirect(url('show_art', id=c.art.id))
+
+
+    def watchstream(self, name):
+        """Watchstream for a certain user."""
+        try:
+            c.watching_user = User.query.filter(func.lower(User.name) == name) \
+                                  .one()
+        except NoResultFound:
+            abort(404)
+
+        # This user has watches which are users which have art
+        # XXX use artist, not uploader
+        c.artwork = Art.query.join(Art.uploader,
+                                   User.target_of_relationships) \
+                       .filter(UserRelationship.user_id == c.watching_user.id)
+
+        return render('/index.mako')
index 1a20aa7..2992ae7 100644 (file)
@@ -9,7 +9,3 @@ engine = None
 
 # SQLAlchemy session manager. Updated by model.init_model()
 Session = scoped_session(sessionmaker())
-
-# Global metadata. If you have multiple databases with overlapping table
-# names, you'll need a metadata for each database
-metadata = MetaData()
index e2afd17..af4bfba 100644 (file)
@@ -16,6 +16,8 @@ class User(Entity):
     # galleries = OneToMany('GalleryWidget')
     pages = OneToMany('UserPage', inverse="owner")
     primary_page = OneToOne('UserPage', inverse="owner")
+    relationships = OneToMany('UserRelationship', inverse='user')
+    target_of_relationships = OneToMany('UserRelationship', inverse='target_user')
 
 
     def __unicode__(self):
@@ -53,4 +55,23 @@ class UserPage(Entity):
     title = Field(String)
 
     visible = Field(Boolean)
-    galleries = OneToMany('GalleryWidget')
\ No newline at end of file
+    galleries = OneToMany('GalleryWidget')
+
+
+class UserRelationshipTypes(object):
+    IS_WATCHING = 1
+
+class UserRelationship(Entity):
+    """Represents some sort of connection between users.
+
+    For the moment, this means "watching".  Later, it may mean friending or
+    ignoring.
+
+    XXX: Watching should be made more general than this; it should have the
+    power of an arbitrary query per watched artist without being unintelligible
+    to users.
+    """
+
+    user = ManyToOne('User')
+    target_user = ManyToOne('User')
+    type = Field(Integer)  # UserRelationshipTypes above
index e4acc6f..0f3597c 100644 (file)
@@ -13,6 +13,7 @@
 % if c.user:
 | <a href="${h.url("new_art")}">Add Art</a>
 | <a href="${h.url_for(controller="search", action="list")}">Your Searches</a>
+| <a href="${h.url_for(controller="art", action="watchstream", name=c.user.name.lower())}">Watchstream</a>
 ## | <a href="${h.url_for("/users/"+c.user}">Your Page</a>
 % endif