Commits

ben...@localhost.metavers.net  committed 1067d70

commit since w have a working parser.
blueprint has been imported and css integration imported.
base.html fixed.

  • Participants
  • Parent commits 782dbb0

Comments (0)

Files changed (45)

File friendpaste.py

+#!/usr/local/bin/python2.5
+
 import friendpaste
 
 if __name__ == "__main__":

File friendpaste/__init__.py

 import web
 import sys
-
+import Queue
 import config
 from snippets.views import Snippet, Copy
+from core.indexer import IndexWorker
+
+paste_queue = Queue.Queue()
 
 render = web.template.render(config.TEMPLATES_DIR)
 web.template.Template.globals['DEBUG'] = config.DEBUG
 
-urls = (
+urls = (  
+        '/(.*)/', 'item',
         '/(?P<snippetid>\d*)', 'Snippet',
-        '/(?P<snippetid>\d+)/copy/', 'Copy',
+        '/(?P<snippetid>\d+)/copy', 'Copy',   
 )
 
+def delegate(path):
+    if not path.endswith('/'):
+        web.seeother("/" + path)
+
+
+def testing():
+    pass
+
+idx = IndexWorker(paste_queue)
+
+
+class item:
+    GET = POST = lambda self, path: delegate(path)
+
 _actions = []
 def action(f):
-    """Decorator to register an infogami action."""
+    """Decorator to register an friendpaste action."""
     _actions.append(f)
     return f
 
 
 @action
 def startserver():
+    idx.start()
     web.run(urls, globals(), *config.middleware)
 
 
 
 
 def run():
-    _load()
+    #_load()
     if len(sys.argv) == 1:
         run_action("startserver")
     else:

File friendpaste/config.py

 # -*- coding: utf-8 -*-
-import os.path, platform
+import os
+import platform
+
 PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 NODE_BENOITC = (platform.node() == 'marduk.metavers.net')
 middleware=[]
 
 STATIC_URL = "/static"
+STATIC_PATH = os.path.join(PROJECT_PATH,"../static")
+TEMPLATES_DIR = "templates/"
 
-TEMPLATES_DIR = "templates/"
+INDEX_PATH = os.path.join(PROJECT_PATH,"../index")

File friendpaste/core/delegate.py

+import web
+
+def delegate(path):
+    web.seeother("/" + path)

File friendpaste/core/indexer.py

+# -*- coding: utf-8 -*-
+import friendpaste
+
+import threading
+from datetime import date
+
+class IndexWorker(threading.Thread):
+    def __init__(self, queue):
+        super(IndexWorker, self).__init__()
+        self.setDaemon(1)
+        
+        self.d = date.today()
+         
+        self.f = open('%s/%s' % (friendpaste.config.INDEX_PATH,
+            self.d.isoformat().replace('-','')), mode='a')  
+        self.q = queue
+
+
+   
+    def index(self, item):
+        d = date.today()
+        if self.d != d:
+            self.d = d
+            self.f.close()
+            self.f = open('%s/%s' % (friendpaste.config.INDEX_PATH,
+                self.d.isoformat().replace('-','')), mode='a')
+        self.f.write(item + "\n")
+        self.f.flush()
+        self.q.task_done()
+
+    def run(self):
+        while True:
+            item = self.q.get() 
+            self.index(item)
+        self.f.close()
+            
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

File friendpaste/snippets/code.py

 # -*- coding: utf-8 -*-
-from pygments.lexers import get_all_lexers
-
 import friendpaste
 
-_snippet_tpl = """
-title = %(title)s
-#content 
-%(content)s
+from pygments.lexers import get_all_lexers
+from pygments import highlight, lexers, formatters
+import re
+import StringIO
+
+_snippet_tpl = """@title %(title)s
+@language %(language)s
+
+@content 
+%(snippet)s
 """
 
+METADATA_RE = re.compile('^@(?P<metadata>[a-z0-9\-_]+)\s+(?P<metacontent>.*)$', re.IGNORECASE)
+METADATA_COMMENT_RE = re.compile('^\s*--')
+CONTENT_START_RE = re.compile('^\s*@content\s*$')
+
+MANDATORY_TAGS = ['title', 'language']
+
+class MetadataException(Exception):
+	pass
+
+class Snippet(object):
+    def __init__(self):
+        self.title = ""
+        self.language = ""
+        self.content = ""
+        self.raw_content = None
+
+    def _parse(self):
+        """ load snippet text """
+        tags_seen = set()
+        end_reached = False
+        last_metadata = None
+        io_obj = StringIO.StringIO(self.raw_content) 
+        while not end_reached:
+            line = io_obj.readline()
+            if line.strip() == '': continue
+            if CONTENT_START_RE.match(line):
+                for t in MANDATORY_TAGS:
+                    if t not in tags_seen:
+                        raise MetadataException("Missing tag '%s' in snippet metadata" % (t))
+                setattr(self, 'content', io_obj.read())
+                self._highlight()
+                end_reached = True
+            elif METADATA_COMMENT_RE.match(line):
+                pass # comment
+            else:
+                last_metadata = self._parse_metadata_line(line, last_metadata)
+                tags_seen.add(last_metadata)
+
+
+    def _parse_metadata_line(self, line, last_metadata):
+        # parse a metadata line
+        match = METADATA_RE.match(line)
+        if match:
+            if match.group('metadata'):
+                metadata = match.group('metadata').lower()
+            else:
+                # metadata continuation
+                metadata = last_metadata
+
+            metacontent = match.group('metacontent').strip()
+            try:
+                setattr(self, metadata, metacontent)
+            except AttributeError:
+                raise MetadataException("Metadata '%s' not handled" % metadata)
+            return metadata
+        else:
+            try:
+                c = getattr(self, last_metaname)
+            except:
+                raise MetadataException("Syntax Error near '%s'" % line.rstrip())
+            c += line.strip()
+            setattr(self, last_metaname, c)
+
+    def _highlight(self):
+        lexer = lexers.get_lexer_by_name(self.language)
+        highlighted = highlight(self.content, lexer,
+                formatters.HtmlFormatter(linenos='inline', 
+                    cssclass="source", lineseparator="<br />"))
+        setattr(self, 'highlighted', highlighted)
+
+    def load(self, raw):
+        self.raw_content = raw
+        self._parse()
+
+    def loadfile(self, file):
+        self.filename = file
+        f = open(file, "r")
+        self.raw_content=f.read()
+        f.close()
+        self._parse()
+
+    def __unicode__(self):
+        return u"%s" % self.content
+
 def save_snippet(args):
     snippet = _snippet_tpl % { 
             'title': args['title'].value,
-            'content': args['content'].value
+            'language': args['language'].value,
+            'snippet': args['snippet'].value
     }
 
-    print snippet
+
+    s = Snippet()
+    s.load(snippet)
+    return s 

File friendpaste/snippets/views.py

 
 snippet_form = form.Form(
         form.Textbox("title"),
-        form.Textarea("content"),
+        form.Textarea("snippet", id="snippet", css="{required:true}"),
         form.Dropdown("language", LEXERS_CHOICE, value='text'),
         )
 
 class Snippet:
     def GET(self, snippetid):
+        friendpaste.paste_queue.put('snippet %s' % snippetid)
         if snippetid:
             print "Snippet %s" % (snippetid)
         else:
             print friendpaste.render.base(friendpaste.render.snippet_form(form, main_lexers, LEXERS_CHOICE))
 
     def POST(self, snippetid):
+        friendpaste.paste_queue.put('copy %s' % snippetid)
         form = snippet_form()
         if not form.validates(): 
             print friendpaste.render.snippet_form(form)
         else:
-            save_snippet(form)
+            snippet = save_snippet(form)
+            print friendpaste.render.base(friendpaste.render.snippet_details(snippet))
 
 class Copy:
     def GET(self, snippetid):
         print "copy 555"
+        friendpaste.paste_queue.put('copy %s' % snippetid)

File index/2007-12-14

Empty file added.

File index/20071214

+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 
+snippet 

File index/20071215

+snippet 
+snippet 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+snippet 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 

File index/<built-in method date of datetime.datetime object at 0x423e77d8>

Empty file added.
+from tests import *
+
+if __name__ == "__main__":
+    import unittest
+    unittest.main()

File static/css/base.css

+body { 
+	margin: 0;
+	padding: 0;
+	background: #f5f8fa;
+	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+	font-size: 12px;
+	color: #000;
+	}
+ul, ol, li, h1, h2, h3, h4, h5, p { margin: 0 0 0.5em 0; padding: 0; }
+strong { font-weight: bold;}
+a:link { text-decoration: none; color: #000; }
+a:visited { text-decoration: none; color: #000; }
+a:hover { text-decoration: underline; }
+a:active { text-decoration: underline; }
+
+
+
+/* form */
+input,
+select {
+	padding: 2px 3px;
+	border: 1px solid #b4ccd6;
+	font-size: 11px;
+	}
+select {
+	padding: 1px 2px;
+	}	
+input:focus,
+select:focus {
+	border: 1px dashed #fe4e00;
+	}
+input[type="button"],
+input[type="submit"],
+input[type="reset"] {
+/*	width: 100px; */
+	padding: 2px 5px;
+	height: 25px;
+	border: 1px solid #fe4e00;
+	background: url(../images/boutonAbg-2s.gif) top repeat-x #fe4e00;
+	font-size: 12px;
+	color: #fff;
+	}
+input[type="button"]:hover,
+input[type="submit"]:hover,
+input[type="reset"]:hover {
+	background: url(../images/boutonAbg-2s.gif) bottom repeat-x transparent #fe8900;
+	cursor: pointer;
+	color: #000;
+	}
+
+
+.form-row { clear: both; overflow:hidden; padding-top:5px; font-weight:normal;font-size:12px; }
+.form-row img, .form-row input { vertical-align:middle; }
+label {  margin-right: 4px;}
+.aligned label { display:block; padding:0 1em 3px 0; float:left; width:12em; }
+.aligned label.inline { display:inline; float:none; }
+.submit-row { padding-top:10px; line-height: 1.3em; vertical-align: middle; }
+
+#snippet { width: 540px; height: 250px; }

File static/css/blueprint/compressed/print.css

+body {
+line-height:1.5;
+font-family:"Helvetica Neue", "Lucida Grande", Arial, Verdana, sans-serif;
+color:#000;
+background:none;
+font-size:10pt;
+}
+
+.container {
+background:none;
+}
+
+h1,h2,h3,h4,h5,h6 {
+font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;
+}
+
+code {
+font:.9em "Courier New", Monaco, Courier, monospace;
+}
+
+img {
+float:left;
+margin:1.5em 1.5em 1.5em 0;
+}
+
+a img {
+border:none;
+}
+
+p img.top {
+margin-top:0;
+}
+
+hr {
+background:#ccc;
+color:#ccc;
+width:100%;
+height:2px;
+border:none;
+margin:2em 0;
+padding:0;
+}
+
+blockquote {
+font-style:italic;
+font-size:.9em;
+margin:1.5em;
+padding:1em;
+}
+
+.small {
+font-size:.9em;
+}
+
+.large {
+font-size:1.1em;
+}
+
+.quiet {
+color:#999;
+}
+
+.hide {
+display:none;
+}
+
+a:link,a:visited {
+background:transparent;
+font-weight:700;
+text-decoration:underline;
+}
+
+a:link:after,a:visited:after {
+content:" (" attr(href) ") ";
+font-size:90%;
+}

File static/css/blueprint/compressed/screen.css

+html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td {
+border:0;
+font-weight:inherit;
+font-style:inherit;
+font-size:100%;
+font-family:inherit;
+vertical-align:baseline;
+margin:0;
+padding:0;
+}
+
+body {
+line-height:1.5;
+background:#fff;
+font-size:75%;
+color:#222;
+font-family:"Helvetica Neue", "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
+margin:1.5em 0;
+}
+
+table {
+border-collapse:separate;
+border-spacing:0;
+margin-bottom:1.4em;
+}
+
+caption,th,td {
+text-align:left;
+font-weight:400;
+}
+
+blockquote:before,blockquote:after,q:before,q:after {
+content:"";
+}
+
+blockquote,q {
+quotes:;
+}
+
+a img {
+border:none;
+}
+
+h1,h2,h3,h4,h5,h6 {
+color:#111;
+font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+font-weight:400;
+}
+
+h1 {
+font-size:3em;
+line-height:1;
+margin-bottom:.5em;
+}
+
+h2 {
+font-size:2em;
+margin-bottom:.75em;
+}
+
+h3 {
+font-size:1.5em;
+line-height:1;
+margin-bottom:1em;
+}
+
+h4 {
+font-size:1.2em;
+line-height:1.25;
+margin-bottom:1.25em;
+}
+
+h5 {
+font-size:1em;
+font-weight:700;
+margin-bottom:1.5em;
+}
+
+h6 {
+font-size:1em;
+font-weight:700;
+}
+
+p.last {
+margin-bottom:0;
+}
+
+p img {
+float:left;
+margin:1.5em 1.5em 1.5em 0;
+padding:0;
+}
+
+p img.top {
+margin-top:0;
+}
+
+ul,ol {
+margin:0 1.5em 1.5em;
+}
+
+ul {
+list-style-type:circle;
+}
+
+ol {
+list-style-type:decimal;
+}
+
+dd {
+margin-left:1.5em;
+}
+
+abbr,acronym {
+border-bottom:1px dotted #666;
+}
+
+address {
+margin-top:1.5em;
+font-style:italic;
+}
+
+a:focus,a:hover {
+color:#000;
+}
+
+a {
+color:#009;
+text-decoration:underline;
+}
+
+blockquote {
+color:#666;
+font-style:italic;
+margin:1.5em;
+}
+
+em,dfn {
+font-style:italic;
+background:#ffc;
+}
+
+pre,code {
+white-space:pre;
+margin:1.5em 0;
+}
+
+pre,code,tt {
+font:1em 'andale mono', monotype.com, 'lucida console', monospace;
+line-height:1.5;
+}
+
+tt {
+display:block;
+line-height:1.5;
+margin:1.5em 0;
+}
+
+th {
+border-bottom:2px solid #ccc;
+font-weight:700;
+}
+
+td {
+border-bottom:1px solid #ddd;
+}
+
+th,td {
+padding:4px 10px 4px 0;
+}
+
+tfoot {
+font-style:italic;
+}
+
+caption {
+background:#ffc;
+}
+
+table .last {
+padding-right:0;
+}
+
+.small {
+font-size:.8em;
+margin-bottom:1.875em;
+line-height:1.875em;
+}
+
+.large {
+font-size:1.2em;
+line-height:2.5em;
+margin-bottom:1.25em;
+}
+
+.hide {
+display:none;
+}
+
+.highlight {
+background:#ff0;
+}
+
+.added {
+color:#060;
+}
+
+.removed {
+color:#900;
+}
+
+.top {
+margin-top:0;
+padding-top:0;
+}
+
+.bottom {
+margin-bottom:0;
+padding-bottom:0;
+}
+
+.container {
+width:950px;
+margin:0 auto;
+}
+
+.column {
+float:left;
+margin-right:10px;
+}
+
+.last {
+margin-right:0;
+}
+
+.span-1 {
+width:30px;
+}
+
+.span-2 {
+width:70px;
+}
+
+.span-3 {
+width:110px;
+}
+
+.span-4 {
+width:150px;
+}
+
+.span-5 {
+width:190px;
+}
+
+.span-6 {
+width:230px;
+}
+
+.span-7 {
+width:270px;
+}
+
+.span-8 {
+width:310px;
+}
+
+.span-9 {
+width:350px;
+}
+
+.span-10 {
+width:390px;
+}
+
+.span-11 {
+width:430px;
+}
+
+.span-12 {
+width:470px;
+}
+
+.span-13 {
+width:510px;
+}
+
+.span-14 {
+width:550px;
+}
+
+.span-15 {
+width:590px;
+}
+
+.span-16 {
+width:630px;
+}
+
+.span-17 {
+width:670px;
+}
+
+.span-18 {
+width:710px;
+}
+
+.span-19 {
+width:750px;
+}
+
+.span-20 {
+width:790px;
+}
+
+.span-21 {
+width:830px;
+}
+
+.span-22 {
+width:870px;
+}
+
+.span-23 {
+width:910px;
+}
+
+.span-24 {
+width:950px;
+margin:0;
+}
+
+.append-1 {
+padding-right:40px;
+}
+
+.append-2 {
+padding-right:80px;
+}
+
+.append-3 {
+padding-right:120px;
+}
+
+.append-4 {
+padding-right:160px;
+}
+
+.append-5 {
+padding-right:200px;
+}
+
+.append-6 {
+padding-right:240px;
+}
+
+.append-7 {
+padding-right:280px;
+}
+
+.append-8 {
+padding-right:320px;
+}
+
+.append-9 {
+padding-right:360px;
+}
+
+.append-10 {
+padding-right:400px;
+}
+
+.append-11 {
+padding-right:440px;
+}
+
+.append-12 {
+padding-right:480px;
+}
+
+.append-13 {
+padding-right:520px;
+}
+
+.append-14 {
+padding-right:560px;
+}
+
+.append-15 {
+padding-right:600px;
+}
+
+.append-16 {
+padding-right:640px;
+}
+
+.append-17 {
+padding-right:680px;
+}
+
+.append-18 {
+padding-right:720px;
+}
+
+.append-19 {
+padding-right:760px;
+}
+
+.append-20 {
+padding-right:800px;
+}
+
+.append-21 {
+padding-right:840px;
+}
+
+.append-22 {
+padding-right:880px;
+}
+
+.append-23 {
+padding-right:920px;
+}
+
+.prepend-1 {
+padding-left:40px;
+}
+
+.prepend-2 {
+padding-left:80px;
+}
+
+.prepend-3 {
+padding-left:120px;
+}
+
+.prepend-4 {
+padding-left:160px;
+}
+
+.prepend-5 {
+padding-left:200px;
+}
+
+.prepend-6 {
+padding-left:240px;
+}
+
+.prepend-7 {
+padding-left:280px;
+}
+
+.prepend-8 {
+padding-left:320px;
+}
+
+.prepend-9 {
+padding-left:360px;
+}
+
+.prepend-10 {
+padding-left:400px;
+}
+
+.prepend-11 {
+padding-left:440px;
+}
+
+.prepend-12 {
+padding-left:480px;
+}
+
+.prepend-13 {
+padding-left:520px;
+}
+
+.prepend-14 {
+padding-left:560px;
+}
+
+.prepend-15 {
+padding-left:600px;
+}
+
+.prepend-16 {
+padding-left:640px;
+}
+
+.prepend-17 {
+padding-left:680px;
+}
+
+.prepend-18 {
+padding-left:720px;
+}
+
+.prepend-19 {
+padding-left:760px;
+}
+
+.prepend-20 {
+padding-left:800px;
+}
+
+.prepend-21 {
+padding-left:840px;
+}
+
+.prepend-22 {
+padding-left:880px;
+}
+
+.prepend-23 {
+padding-left:920px;
+}
+
+.border {
+padding-right:4px;
+margin-right:5px;
+border-right:1px solid #eee;
+}
+
+.colborder {
+padding-right:24px;
+margin-right:25px;
+border-right:1px solid #eee;
+}
+
+.pull-1 {
+margin-left:-40px;
+}
+
+.pull-2 {
+margin-left:-80px;
+}
+
+.pull-3 {
+margin-left:-120px;
+}
+
+.pull-4 {
+margin-left:-160px;
+}
+
+.push-0 {
+margin:0 0 0 18px;
+}
+
+.push-1 {
+margin:0 -40px 0 18px;
+}
+
+.push-2 {
+margin:0 -80px 0 18px;
+}
+
+.push-3 {
+margin:0 -120px 0 18px;
+}
+
+.push-4 {
+margin:0 -160px 0 18px;
+}
+
+.push-0,.push-1,.push-2,.push-3,.push-4 {
+float:right;
+}
+
+.box {
+margin-bottom:1.5em;
+background:#eee;
+padding:1.5em;
+}
+
+hr {
+background:#ddd;
+color:#ddd;
+clear:both;
+float:none;
+width:100%;
+height:.1em;
+border:none;
+margin:0 0 1.4em;
+}
+
+hr.space {
+background:#fff;
+color:#fff;
+}
+
+.clear {
+display:block;
+}
+
+.clear:after,.container:after {
+content:".";
+display:block;
+height:0;
+clear:both;
+visibility:hidden;
+}
+
+* html .clear {
+height:1%;
+}
+
+fieldset {
+border:1px solid #ccc;
+margin:0 0 1.5em;
+padding:1.4em;
+}
+
+legend {
+font-weight:700;
+font-size:1.2em;
+}
+
+input.text,input.title {
+width:300px;
+border:1px solid #bbb;
+background:#f6f6f6;
+margin:.5em .5em .5em 0;
+padding:5px;
+}
+
+input.title {
+font-size:1.5em;
+}
+
+textarea {
+width:400px;
+height:250px;
+border:1px solid #bbb;
+background:#eee;
+margin:.5em .5em .5em 0;
+padding:5px;
+}
+
+select {
+border:1px solid #ccc;
+background:#f6f6f6;
+width:200px;
+}
+
+.error,.notice,.success {
+margin-bottom:1em;
+border:2px solid #ddd;
+padding:.8em;
+}
+
+.error {
+background:#FBE3E4;
+color:#D12F19;
+border-color:#FBC2C4;
+}
+
+.notice {
+background:#FFF6BF;
+color:#817134;
+border-color:#FFD324;
+}
+
+.success {
+background:#E6EFC2;
+color:#529214;
+border-color:#C6D880;
+}
+
+.error a {
+color:#D12F19;
+}
+
+.notice a {
+color:#817134;
+}
+
+.success a {
+color:#529214;
+}
+
+p,img,dl {
+margin:0 0 1.5em;
+}
+
+dl dt,strong,dfn,label {
+font-weight:700;
+}
+
+del,.quiet {
+color:#666;
+}
+
+input.text:focus,input.title:focus,textarea:focus,select:focus {
+background:#fff;
+border:1px solid #999;
+}

File static/css/blueprint/lib/forms.css

+/* -------------------------------------------------------------- 
+   
+   forms.css
+   * Sets up some default styling for forms
+   * Gives you classes to enhance your forms
+   
+   Usage:
+   * For text fields, use class .title or .text
+   
+-------------------------------------------------------------- */
+
+label { font-weight: bold; }
+
+
+/* Fieldsets */
+fieldset    { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; }
+legend      { font-weight: bold; font-size:1.2em; }
+
+/* Text fields */
+input.text, input.title   { width: 300px; margin:0.5em 0.5em 0.5em 0; }
+input.text, input.title   { border:1px solid #bbb; background:#f6f6f6; padding:5px; }
+input.text:focus,
+input.title:focus         { border:1px solid #999; background:#fff; }
+input.title               { font-size:1.5em; }
+
+/* Textareas */
+textarea            { width: 400px; height: 250px; margin:0.5em 0.5em 0.5em 0; }
+textarea            { border:1px solid #bbb; background:#eee; padding:5px; }
+textarea:focus      { border:1px solid #999; background:#fff; }
+
+/* Select fields */
+select              { border:1px solid #ccc; background:#f6f6f6; width:200px; }
+select:focus        { border:1px solid #999; background:#fff; }
+
+
+/* Success, error & notice boxes for messages and errors. */
+.error,
+.notice, 
+.success    { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
+.error      { background: #FBE3E4; color: #D12F19; border-color: #FBC2C4; }
+.notice     { background: #FFF6BF; color: #817134; border-color: #FFD324; }
+.success    { background: #E6EFC2; color: #529214; border-color: #C6D880; }
+.error a    { color: #D12F19; }
+.notice a   { color: #817134; }
+.success a  { color: #529214; }

File static/css/blueprint/lib/grid.css

+/* -------------------------------------------------------------- 
+   
+   grid.css
+   * Sets up an easy-to-use grid of 24 columns.
+   
+   Based on work by:
+   * Nathan Borror     [playgroundblues.com]
+   * Jeff Croft        [jeffcroft.com]
+   * Christian Metts   [mintchaos.com]
+   * Khoi Vinh         [subtraction.com]
+   
+   By default, the grid is 950px wide, with 24 columns 
+   spanning 30px, and a 10px margin between columns.
+   
+   If you need fewer or more columns, use this 
+   formula to find the new total width: 
+   Total width = (columns * 40) - 10
+   
+   Read more about using a grid here:
+   * subtraction.com/archives/2007/0318_oh_yeeaahh.php
+   
+-------------------------------------------------------------- */
+
+/* A container should group all your columns. */
+.container {
+  width: 950px;
+  margin: 0 auto;
+}
+
+
+/* Columns
+-------------------------------------------------------------- */
+
+/* Use this class together with the .span-x classes
+   to create any composition of columns in a layout. */
+   
+.column {
+  float: left;
+  margin-right: 10px;
+}
+
+
+/* The last column in a row needs this class. */
+.last { margin-right: 0; }
+
+/* Use these classes to set the width of a column. */
+.span-1   { width: 30px; }
+.span-2   { width: 70px; }
+.span-3   { width: 110px; }
+.span-4   { width: 150px; }
+.span-5   { width: 190px; }
+.span-6   { width: 230px; }
+.span-7   { width: 270px; }
+.span-8   { width: 310px; }
+.span-9   { width: 350px; }
+.span-10  { width: 390px; }
+.span-11  { width: 430px; }
+.span-12  { width: 470px; }
+.span-13  { width: 510px; }
+.span-14  { width: 550px; }
+.span-15  { width: 590px; }
+.span-16  { width: 630px; }
+.span-17  { width: 670px; }
+.span-18  { width: 710px; }
+.span-19  { width: 750px; }
+.span-20  { width: 790px; }
+.span-21  { width: 830px; }
+.span-22  { width: 870px; }
+.span-23  { width: 910px; }
+.span-24  { width: 950px; margin: 0; }
+
+/* Add these to a column to append empty cols. */
+.append-1   { padding-right: 40px; }  
+.append-2   { padding-right: 80px; } 
+.append-3   { padding-right: 120px; } 
+.append-4   { padding-right: 160px; } 
+.append-5   { padding-right: 200px; } 
+.append-6   { padding-right: 240px; } 
+.append-7   { padding-right: 280px; } 
+.append-8   { padding-right: 320px; } 
+.append-9   { padding-right: 360px; } 
+.append-10  { padding-right: 400px; } 
+.append-11  { padding-right: 440px; } 
+.append-12  { padding-right: 480px; } 
+.append-13  { padding-right: 520px; } 
+.append-14  { padding-right: 560px; } 
+.append-15  { padding-right: 600px; } 
+.append-16  { padding-right: 640px; } 
+.append-17  { padding-right: 680px; } 
+.append-18  { padding-right: 720px; } 
+.append-19  { padding-right: 760px; } 
+.append-20  { padding-right: 800px; } 
+.append-21  { padding-right: 840px; } 
+.append-22  { padding-right: 880px; } 
+.append-23  { padding-right: 920px; } 
+
+/* Add these to a column to prepend empty cols. */
+.prepend-1   { padding-left: 40px; }  
+.prepend-2   { padding-left: 80px; } 
+.prepend-3   { padding-left: 120px; } 
+.prepend-4   { padding-left: 160px; } 
+.prepend-5   { padding-left: 200px; } 
+.prepend-6   { padding-left: 240px; } 
+.prepend-7   { padding-left: 280px; } 
+.prepend-8   { padding-left: 320px; } 
+.prepend-9   { padding-left: 360px; } 
+.prepend-10  { padding-left: 400px; } 
+.prepend-11  { padding-left: 440px; } 
+.prepend-12  { padding-left: 480px; } 
+.prepend-13  { padding-left: 520px; } 
+.prepend-14  { padding-left: 560px; } 
+.prepend-15  { padding-left: 600px; } 
+.prepend-16  { padding-left: 640px; } 
+.prepend-17  { padding-left: 680px; } 
+.prepend-18  { padding-left: 720px; } 
+.prepend-19  { padding-left: 760px; } 
+.prepend-20  { padding-left: 800px; } 
+.prepend-21  { padding-left: 840px; } 
+.prepend-22  { padding-left: 880px; } 
+.prepend-23  { padding-left: 920px; } 
+
+
+/* Border on right hand side of a column. */
+.border {
+  padding-right: 4px;
+  margin-right: 5px;
+  border-right: 1px solid #eee;
+}
+
+/* Border with more whitespace, spans one column. */
+.colborder {
+  padding-right: 24px;
+  margin-right: 25px;
+  border-right: 1px solid #eee;
+}
+
+
+/* Use these classes on an element to push it into the 
+   next column, or to pull it into the previous column. */
+
+.pull-1  { margin-left: -40px; }
+.pull-2  { margin-left: -80px; }
+.pull-3  { margin-left: -120px; }
+.pull-4  { margin-left: -160px; }
+
+.push-0  { margin: 0 0 0 18px; }
+.push-1  { margin: 0 -40px 0 18px; }
+.push-2  { margin: 0 -80px 0 18px; }
+.push-3  { margin: 0 -120px 0 18px; }
+.push-4  { margin: 0 -160px 0 18px; }
+.push-0, .push-1, .push-2, .push-3, .push-4 { float: right; }
+
+
+/* Misc classes and elements
+-------------------------------------------------------------- */
+
+/* Use a .box to create a padded box inside a column.  */ 
+.box { 
+  padding: 1.5em; 
+  margin-bottom: 1.5em; 
+  background: #eee; 
+}
+
+/* Use this to create a horizontal ruler across a column. */
+hr {
+  background: #ddd; 
+  color: #ddd;
+  clear: both; 
+  float: none; 
+  width: 100%; 
+  height: .1em;
+  margin: 0 0 1.4em;
+  border: none; 
+}
+hr.space {
+  background: #fff;
+  color: #fff;
+}
+
+/* Clearing floats without extra markup
+   Based on How To Clear Floats Without Structural Markup by PiE
+   [http://www.positioniseverything.net/easyclearing.html] */
+
+.clear { display: inline-block; }   
+.clear:after, .container:after {
+  content: "."; 
+  display: block; 
+  height: 0; 
+  clear: both; 
+  visibility: hidden;
+}
+* html .clear { height: 1%; }
+.clear { display: block; }

File static/css/blueprint/lib/grid.png

Added
New image

File static/css/blueprint/lib/ie.css

+/* -------------------------------------------------------------- 
+   
+   ie.css
+   
+   Contains every hack for Internet Explorer versions prior 
+   to IE7, so that our core files stay sweet and nimble.
+   
+-------------------------------------------------------------- */
+
+/* Make sure the layout is centered in IE5 */
+body        { text-align: center; }
+.container  { text-align: left; }
+
+
+/* This fixes the problem where IE6 adds an extra 3px margin to
+   two columns that are floated up against each other. */
+
+* html .column { overflow-x: hidden; } /* IE6 fix */
+
+.pull-1, .pull-2, .pull-3, .pull-4,
+.push-1, .push-2, .push-3, .push-4, 
+ul, ol {
+  position: relative; /* Keeps IE6 from cutting pulled/pushed images */
+}
+
+/* Fixes incorrect styling of legend in IE6 fieldsets. */
+legend { margin-bottom:1.4em; }
+
+/* Fixes incorrect placement of numbers in ol's in IE6/7 */
+ol { margin-left:2em; }

File static/css/blueprint/lib/reset.css

+/* -------------------------------------------------------------- 
+  
+   reset.css
+   * Resets default browser CSS.
+   
+   Based on work by Eric Meyer:
+   * meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
+   
+-------------------------------------------------------------- */
+
+html, body, div, span, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, code,
+del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-weight: inherit;
+	font-style: inherit;
+	font-size: 100%;
+	font-family: inherit;
+	vertical-align: baseline;
+}
+
+
+body { line-height: 1.5; background: #fff; margin:1.5em 0; }
+
+/* Tables still need 'cellspacing="0"' in the markup. */
+table { border-collapse: separate; border-spacing: 0; }
+caption, th, td { text-align: left; font-weight:400; }
+
+/* Remove possible quote marks (") from <q>, <blockquote>. */
+blockquote:before, blockquote:after, q:before, q:after { content: ""; }
+blockquote, q { quotes: "" ""; }
+
+a img { border: none; }
+

File static/css/blueprint/lib/typography.css

+/* -------------------------------------------------------------- 
+   
+   typography.css
+   * Sets up some sensible default typography.
+  
+   Based on work by:
+   * Nathan Borror     [playgroundblues.com]
+   * Jeff Croft        [jeffcroft.com]
+   * Christian Metts   [mintchaos.com]
+   * Wilson Miner      [wilsonminer.com]
+   * Richard Rutter    [clagnut.com]
+   
+   Read more about using a baseline here:
+   * alistapart.com/articles/settingtypeontheweb
+  
+-------------------------------------------------------------- */
+
+/* This is where you set your desired font size. The line-heights 
+   and vertical margins are automatically calculated from this. 
+   The percentage is of 16px (0.75 * 16px = 12px). */
+   
+body { font-size: 75%; }
+
+
+/* Default fonts and colors. 
+   If you prefer serif fonts, remove the font-family 
+   on the headings, and apply this one to the body:
+   font: 1em Georgia, "lucida bright", "times new roman", serif; */
+   
+body { 
+  color: #222; 
+  font-family: "Helvetica Neue", "Lucida Grande", Helvetica, Arial, Verdana, sans-serif; 
+}
+h1,h2,h3,h4,h5,h6 { 
+  color: #111; 
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
+}
+
+
+/* Headings
+-------------------------------------------------------------- */
+
+h1,h2,h3,h4,h5,h6 { font-weight: normal; }
+
+h1 { font-size: 3em; line-height: 1; margin-bottom: 0.5em; }
+h2 { font-size: 2em; margin-bottom: 0.75em; }
+h3 { font-size: 1.5em; line-height: 1; margin-bottom: 1em; }
+h4 { font-size: 1.2em; line-height: 1.25; margin-bottom: 1.25em; }
+h5 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; }
+h6 { font-size: 1em; font-weight: bold; }
+
+
+/* Text elements
+-------------------------------------------------------------- */
+
+p           { margin: 0 0 1.5em; }
+p.last      { margin-bottom: 0; }
+p img       { float: left; margin: 1.5em 1.5em 1.5em 0; padding: 0; }
+p img.top   { margin-top: 0; } /* Use this if the image is at the top of the <p>. */
+img         { margin: 0 0 1.5em; }
+
+ul, ol      { margin:0 1.5em 1.5em 1.5em; }
+ul          { list-style-type: circle; }
+ol          { list-style-type: decimal; }
+dl          { margin: 0 0 1.5em 0; }
+dl dt       { font-weight: bold; }
+dd          { margin-left: 1.5em;}
+
+abbr, 
+acronym     { border-bottom: 1px dotted #666; }
+address     { margin-top: 1.5em; font-style: italic; }
+del         { color:#666; }
+
+a:focus, 
+a:hover     { color: #000; }
+a           { color: #009; text-decoration: underline; }
+
+blockquote  { margin: 1.5em; color: #666; font-style: italic; }
+strong      { font-weight: bold; }
+em,dfn      { font-style: italic; background: #ffc; }
+dfn         { font-weight: bold; }
+pre,code    { margin: 1.5em 0; white-space: pre; }
+pre,code,tt { font: 1em 'andale mono', 'monotype.com', 'lucida console', monospace; line-height: 1.5; } 
+tt          { display: block; margin: 1.5em 0; line-height: 1.5; }
+
+
+/* Tables
+-------------------------------------------------------------- */
+
+table   { margin-bottom: 1.4em; }
+th      { border-bottom: 2px solid #ccc; font-weight: bold; }
+td      { border-bottom: 1px solid #ddd; }
+th,td   { padding: 4px 10px 4px 0; }
+tfoot   { font-style: italic; }
+caption { background: #ffc; }
+
+/* Use this if you use span-x classes on th/td. */
+table .last { padding-right: 0; } 
+
+
+/* Some default classes
+-------------------------------------------------------------- */
+
+.small      { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; }
+.large      { font-size: 1.2em; line-height: 2.5em; margin-bottom: 1.25em; }
+.quiet      { color: #666; }
+
+.hide       { display: none; }
+.highlight  { background:#ff0; }
+.added      { color:#060; }
+.removed    { color:#900; }
+
+.top        { margin-top:0; padding-top:0; }
+.bottom     { margin-bottom:0; padding-bottom:0; }
+
+

File static/css/blueprint/plugins/buttons/Readme

+Buttons
+* Gives you great looking CSS buttons, for both <a> and <button>.
+* Demo: particletree.com/features/rediscovering-the-button-element
+
+
+Credits
+----------------------------------------------------------------
+
+* Created by Kevin Hale [particletree.com]
+* Adapted for Blueprint by Olav Bjorkoy [bjorkoy.com]
+
+
+Usage
+----------------------------------------------------------------
+
+1) Add this line to "blueprint/screen.css":
+	 @import 'plugins/buttons/buttons.css';
+
+2) Use the following HTML code to place the buttons on your site:
+
+	<button type="submit" class="button positive">
+	  <img src="css/blueprint/plugins/buttons/icons/tick.png" alt=""/> Save
+	</button>
+
+	<a class="button" href="/password/reset/">
+	  <img src="css/blueprint/plugins/buttons/icons/key.png" alt=""/> Change Password
+	</a>
+
+	<a href="#" class="button negative">
+	  <img src="css/blueprint/plugins/buttons/icons/cross.png" alt=""/> Cancel
+	</a>

File static/css/blueprint/plugins/buttons/buttons.css

+/* -------------------------------------------------------------- 
+  
+   buttons.css
+   * Gives you some great CSS-only buttons.
+   
+   Created by Kevin Hale [particletree.com]
+   * particletree.com/features/rediscovering-the-button-element
+
+   See Readme.txt in this folder for instructions.
+
+-------------------------------------------------------------- */
+
+a.button, button {
+  display:block;
+  float:left;
+  margin:0 0.583em 0.667em 0;
+  padding:5px 10px 5px 7px;   /* Links */
+  
+  border:1px solid #dedede;
+  border-top:1px solid #eee;
+  border-left:1px solid #eee;
+
+  background-color:#f5f5f5;
+  font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;
+  font-size:100%;
+  line-height:130%;
+  text-decoration:none;
+  font-weight:bold;
+  color:#565656;
+  cursor:pointer;
+}
+button {
+  width:auto;
+  overflow:visible;
+  padding:4px 10px 3px 7px;   /* IE6 */
+}
+button[type] {
+  padding:4px 10px 4px 7px;   /* Firefox */
+  line-height:17px;           /* Safari */
+}
+*:first-child+html button[type] {
+  padding:4px 10px 3px 7px;   /* IE7 */
+}
+button img, a.button img{
+  margin:0 3px -3px 0 !important;
+  padding:0;
+  border:none;
+  width:16px;
+  height:16px;
+  float:none;
+}
+
+
+/* Button colors
+-------------------------------------------------------------- */
+
+/* Standard */
+button:hover, a.button:hover{
+  background-color:#dff4ff;
+  border:1px solid #c2e1ef;
+  color:#336699;
+}
+a.button:active{
+  background-color:#6299c5;
+  border:1px solid #6299c5;
+  color:#fff;
+}
+
+/* Positive */
+body .positive {
+  color:#529214;
+}
+a.positive:hover, button.positive:hover {
+  background-color:#E6EFC2;
+  border:1px solid #C6D880;
+  color:#529214;
+}
+a.positive:active {
+  background-color:#529214;
+  border:1px solid #529214;
+  color:#fff;
+}
+
+/* Negative */
+body .negative {
+  color:#d12f19;
+}
+a.negative:hover, button.negative:hover {
+  background:#fbe3e4;
+  border:1px solid #fbc2c4;
+  color:#d12f19;
+}
+a.negative:active {
+  background-color:#d12f19;
+  border:1px solid #d12f19;
+  color:#fff;
+}

File static/css/blueprint/plugins/buttons/icons/cross.png

Added
New image

File static/css/blueprint/plugins/buttons/icons/key.png

Added
New image

File static/css/blueprint/plugins/buttons/icons/tick.png

Added
New image

File static/css/blueprint/plugins/css-classes/Readme

+CSS Development Classes Plugin
+
+Sets up some classes to use in CSS development
+
+This is an experimental plugin, and the tools it provides
+are not exactly semantically correct, so use with care,
+and preferably only in development. :)
+
+
+Usage
+----------------------------------------------------------------
+
+1) Add this line to "blueprint/screen.css", and you're done:
+	 @import 'plugins/css-classes/css-classes.css';

File static/css/blueprint/plugins/css-classes/css-classes.css

+/* -------------------------------------------------------------- 
+
+   css-classes.css
+   * Classes for CSS development
+   
+   See the Readme file in this directory
+   for further instructions.
+   
+-------------------------------------------------------------- */
+
+.left   { float:left; }
+.right  { float:right; }
+
+.hide   { display:none; }
+
+.reset-margin   { margin:0; } 
+.reset-padding  { padding:0; } 
+.reset          { margin:0; padding:0; } 
+
+.align-justify  { text-align:justify; } 
+.align-left     { text-align:left; } 
+.align-center   { text-align:center; } 
+.align-right    { text-align:right; } 
+

File static/css/blueprint/plugins/fancy-type/Readme

+Fancy Type
+* Gives you classes to use if you'd like some 
+  extra fancy typography. 
+
+Credits and instructions are specified above each class
+in the fancy-type.css file in this directory.
+
+
+Usage
+----------------------------------------------------------------
+
+1) Add this line to "blueprint/screen.css", and you're done:
+	 @import 'plugins/fancy-type/fancy-type-compressed.css';
+
+Note that this uses the compressed version of the CSS file, 
+as the original file contains a lot of instructing comments.
+
+Remember to re-compress (or change) the compressed file 
+if you make any changes to the original CSS file.
+
+Here's a pretty good CSS compressor: 
+http://teenage.cz/acidofil/tools/cssformat.php

File static/css/blueprint/plugins/fancy-type/fancy-type-compressed.css

+p + p { text-indent:2em; margin-top:-1.5em; }
+.alt{color:#666;font-family:"Warnock Pro","Goudy Old Style","Palatino","Book Antiqua",Georgia,serif;font-size:1.2em;line-height:80%;font-style:italic;}
+.dquo{margin-left:-.5em;}
+p.incr,.incr p{font-size:10px;line-height:1.44em;margin-bottom:1.5em;}
+.caps{font-variant:small-caps;letter-spacing:1px;text-transform:lowercase;font-size:1.2em;line-height:1%;font-weight:bold;}

File static/css/blueprint/plugins/fancy-type/fancy-type.css

+/* -------------------------------------------------------------- 
+  
+   fancy-type.css
+   * Lots of pretty advanced classes for manipulating text.
+   
+   See the Readme file in this folder for additional instructions.
+
+-------------------------------------------------------------- */
+
+/* Indentation instead of line shifts for sibling paragraphs. */
+   p + p { text-indent:2em; margin-top:-1.5em; }
+
+/* Ornaments on first paragraph.
+   Commented out by default. Use with care.
+   p:before { content: "\2767"; padding-right: 0.4em; }
+   p + p:before { content: ""; padding:0; } */
+
+/* For great looking type, use this code instead of asdf: 
+   <span class="alt">asdf</span>  
+   Best used on prepositions and ampersands. */
+  
+.alt { 
+  color: #666; 
+  font-family: "Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua", Georgia, serif; 
+  font-style: italic;
+  font-weight: normal;
+}
+
+
+/* For great looking quote marks in titles, replace "asdf" with:
+   <span class="dquo">&#8220;</span>asdf&#8221;
+   (That is, when the title starts with a quote mark). 
+   (You may have to change this value depending on your font size). */  
+   
+.dquo { margin-left: -.5em; } 
+
+
+/* Reduced size type with incremental leading