Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 3dc507ab8c6d8fce88a435d0d3e46346f01a76b3 Louis Sobel committed Apr 10, 2012
16 README
@@ -0,0 +1,16 @@
+Drapache:
+
+A python server that uses the dropbox API to serve files
+
+It will create an index for a folder if one doesn't exist
+
+Static files work great.
+
+I'm trying to include the ability to execute python scripts that in a dropbox folder, this is where problems come in.
+
+It works, but its very hack-y and unstable
+
+
+
+I'm hosting an instance on heroku, go to get.drapache.com to set it up.
+
Binary file not shown.
@@ -0,0 +1,5 @@
+import subdomain
+import dbapiaccess
+from instance import Drapache
+
+from twistd_resource import DrapacheTwistdResource
Binary file not shown.
@@ -0,0 +1,37 @@
+"""
+Defines utility classes for connecting to dropbox
+"""
+
+import dropbox
+
+
+#credentials for Dropaches
+
+
+
+class DropboxClientCreator:
+
+
+ def __init__(self,app_key,app_secret,access_type='app_folder'):
+
+ self.app_key = app_key
+ self.app_secret = app_secret
+ self.access_type = access_type
+
+
+ def get_client(self,oauth_token,oauth_token_secret):
+
+ sess = dropbox.session.DropboxSession(self.app_key,self.app_secret,self.access_type)
+ sess.set_token(oauth_token,oauth_token_secret)
+ client = dropbox.client.DropboxClient(sess)
+ return client
+
+
+def generate_oauth_credentials():
+ sess = dropbox.session.DropboxSession(APP_KEY,APP_SECRET,'app_folder')
+ rt = sess.obtain_request_token()
+ url = sess.build_authorize_url(rt)
+ print url
+ raw_input()
+ at = sess.obtain_access_token(rt)
+ print at
Binary file not shown.
@@ -0,0 +1,37 @@
+"""
+The class that allows templateing from dropbox
+"""
+import jinja2
+import os
+import dropbox
+
+class DropboxLoader(jinja2.BaseLoader):
+
+
+ def __init__(self,client,search_root):
+ self.client = client
+ self.search_root = search_root
+
+
+ def get_source(self,environment,template):
+
+ template_path = os.path.join(self.search_root,template)
+
+ try:
+ f = self.client.get_file(template_path).read()
+ except dropbox.rest.ErrorResponse as e:
+ raise jinja2.TemplateNotFound(template)
+
+ return f,template_path,True
+
+
+def render_dropbox_template(client,template,data,search_root):
+ env = jinja2.Environment(loader=DropboxLoader(client,search_root))
+
+ try:
+ template = env.get_template(template)
+ output = template.render(**data)
+ except jinja2.TemplateNotFound as e:
+ output = "Template %s not found; looking in %s" % (template,search_root)
+
+ return output
Binary file not shown.
@@ -0,0 +1,154 @@
+"""
+Implements the interaction with the dropbox api
+"""
+import dropbox
+
+import dbpyexecute
+import index_generator
+from util import ResponseObject,DropacheException
+
+import os.path
+import re
+
+#for dev
+import pprint
+#
+
+
+
+class FileServer:
+ """
+ The class responsable for hitting the dropbox and processing the results
+
+ most of the power of the service will come from here
+ """
+
+
+ def __init__(self,client,get_params,query_string):
+ self.client = client
+ self.get_params = get_params
+ self.query_string = query_string
+
+ def serve(self,path):
+ """
+ serves the given path, returning a Response Object
+
+ some special rules
+ - if it is a directory,
+ returns an indexed list of the files
+ - if it is a directory without a trailing slash,
+ returns a redirect request (these will also be able to come fro)
+ """
+
+ try:
+ meta_info = self.client.metadata(path)
+
+ #### checking for the is_Deleted flag
+ try:
+ if meta_info['is_deleted']:
+ raise DropacheException(410,"File is deleted")
+ except KeyError:
+ pass #its not deleted
+
+ if meta_info['is_dir']:
+ #that means we are dealing with a directory
+ #first check if it doesn't end with a slash
+ if not path.endswith('/'):
+ redirect_location = path+'/'
+ if self.query_string:
+ redirect_location += '?'+self.query_string
+
+ return ResponseObject(301,'redirect',{'Location':redirect_location})
+ else:
+ return self._find_and_serve_index(meta_info,path)
+
+ else:
+ #serve file handles the routing of pyhton vs file
+ return self._serve_file(meta_info)
+
+
+ except dropbox.rest.ErrorResponse as e:
+ return ResponseObject(e.status,e.reason,headers=e.headers,error=True)
+
+ except DropacheException as e:
+ return ResponseObject(e.status,e.message,error=True)
+
+ def _serve_file(self,file_meta):
+ #here is where special handling must be invoked
+ if file_meta['path'].endswith('.dbpy'):
+ return self._serve_python(file_meta)
+ else:
+ return self._serve_static(file_meta)
+
+
+ def _serve_static(self,file_meta):
+ """
+ downloads and serves the file in path
+ """
+ path = file_meta['path']
+ f = self.client.get_file(path).read()
+ headers = {'Content-type':self._get_content_type(file_meta)}
+ return ResponseObject(200,f,headers)
+
+
+ def _serve_python(self,file_meta):
+ path = file_meta['path']
+ f = self.client.get_file(path).read()
+ if f.startswith("#NOEXECUTE"):
+ #allows these files to be shared without getting executed
+ headers = {'Content-type':'text/plain'}
+ return ResponseObject(200,f,headers)
+
+
+ param_dict = {}
+ param_dict['client'] = self.client
+ param_dict['get_params'] = self.get_params
+
+ return dbpyexecute.execute(f,**param_dict)
+
+ def _find_and_serve_index(self,directory_meta,path):
+ """
+ called when asked to serce a directory
+ check for the presence of an index file and serve it (without redirect of course)
+ or present an index if there isn't one
+ lets lok through meta_info[contents], anything with index is of interest
+ precedence is .dbpy, .html, .txt, and thats it
+
+ for now, just auto generate an index, fun!
+ """
+ extensions_precedence = ('dbpy','html','txt')
+
+ #build the re
+ re_string = "^index\.(%s)$"%( '|'.join(extensions_precedence) )
+ index_re = re.compile(re_string)
+
+ index_paths = {}
+
+ for file_meta in directory_meta['contents']:
+ file_path = file_meta['path']
+ base_name = os.path.basename(file_path)
+
+ index_re_match = index_re.match(base_name)
+
+ if index_re_match:
+ match_type = index_re_match.group(1)
+ index_paths[match_type] = file_meta
+
+
+ for extension in extensions_precedence:
+ if extension in index_paths:
+ return self._serve_file(index_paths[extension])
+
+
+ return ResponseObject(200,index_generator.get_index_file(directory_meta['contents'],path,self.client))
+
+
+ def _get_content_type(self,file_meta):
+ given = file_meta['mime_type']
+ if given.startswith('text/x-'):
+ return 'text/plain'
+ else:
+ return given
+
+
+
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,74 @@
+"""
+Here are the functions that will ship with python executable code
+"""
+
+import dbapijinja
+import sys
+import signal
+import time
+
+def get_builtins(**kwargs):
+ """
+ client is the client
+ get_params are the params from the get request
+ sandbox is the sandbox in which it runs
+ """
+
+ client = kwargs['client']
+ get_params = kwargs['get_params']
+ sandbox = kwargs['sandbox']
+
+
+ built_in_hash = {'GETPARAMS':get_params}
+ def register(function):
+
+ curglobs = globals()
+ curlocs = locals()
+
+ def outer_wrapper(*args,**kwargs):
+
+ for p in reversed(sandbox.protections):
+ p.disable(sandbox)
+
+ retval = function(*args,**kwargs)
+
+ #redo the protections
+ for p in sandbox.protections:
+ p.enable(sandbox)
+
+ return retval
+
+
+ built_in_hash[function.func_name] = outer_wrapper
+ return function
+
+
+
+
+ @register
+ def render_template(path,with_data=None,search_root="/_templates"):
+ """
+ renders the given template
+ """
+
+ print dbapijinja.render_dropbox_template(client,path,with_data,search_root)
+
+ @register
+ def die(message=""):
+ """
+ Raises an Exception
+ """
+ raise Exception(message)
+
+
+
+
+
+
+
+
+
+
+ return built_in_hash
+
+
Binary file not shown.
Oops, something went wrong.

0 comments on commit 3dc507a

Please sign in to comment.