Implemented unique colorbars.
authorEevee <git@veekun.com>
Fri, 23 Apr 2010 07:36:52 +0000 (00:36 -0700)
committerEevee <git@veekun.com>
Fri, 23 Apr 2010 07:36:52 +0000 (00:36 -0700)
migration/versions/002_Add_User_unique_identifier.py [new file with mode: 0644]
spline/plugins/users/controllers/accounts.py
spline/plugins/users/model/__init__.py
spline/plugins/users/templates/css/users.mako [new file with mode: 0644]
spline/plugins/users/templates/users/lib.mako [new file with mode: 0644]
spline/plugins/users/templates/widgets/user_state.mako

diff --git a/migration/versions/002_Add_User_unique_identifier.py b/migration/versions/002_Add_User_unique_identifier.py
new file mode 100644 (file)
index 0000000..83dd3c5
--- /dev/null
@@ -0,0 +1,33 @@
+import random
+
+from sqlalchemy import *
+from migrate import *
+import migrate.changeset  # monkeypatches Column
+
+from sqlalchemy import orm
+from sqlalchemy.ext.declarative import declarative_base
+TableBase = declarative_base(bind=migrate_engine)
+
+
+class User(TableBase):
+    __tablename__ = 'users'
+    id = Column(Integer, primary_key=True)
+    name = Column(Unicode(length=20), nullable=False)
+    unique_identifier = Column(Unicode(length=32), nullable=False)
+
+
+session = orm.scoped_session(
+    orm.sessionmaker(autoflush=True, autocommit=False, bind=migrate_engine))
+
+def upgrade():
+    User.__table__.c.unique_identifier.create()
+
+    for user in session.query(User):
+        ident = u''.join(random.choice(u'0123456789abcdef') for _ in range(32))
+        user.unique_identifier = ident
+        session.add(user)
+
+    session.commit()
+
+def downgrade():
+    User.__table__.c.unique_identifier.drop()
index ba2fa26..e38a4cd 100644 (file)
@@ -69,8 +69,10 @@ class AccountsController(BaseController):
             # Create db records
             user = model.User(name=username)
             meta.Session.add(user)
             # Create db records
             user = model.User(name=username)
             meta.Session.add(user)
+
             openid = model.OpenID(openid=res.identity_url)
             user.openids.append(openid)
             openid = model.OpenID(openid=res.identity_url)
             user.openids.append(openid)
+
             meta.Session.commit()
 
         # Remember who's logged in, and we're good to go
             meta.Session.commit()
 
         # Remember who's logged in, and we're good to go
index f7a30d1..e4b824c 100644 (file)
@@ -1,3 +1,6 @@
+import colorsys
+import random
+
 from sqlalchemy import Column, ForeignKey
 from sqlalchemy.orm import relation
 from sqlalchemy.types import Integer, Unicode
 from sqlalchemy import Column, ForeignKey
 from sqlalchemy.orm import relation
 from sqlalchemy.types import Integer, Unicode
@@ -8,6 +11,56 @@ class User(TableBase):
     __tablename__ = 'users'
     id = Column(Integer, primary_key=True)
     name = Column(Unicode(length=20), nullable=False)
     __tablename__ = 'users'
     id = Column(Integer, primary_key=True)
     name = Column(Unicode(length=20), nullable=False)
+    unique_identifier = Column(Unicode(length=32), nullable=False)
+
+    def __init__(self, *args, **kwargs):
+        # Generate a unique hash if one isn't provided (which it shouldn't be)
+        if 'unique_identifier' not in kwargs:
+            ident = u''.join(random.choice(u'0123456789abcdef')
+                             for _ in range(32))
+            kwargs['unique_identifier'] = ident
+
+        super(User, self).__init__(*args, **kwargs)
+
+    @property
+    def unique_colors(self):
+        """Returns a list of (width, '#rrggbb') tuples that semi-uniquely
+        identify this user.
+        """
+
+        width_blob, colors_blob = self.unique_identifier[0:8], \
+                                  self.unique_identifier[8:32]
+
+        widths = []
+        for i in range(4):
+            width_hex = width_blob[i*2:i*2+2]
+            widths.append(int(width_hex, 16))
+        total_width = sum(widths)
+
+        ret = []
+        for i in range(4):
+            h = int(colors_blob[i*6:i*6+2], 16) / 256.0
+            l = int(colors_blob[i*6+2:i*6+4], 16) / 256.0
+            s = int(colors_blob[i*6+4:i*6+6], 16) / 256.0
+
+            # Cap lightness to 0.25 to 0.75, so it's not too close to white or
+            # black
+            l = l * 0.5 + 0.25
+
+            # Cap saturation to 0.5 to 1.0, so the color isn't too gray
+            s = s * 0.5 + 0.5
+
+            r, g, b = colorsys.hls_to_rgb(h, l, s)
+            color = "#{0:02x}{1:02x}{2:02x}".format(
+                int(r * 256),
+                int(g * 256),
+                int(b * 256),
+            )
+
+            ret.append((1.0 * widths[i] / total_width, color))
+
+        return ret
+
 
 class OpenID(TableBase):
     __tablename__ = 'openid'
 
 class OpenID(TableBase):
     __tablename__ = 'openid'
diff --git a/spline/plugins/users/templates/css/users.mako b/spline/plugins/users/templates/css/users.mako
new file mode 100644 (file)
index 0000000..4c33efa
--- /dev/null
@@ -0,0 +1,2 @@
+.user-color-bar { display: inline-block; height: 1em; width: 3em; padding: 1px; vertical-align: middle; border: 1px solid black; background: #e0e0e0; }
+.user-color-bar-chunk { float: left; height: 1em; }
diff --git a/spline/plugins/users/templates/users/lib.mako b/spline/plugins/users/templates/users/lib.mako
new file mode 100644 (file)
index 0000000..34c3194
--- /dev/null
@@ -0,0 +1,7 @@
+<%def name="color_bar(user)">\
+<span class="user-color-bar">
+    % for width, color in user.unique_colors:
+    <span class="user-color-bar-chunk" style="width: ${width * 100.0}%; background-color: ${color};"></span>
+    % endfor
+</span>\
+</%def>
index dbc73a0..47c36f1 100644 (file)
@@ -1,6 +1,7 @@
+<%namespace name="userlib" file="/users/lib.mako" />
 % if c.user:
 ${h.form(url(controller='accounts', action='logout'), id='user')}
 % if c.user:
 ${h.form(url(controller='accounts', action='logout'), id='user')}
-    Logged in as ${c.user.name}.
+    Logged in as ${c.user.name} ${userlib.color_bar(c.user)}.
     <input type="submit" value="Log out">
 ${h.end_form()}
 % else:
     <input type="submit" value="Log out">
 ${h.end_form()}
 % else: