Anonymous avatar Anonymous committed ec8451f

working version of friendpaste

Comments (0)

Files changed (14)

 *.pyo
 tests/*.err
 *.swp
+store/*
 
 syntax: regexp
 .*\#.*\#$

friendpaste/__init__.py

 
 urls = (  
         '/(.*)/', 'item',
-        '/(?P<snippetid>\d*)', 'Snippet',
+        '/(?P<snippetid>\w*)', 'Snippet',
         '/(?P<snippetid>\d+)/copy', 'Copy',   
 )
 

friendpaste/config.py

 TEMPLATES_DIR = "templates/"
 
 INDEX_PATH = os.path.join(PROJECT_PATH,"../index")
+DATA_PATH = os.path.join(PROJECT_PATH, "../store")

friendpaste/core/db.py

-# -*- coding: utf-8 -*-
-from friendpaste import config
-
-from storm.locals import create_database, Store
-
-database = create_database(config.DB_URI)
-store = Store(database)
-

friendpaste/core/delegate.py

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

friendpaste/core/indexer.py

 import threading
 from datetime import date
 
+import struct
+_pack = struct.pack
+_unpack = struct.unpack
+
+
+
+nullid = "\0" * 20
+indexformatv0 = "i20s"
+
+class logio(object):
+    def __init__(self):
+        self.size = struct.calcsize(indexformatv0)
+
+    def packentry(self, timestamp, snippetid):
+        e = (timestamp, snippetid)
+        return _pack(indexformatv0, *e)
+
+
 class IndexWorker(threading.Thread):
     def __init__(self, queue):
         super(IndexWorker, self).__init__()
         
         self.d = date.today()
          
-        self.f = open('%s/%s' % (friendpaste.config.INDEX_PATH,
+        self.f = open('%s/%s.i' % (friendpaste.config.INDEX_PATH,
             self.d.isoformat().replace('-','')), mode='a')  
         self.q = queue
+        self._io = logio()
 
-
-   
-    def index(self, item):
+    def index(self, snippet):
         d = date.today()
         if self.d != d:
             self.d = d
             self.f.close()
-            self.f = open('%s/%s' % (friendpaste.config.INDEX_PATH,
+            self.f = open('%s/%s.i' % (friendpaste.config.INDEX_PATH,
                 self.d.isoformat().replace('-','')), mode='a')
-        self.f.write(item + "\n")
+
+        entry = self._io.packentry(snippet.created, snippet.id)
+        self.f.write(entry)
         self.f.flush()
         self.q.task_done()
 
     def run(self):
         while True:
-            item = self.q.get() 
-            self.index(item)
+            snippet = self.q.get() 
+            self.index(snippet)
         self.f.close()
             
 

friendpaste/core/lexers.py

-from pygments.lexers import get_all_lexers
-
-lexers = get_all_lexers()
-for l in lexers:
-    print "('%s','%s')," % (l[1][0],l[0])
-
-
-all_lexers = (
-        ('text', 'None'),
-        ('bash','Bash'),
-        ('c','C/C++'),
-        ('css','CSS'),
-        ('diff','Diff'),
-        ('html','HTML'),
-        ('java','Java'),
-        ('js','JavaScript'),
-        ('lua','Lua'),
-        ('perl','Perl'),
-        ('php', 'PHP'),
-        ('python','Python'),
-        ('rb','Ruby'),
-
-)

friendpaste/core/utils.py

+# -*- coding: utf-8 -*-
+import sha
+import binascii
+
+_sha = sha.new
+hex = binascii.hexlify
+bin = binascii.unhexlify
+
+
+def hash(c, t):
+    s = _sha(c)
+    s.update(t)
+    return s.digest()
+
+
+def short(node):
+    return hex(node[:6])

friendpaste/snippets/code.py

 # -*- coding: utf-8 -*-
 import friendpaste
+from friendpaste.core.utils import hash, short, bin, hex
 
 from pygments.lexers import get_all_lexers
 from pygments import highlight, lexers, formatters
 import re
 import StringIO
+from datetime import datetime
+from time import mktime
+import os
+import web
 
 _snippet_tpl = """@title %(title)s
 @language %(language)s
+@created %(created)s
 
 @content 
 %(snippet)s
 
 MANDATORY_TAGS = ['title', 'language']
 
+
 class MetadataException(Exception):
 	pass
 
 class Snippet(object):
     def __init__(self):
+        self.id = None
         self.title = ""
         self.language = ""
         self.content = ""
             else:
                 last_metadata = self._parse_metadata_line(line, last_metadata)
                 tags_seen.add(last_metadata)
+        
 
 
     def _parse_metadata_line(self, line, last_metadata):
                     cssclass="source", lineseparator="<br />"))
         setattr(self, 'highlighted', highlighted)
 
-    def load(self, raw):
+    def _genid(self):
+        charset = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
+        from random import choice
+        return ''.join([choice(charset) for i in range(8)])
+        
+    def save(self, raw):
         self.raw_content = raw
         self._parse()
+        found = False
+        id = ""
+        while not found:
+            id = self._genid()
+            dirs = '/'.join(c for c in id[0:4])
+            path = "%s/%s" % (friendpaste.config.DATA_PATH,dirs)
+            fn = "%s/%s" % (path, id[4:])
+            if not os.path.exists(path):
+                os.makedirs(path)
+                self.id = id
+                self.filename = fn
+                found = True
+                print path
+            elif not os.path.exists(fn):
+                self.id = id
+                self.filename = fn
+                found = True
 
-    def loadfile(self, file):
-        self.filename = file
-        f = open(file, "r")
-        self.raw_content=f.read()
+        f = open(self.filename, 'w')
+        f.write(self.raw_content)
+        f.close()
+
+
+
+    def get (self, id):
+        if len(id) <= 4:
+            raise
+
+        dirs = '/'.join(c for c in id[0:4])
+        fn = "%s/%s/%s" % (friendpaste.config.DATA_PATH,dirs, id[4:])
+        if not os.path.exists(fn):
+            raise
+       
+        self.id = id
+        self.filename = fn
+        f = open(self.filename, 'r')
+        self.raw_content = f.read()
         f.close()
         self._parse()
 
         return u"%s" % self.content
 
 def save_snippet(args):
+    now = datetime.now()
     snippet = _snippet_tpl % { 
             'title': args['title'].value,
             'language': args['language'].value,
-            'snippet': args['snippet'].value
+            'snippet': args['snippet'].value,
+            'created': int(mktime(now.timetuple()))
     }
 
+    s = Snippet()
+    s.save(snippet)
 
+    #friendpaste.paste_queue.put(s)
+    return s
+
+
+def get_snippet(id):
     s = Snippet()
-    s.load(snippet)
-    return s 
+    try:
+        s.get(id)
+    except:
+        raise
+    return s
+

friendpaste/snippets/models.py

-# -*- coding: utf-8 -*-
-from storm.locals import *
-from storm.exceptions import StoreError,DatabaseError
-
-import friendpaste
-from friendpaste.core.db import store
-
-class Snippet(object):
-   __storm_table__ = "paste"
-   __storm_primary__ = "id"
-   id = Int(primary=True)
-   title = Unicode()
-   content = Unicode()
-   lang = Unicode()
-   original_id = Int()
-   original = Reference(original_id, id)
-   created = DateTime()
-   expire = DateTime()
-   password = Unicode()
-   expired = Bool()
-   private = Bool()
-
-   def __init__(self, title, content, original_id=0):
-       self.title = title
-       self.content = content
-       self.original_id = original_id
-
-
-@friendpaste.install_hook
-def create_model():
-    try: 
-        store.execute("CREATE TABLE snippet "
-            "(id INTEGER PRIMARY KEY, title VARCHAR(100), "
-            "content LONGTEXT, original_id INTEGER, "
-            "created DATETIME, expire DATETIME, "
-            "password VARCHAR(32), "
-            "expired TINYINT(1), private TINYINT(1), "
-            "FULLTEXT (title,content))")
-    except DatabaseError, err:
-        print err[1]
-

friendpaste/snippets/views.py

 
 from friendpaste.snippets import LEXERS_CHOICE, main_lexers
 
-from code import save_snippet
+from code import save_snippet, get_snippet
 
 snippet_form = form.Form(
         form.Textbox("title"),
 
 class Snippet:
     def GET(self, snippetid):
-        friendpaste.paste_queue.put('snippet %s' % snippetid)
         if snippetid:
-            print "Snippet %s" % (snippetid)
+            try:
+                snippet = get_snippet(snippetid)
+            except:
+                return web.notfound()
+            print friendpaste.render.base(friendpaste.render.snippet_details(snippet))
         else:
             form = snippet_form()
             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:
             snippet = save_snippet(form)
-            print friendpaste.render.base(friendpaste.render.snippet_details(snippet))
+            web.redirect("/%s" % snippet.id)
+            #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)
+        pass
 copy 
 copy 
 copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+copy 
+snippet 

Empty file added.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.