[z3-checkins] r41923 - z3/deliverance/DeliveranceVHoster/trunk/dvhoster
ianb at codespeak.net
ianb at codespeak.net
Fri Apr 6 00:25:41 CEST 2007
Author: ianb
Date: Fri Apr 6 00:25:41 2007
New Revision: 41923
Added:
z3/deliverance/DeliveranceVHoster/trunk/dvhoster/model.py
- copied unchanged from r41921, z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py
Removed:
z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py
Modified:
z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py
Log:
Renamed dataprovider to more normal name 'model'
Deleted: /z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py
==============================================================================
--- /z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py Fri Apr 6 00:25:41 2007
+++ (empty file)
@@ -1,327 +0,0 @@
-import re
-import os
-from ohm import persist
-from ohm import server
-from ohm import descriptors
-from ohm import lildav
-from ohm.validators import LineConverter
-from formencode import validators
-from formencode.foreach import ForEach
-from formencode.compound import All
-
-domain_re = re.compile(r'^localhost|[a-z][a-z0-9.\-]+\.[a-z]+$', re.I)
-
-default_rule_xml = '''\
-<?xml version="1.0" encoding="UTF-8"?>
-<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance" >
- <xi:include href="standardrules.xml" />
-
- <copy theme="//div[@id='container']" content="//*[@id='portal-columns']" />
-</rules>
-'''
-
-marker = '<!-- Generated, do not edit! -->'
-abstract_rule_xml = '''\
-<?xml version="1.0" encoding="UTF-8"?>
-MARKER
-<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance" >
- <xi:include href="standardrules.xml" />
-
- <copy theme="//*[%(theme_expr)s]" content="//*[%(content_expr)s]" />
-</rules>
-'''.replace('MARKER', marker)
-
-default_standardrules = '''\
-<?xml version="1.0" encoding="UTF-8"?>
-<rules xmlns:xi="http://www.w3.org/2001/XInclude" xmlns="http://www.plone.org/deliverance">
- <prepend theme="//head" content="//head/link" nocontent="ignore" />
- <prepend theme="//head" content="//head/style" nocontent="ignore" />
- <append theme="//head" content="//head/script" nocontent="ignore" />
- <append theme="//head" content="//head/meta" nocontent="ignore" />
- <append-or-replace theme="//head" content="//head/title"
- nocontent="ignore" />
-</rules>
-'''
-
-class DataProvider(object):
-
- def __init__(self, dir):
- self.dir = dir
- if not os.path.exists(self.dir):
- print 'Creating data directory %s' % self.dir
- os.makedirs(self.dir)
-
- def alias_fn(self, alias):
- return os.path.join(self.dir, alias+'-alias.txt')
-
- def domain(self, domain_name, aliases=()):
- """
- Return the domain object for the given domain_name. The
- domain name given may not be the canonical domain.
- """
- domain_name = self.normalize(domain_name)
- alias_fn = self.alias_fn(domain_name)
- if os.path.exists(alias_fn):
- f = open(alias_fn, 'rb')
- alias = f.read()
- f.close()
- aliases = list(aliases)
- if alias in aliases:
- raise ValueError(
- "Infinite alias loop (found: %s -> %s)"
- % (aliases, alias))
- aliases.append(alias)
- return self.domain(alias, aliases=aliases)
- dir = os.path.join(self.dir, domain_name)
- if not os.path.exists(dir):
- os.mkdir(dir)
- return DomainDataProvider(self, domain_name, dir)
-
- def normalize(self, domain_name):
- """
- Normalize a domain name (lower case, no funny characters).
- """
- domain_name = domain_name.strip().lower()
- if not domain_re.search(domain_name):
- raise ValueError(
- 'Bad domain name: %r' % domain_name)
- return domain_name
-
- def add_alias(self, alias, domain):
- """
- Add an alias domain ``alias`` which points to ``domain``.
- There must not be an existing alias.
- """
- alias = self.normalize(alias)
- domain = self.normalize(domain)
- fn = self.alias_fn(alias)
- assert not os.path.exists(fn), (
- "Alias file already exists (%r)" % fn)
- f = open(fn, 'wb')
- f.write(domain)
- f.close()
-
- def remove_alias(self, alias, domain=None):
- """
- Remove the alias for the domain ``alias``. ``domain`` (if
- given) is what the alias should currently be pointing to (we
- won't remove the alias then if it points elsewhere).
- """
- alias = self.normalize(alias)
- if domain:
- domain = self.normalize(domain)
- fn = self.alias_fn(alias)
- if not os.path.exists(fn):
- raise ValueError(
- "Alias does not exist (not file %r)" % fn)
- if domain:
- f = open(fn, 'rb')
- existing = f.read().strip()
- f.close()
- if existing != domain:
- raise ValueError(
- "Tried to remove alias from %s->%s, but %s actually "
- "points to %s" % (alias, domain, alias, existing))
- os.unlink(fn)
-
- def rename_domain(self, old_domain_name, new_domain_name):
- """
- Rename the old domain to the new domain, returning the new domain
- object.
- """
- old_domain_name = self.normalize(old_domain_name)
- new_domain_name = self.normalize(new_domain_name)
- old_dir = os.path.join(self.dir, old_domain_name)
- new_dir = os.path.join(self.dir, new_domain_name)
- assert os.path.exists(old_dir)
- assert not os.path.exists(new_dir)
- os.rename(old_dir, new_dir)
- return self.domain(new_domain_name)
-
-class DomainDataProvider(object):
-
- def __init__(self, provider, domain_name, base_dir):
- self._domain_name = domain_name
- self.base_dir = base_dir
- self.provider = provider
-
- def __repr__(self):
- return '<%s %s for %s in %r>' % (
- self.__class__.__name__,
- hex(id(self)),
- self._domain_name,
- self.base_dir)
-
- def initialize(self):
- for dir in [self.base_dir, self.rule_dir,
- self.static_dir]:
- if not os.path.exists(dir):
- os.mkdir(dir)
- for filename, content in [
- ('rule.xml', default_rule_xml),
- ('standardrules.xml', default_standardrules)]:
- filename = os.path.join(self.rule_dir, filename)
- if not os.path.exists(filename):
- f = open(filename, 'w')
- f.write(content)
- f.close()
-
- @property
- def initialized(self):
- return hasattr(self, 'remote_uris')
-
- @property
- def rule_dir(self):
- return os.path.join(self.base_dir, 'rules')
-
- @property
- def static_dir(self):
- return os.path.join(self.base_dir, 'static')
-
- remote_uris = descriptors.json_converter(
- persist.file_property('remote_uris.txt'))
- theme_uri = persist.file_property('theme_uri.txt')
- redirects = descriptors.json_converter(
- persist.file_property('redirects.txt', default='[]'))
-
- additional_request_headers = descriptors.json_converter(
- persist.file_property('additional_request_headers.txt', default='[]'))
-
- def aliases__rename(self, old_aliases, new_aliases):
- dropped = list(old_aliases)
- added = list(new_aliases)
- for new_alias in new_aliases:
- if new_alias in dropped:
- dropped.remove(new_alias)
- added.remove(new_alias)
- for alias in dropped:
- self.provider.remove_alias(alias, self.domain)
- for alias in added:
- self.provider.add_alias(alias, self.domain)
-
- aliases = descriptors.watcher(
- descriptors.line_converter(persist.file_property('aliases.txt', default='')),
- after_watcher=aliases__rename)
-
- def set_rule_file(self, filename, content):
- filename = os.path.join(self.rule_dir, filename)
- f = open(filename, 'wb')
- f.write(content)
- f.close()
-
- def domain__get(self):
- return self._domain_name
-
- def domain__set(self, new_domain):
- aliases = self.aliases
- old_domain = self.domain
- new_obj = self.provider.rename_domain(self.domain, new_domain)
- # Clone new object as self:
- self.__dict__.update(new_obj.__dict__)
- for alias in aliases:
- self.provider.remove_alias(alias, domain=old_domain)
- self.provider.add_alias(alias, new_domain)
-
- domain = property(domain__get, domain__set)
-
-class DomainValidator(validators.Regex):
- regex = r'^[a-z0-9\-]+|[a-z0-9][a-z0-9\-\.\_]*\.[a-z]+$'
-
-class ListDictValidator(validators.FancyValidator):
- required_keys = ()
- optional_keys = ()
- trail_slash_keys = ()
- sort_key = None
-
- def validate_python(self, value, state=None):
- # Should be like [{'path': path, 'remote_uri': uri, 'comment': str}]
- # comment is optional
- try:
- assert isinstance(value, list), 'Must be list'
- for d in value:
- keys = d.keys()
- for key in self.required_keys:
- assert key in d, "Must have key %r in %r" % d
- assert isinstance(d[key], basestring), (
- '%s must be string (not %r)' % (key, d[key]))
- keys.remove(key)
- for key in self.optional_keys:
- if key not in d:
- continue
- assert isinstance(d[key], basestring), (
- '%s must be string (not %r)' % (key, d[key]))
- keys.remove(key)
- assert not keys, (
- "Key(s) not allowed: %s in %r"
- % (', '.join(map(repr, keys)), d))
- except AssertionError, e:
- raise validators.Invalid(str(e), value, state)
-
- def _to_python(self, value, state=None):
- for d in value:
- for key in self.trail_slash_keys:
- if key not in d:
- continue
- if not d[key].endswith('/'):
- d[key] += '/'
- if self.sort_key:
- value = sorted(value, key=self.sort_key)
- return value
-
-class RemoteURIValidator(ListDictValidator):
- required_keys = ('path', )
- optional_keys = ('comment', 'headers', 'remote_uri')
- trail_slash_keys = ('path', 'remote_uri')
- def sort_key(self, item):
- return -len(item['path'])
-
-class RewriteValidator(ListDictValidator):
- required_keys = ('rewrite', )
- # @@: Really we should require one of path or prefix
- optional_keys = ('path', 'prefix', 'comment')
- trail_slash_keys = ('prefix', 'rewrite')
-
-class HeaderValidator(validators.FancyValidator):
- header_name_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9-]+$')
- header_value_re = re.compile(r'^[^\n\r\000-\037\200-\377]*$')
-
- def validate_python(self, value, state=None):
- assert isinstance(value, list), (
- "Value must be a list (not %r)" % value)
- for item in list:
- assert isinstance(value, (list, tuple)), (
- "Item must be a list or tuple (not %r)" % value)
- assert len(item) == 2, (
- "Item must be a two-tuple (not %r)" % value)
- header, value = item
- assert header_name_re.search(header), (
- "Header name invalid: %r" % header)
- assert header_value_re.search(value), (
- "Header value invalid: %r" % value)
-
-class ProviderApp(server.ApplicationWrapper):
-
- theme_uri = server.Setter(
- validator=validators.URL())
- domain = server.Setter(
- validator=DomainValidator())
- aliases = server.Setter(
- validator=All(ForEach(DomainValidator()), LineConverter()))
- remote_uris = server.JSONSetter(
- validator=RemoteURIValidator())
- redirects = server.JSONSetter(
- validator=RewriteValidator())
- additional_request_headers = server.JSONSetter(
- validator=HeaderValidator())
-
- @server.appfactory()
- def rules(self):
- if not os.path.exists(self.rule_dir):
- os.makedirs(self.rule_dir)
- return lildav.LilDAV(self.rule_dir)
-
- @server.appfactory()
- def static(self):
- if not os.path.exists(self.static_dir):
- os.makedirs(self.static_dir)
- return lildav.LilDAV(self.static_dir)
Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py
==============================================================================
--- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py (original)
+++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py Fri Apr 6 00:25:41 2007
@@ -10,7 +10,7 @@
from wsgifilter import proxyapp
from wsgifilter import relocateresponse
from deliverance.wsgimiddleware import DeliveranceMiddleware
-from dvhoster.dataprovider import DataProvider, ProviderApp
+from dvhoster.model import DataProvider, ProviderApp
from dvhoster import current_environ
from dvhoster.debuginterp import Renderer
from dvhoster.util import load_func
More information about the z3-checkins
mailing list