Cleaned up websetup a little.
[zzz-floof.git] / floof / model / users.py
index 86c31d8..6643702 100644 (file)
 #   Copyright (c) 2009 Scribblr
 #
 
-# from elixir import Entity, Field, Unicode, belongs_to, has_many
+import re
+
 from elixir import *
+
 from search import GalleryWidget
 
 class User(Entity):
-    name = Field(Unicode(20))
+    name = Field(Unicode(20), unique=True, required=True)
+    display_name = Field(Unicode(20), required=True)
     uploads = OneToMany('Art')
     has_many('identity_urls', of_kind='IdentityURL')
     searches = OneToMany('SavedSearch')
     # 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')
+
+    @classmethod
+    def is_valid_name(cls, name):
+        """Returns True iff the name is a valid username.
+
+        Only lowercase letters, numbers, and hyphens are allowed.
+
+        Names must also be at least one character long, but no more than 20,
+        and cannot start or end with a hyphen.
+        """
+        return re.match('^[-a-z0-9]{1,20}$', name) \
+               and name[0] != '-' and name[-1] != '-'
+
 
-    
     def __unicode__(self):
         return self.name
 
+    def __str__(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)
+        prepositions = ['by','for','of']
+        for preposition in prepositions:
+            GalleryWidget(page=self.primary_page, string=preposition+":me", owner=self)
 
+        #UserPage.clone_primary_template(self)
 
-class IdentityURL(Entity):
-    url = Field(Unicode(255))
-    belongs_to('user', of_kind='User')
 
+class IdentityURL(Entity):
+    url = Field(Unicode(255), required=True)
+    user = ManyToOne('User', required=True)
 
 
+from copy import copy
 class UserPage(Entity):
+    default_name = "default"
+
+    ### This was a bit more complex than I thought it would be...
+    ### Sure it probably works ok, but I'd rather duct-tape it for now (above)
+    # @classmethod
+    # def get_primary_template(cls):
+    #     return cls.get_by(owner=None, title=cls.default_name)
+    # 
+    # @classmethod
+    # def make_primary_template(cls):
+    #     if not cls.get_primary_template():
+    #         page = cls(owner=None, title=cls.default_name, visible=True)
+    #         prepositions = ['by','for','of']
+    #         for preposition in prepositions:
+    #             GalleryWidget(page=page, string=preposition+":me")
+    #         
+    # @classmethod
+    # def clone_primary_template(cls, user):
+    #     template = cls.get_primary_template()
+    #     new = cls(owner=user, title=template.title)
+    #     for gallery in template.galleries:
+    #         new.galleries.append(GalleryWidget(user=user, string=gallery.string))
+    #     
+    #     
+    #     session.add(template)
+    #     template.user = user
+    #     template.id = None
+    #     return template
+    
     """A user can have multiple pages, though by default they only have one visible.
     This is so that they can keep some nice themed pages lying around for special occasions.
     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.
-    
-     """
+    If more than one is set to visible, there would be tabs.  The primary page is indicated in the user model.
+    """
     
     owner = ManyToOne('User', inverse="pages")
     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', required=True)
+    target_user = ManyToOne('User', required=True)
+    type = Field(Integer)  # UserRelationshipTypes above
+