rudimentary file uploading. Saves as sha1 like git objects. code is in lib. needs...
authorNick Retallack <nickretallack@gmil.com>
Sun, 4 Oct 2009 08:55:36 +0000 (01:55 -0700)
committerNick Retallack <nickretallack@gmil.com>
Sun, 4 Oct 2009 08:55:36 +0000 (01:55 -0700)
.gitignore
development.ini
floof/controllers/art.py [new file with mode: 0644]
floof/lib/file_storage.py [new file with mode: 0644]
floof/lib/helpers.py
floof/model/art.py
floof/templates/art/new.mako [new file with mode: 0644]
floof/templates/upload_art.mako [new file with mode: 0644]
floof/tests/functional/test_art.py [new file with mode: 0644]
floof/todo.txt [new file with mode: 0644]

index 77508f0..bc97b44 100644 (file)
@@ -5,3 +5,4 @@
 *.egg/
 *.egg-info/
 data/
+public/art/*
index bd6fc70..0c39bba 100644 (file)
@@ -19,6 +19,7 @@ port = 5000
 use = egg:floof
 full_stack = true
 static_files = true
+art_root = %(here)s/public/art
 
 cache_dir = %(here)s/data
 beaker.session.key = floof
@@ -36,7 +37,7 @@ sqlalchemy.url = sqlite:///%(here)s/development.db
 # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
 # Debug mode will enable the interactive debugging tool, allowing ANYONE to
 # execute malicious code after an exception is raised.
-set debug = false
+set debug = false
 
 
 # Logging configuration
diff --git a/floof/controllers/art.py b/floof/controllers/art.py
new file mode 100644 (file)
index 0000000..dd06f12
--- /dev/null
@@ -0,0 +1,29 @@
+import logging
+
+from pylons import request, response, session, tmpl_context as c, config
+from pylons.controllers.util import abort, redirect_to
+
+from floof.lib.base import BaseController, render
+
+log = logging.getLogger(__name__)
+
+
+
+from floof.lib.file_storage import save_file
+
+class ArtController(BaseController):
+
+    # def index():
+    #     c.artwork = Art.query.order_by(Art.id.desc()).all()
+    #     return render
+
+    def new(self):
+        """ New Art! """
+        return render("/art/new.mako")
+        
+        
+    def upload(self):
+        file = request.POST['file']
+        root = config['app_conf']['art_root']
+        save_file(root, file)
+        redirect_to(controller="main", action="index")
diff --git a/floof/lib/file_storage.py b/floof/lib/file_storage.py
new file mode 100644 (file)
index 0000000..5595e88
--- /dev/null
@@ -0,0 +1,58 @@
+# This sucks.  Make it not suck.
+import os, shutil, tempfile, hashlib
+
+chunk_size = 1024*1024 # TODO: is this a good chunk size?
+
+"""
+Notes:
+# Here's one way to move stuff...
+shutil.copyfileobj(temp.file, dest_file)
+
+# we should probably store the basename of the original filename in the database somewhere
+temp_base = os.path.basename(temp.filename)
+
+# You can get a mime type like so:
+from mimetypes import guess_type
+guess_type(temp.filename)[0]
+"""
+
+
+def save_file(dest_root, temp):    
+    # we don't know where we're going to save this stuff yet,
+    # so I guess we'll write it to another tempfile.  One we know the path of.
+    # I'm assuming the tempfile we get from pylons is set to delete itself 
+    # when it closes, and has no visible path.  Maybe I'm wrong?
+    intermediate_file_descriptor, intermediate_path = tempfile.mkstemp()
+    
+    # that function gives me an integer file descriptor for some reason.
+    intermediate_file = os.fdopen(intermediate_file_descriptor, "wb")
+    
+    sha1 = hashlib.sha1()
+    while 1:
+        data = temp.file.read(chunk_size)
+        if not data:
+            break
+        sha1.update(data)
+        intermediate_file.write(data)
+
+    temp.file.close()
+    intermediate_file.close()
+    hash = sha1.hexdigest()
+
+    # git convention: first two characters are the directory
+    dest_dir = os.path.join( dest_root, hash[:2] )
+    dest_path =  os.path.join( dest_dir, hash[2:] )
+
+    makedirs(dest_dir)
+    os.rename(intermediate_path, dest_path)
+
+    return hash
+
+
+
+def makedirs(dir):
+    try:
+         os.makedirs(dir)
+    except OSError:
+         pass
+    
\ No newline at end of file
index 878b888..ff55eb6 100644 (file)
@@ -5,3 +5,11 @@ available to Controllers. This module is available to templates as 'h'.
 """
 # Import helpers as desired, or define your own, ie:
 #from webhelpers.html.tags import checkbox, password
+from webhelpers import *
+from routes import url_for, redirect_to
+
+from webhelpers.html.tags import *
+from webhelpers.html import literal
+from webhelpers.pylonslib import Flash
+import sqlalchemy.types as types
+flash = Flash()
index 517fea0..725b9e8 100644 (file)
@@ -8,4 +8,5 @@ from elixir import Entity, Field, Integer, Unicode
 
 class Art(Entity):
     title = Field(Unicode(120))
+    # filename = Field(Unicode(120))
 
diff --git a/floof/templates/art/new.mako b/floof/templates/art/new.mako
new file mode 100644 (file)
index 0000000..4988917
--- /dev/null
@@ -0,0 +1,9 @@
+<%inherit file="/base.mako" />
+
+<h1>Add New Art</h1>
+<p>Now: Upload a file.  Later: Supply a link?  Not exclusive to uploading.</p>
+
+${h.form(h.url_for(controller='art', action='upload'), multipart=True)}
+${h.file('file')}
+${h.submit('submit', 'Upload!')}
+${h.end_form()}
\ No newline at end of file
diff --git a/floof/templates/upload_art.mako b/floof/templates/upload_art.mako
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/floof/tests/functional/test_art.py b/floof/tests/functional/test_art.py
new file mode 100644 (file)
index 0000000..e82d5c8
--- /dev/null
@@ -0,0 +1,7 @@
+from floof.tests import *
+
+class TestArtController(TestController):
+
+    def test_index(self):
+        response = self.app.get(url(controller='art', action='index'))
+        # Test response...
diff --git a/floof/todo.txt b/floof/todo.txt
new file mode 100644 (file)
index 0000000..f9a7cd0
--- /dev/null
@@ -0,0 +1 @@
+-- uploading files
\ No newline at end of file