skip audio reprocessing if necessary
[mediagoblin.git] / mediagoblin / tools / staticdirect.py
index 7477de68b8d62cbf9d43c8e5af6c736b5307316c..8381b8b6874b81ec475dfa5399bd05a1aab18868 100644 (file)
 # This needs documentation!
 ####################################
 
-import pkg_resources
 import logging
 
 _log = logging.getLogger(__name__)
 
 
 class StaticDirect(object):
-    def __init__(self):
+    """
+    Direct to a static resource.
+
+    This StaticDirect class can take a series of "domains" to
+    staticdirect to.  In general, you should supply a None domain, as
+    that's the "default" domain.
+
+    Things work like this::
+
+      >>> staticdirect = StaticDirect(
+      ...     {None: "/static/",
+      ...      "theme": "http://example.org/themestatic/"})
+      >>> staticdirect("css/monkeys.css")
+      "/static/css/monkeys.css"
+      >>> staticdirect("images/lollerskate.png", "theme")
+      "http://example.org/themestatic/images/lollerskate.png"
+    """
+    def __init__(self, domains):
+        self.domains = dict(
+            [(key, value.rstrip('/'))
+             for key, value in domains.iteritems()])
         self.cache = {}
 
-    def __call__(self, filepath):
-        if filepath in self.cache:
-            return self.cache[filepath]
+    def __call__(self, filepath, domain=None):
+        if domain in self.cache and filepath in self.cache[domain]:
+            return self.cache[domain][filepath]
 
-        if not pkg_resources.resource_exists('mediagoblin',
-                'static' + filepath):
-            _log.info("StaticDirect resource %r not found locally",
-                filepath)
-        static_direction = self.cache[filepath] = self.get(filepath)
+        static_direction = self.cache.setdefault(
+            domain, {})[filepath] = self.get(filepath, domain)
         return static_direction
 
-    def get(self, filepath):
-        # should be implemented by the individual staticdirector
-        pass
+    def get(self, filepath, domain=None):
+        return '%s/%s' % (
+            self.domains[domain], filepath.lstrip('/'))
 
 
-class RemoteStaticDirect(StaticDirect):
-    def __init__(self, remotepath):
-        StaticDirect.__init__(self)
-        self.remotepath = remotepath.rstrip('/')
+class PluginStatic(object):
+    """Pass this into the ``'static_setup'`` hook to register your
+    plugin's static directory.
 
-    def get(self, filepath):
-        return '%s/%s' % (
-            self.remotepath, filepath.lstrip('/'))
+    This has two mandatory attributes that you must pass in on class
+    init:
 
+    - *name:* this name will be both used for lookup in "urlgen" for
+      your plugin's static resources and for the subdirectory that
+      it'll be "mounted" to for serving via your web browser.  It
+      *MUST* be unique.  If writing a plugin bundled with MediaGoblin
+      please use the pattern 'coreplugin__foo' where 'foo' is your
+      plugin name.  All external plugins should use their modulename,
+      so if your plugin is 'mg_bettertags' you should also call this
+      name 'mg_bettertags'.
+    - *file_path:* the directory your plugin's static resources are
+      located in.  It's recommended that you use
+      pkg_resources.resource_filename() for this.
 
-class MultiRemoteStaticDirect(StaticDirect):
-    """
-    For whene separate sections of the static data is served under
-    separate urls.
-    """
-    def __init__(self, remotepaths):
-        StaticDirect.__init__(self)
-        self.remotepaths = remotepaths
+    An example of using this::
 
-    def get(self, filepath):
-        section, rest = filepath.strip('/').split('/', 1)
+      from pkg_resources import resource_filename
+      from mediagoblin.tools.staticdirect import PluginStatic
 
-        return '%s/%s' % (
-            self.remotepaths[section].rstrip('/'),
-            rest.lstrip('/'))
+      hooks = {
+          'static_setup': lambda: PluginStatic(
+              'mg_bettertags',
+              resource_filename('mg_bettertags', 'static'))
+      }
+
+    """
+    def __init__(self, name, file_path):
+        self.name = name
+        self.file_path = file_path
+
+    def __call__(self):
+        return self