Back to index

moin  1.9.0~rc2
Functions | Variables
MoinMoin.action.cache Namespace Reference

Functions

def key
def put
def exists
def remove
def url
def _get_headers
def _get_datafile
def _do_get
def _do_remove
def _do
def execute

Variables

tuple logging = log.getLogger(__name__)
tuple action_name = __name__.split('.')
string cache_arena = 'sendcache'
string cache_scope = 'wiki'
 do_locking = False

Function Documentation

def MoinMoin.action.cache._do (   request,
  do,
  key 
) [private]

Definition at line 243 of file cache.py.

00243 
00244 def _do(request, do, key):
00245     if do == 'get':
00246         _do_get(request, key)
00247     elif do == 'remove':
00248         _do_remove(request, key)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.cache._do_get (   request,
  key 
) [private]
send a complete http response with headers/data cached for key 

Definition at line 215 of file cache.py.

00215 
00216 def _do_get(request, key):
00217     """ send a complete http response with headers/data cached for key """
00218     try:
00219         last_modified, headers = _get_headers(request, key)
00220         if request.if_modified_since == last_modified:
00221             request.status_code = 304
00222         else:
00223             data_file = _get_datafile(request, key)
00224             for key, value in headers:
00225                 lkey = key.lower()
00226                 if lkey == 'content-type':
00227                     request.content_type = value
00228                 elif lkey == 'last-modified':
00229                     request.last_modified = value
00230                 elif lkey == 'content-length':
00231                     request.content_length = value
00232                 else:
00233                     request.headers.add(key, value)
00234             request.send_file(data_file)
00235     except caching.CacheError:
00236         request.status_code = 404
00237 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.cache._do_remove (   request,
  key 
) [private]
delete headers/data cache for key 

Definition at line 238 of file cache.py.

00238 
00239 def _do_remove(request, key):
00240     """ delete headers/data cache for key """
00241     remove(request, key)
00242 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.cache._get_datafile (   request,
  key 
) [private]
get an open data file for the data cached for key 

Definition at line 208 of file cache.py.

00208 
00209 def _get_datafile(request, key):
00210     """ get an open data file for the data cached for key """
00211     data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
00212     data_cache.open(mode='r')
00213     return data_cache
00214 

Here is the caller graph for this function:

def MoinMoin.action.cache._get_headers (   request,
  key 
) [private]
get last_modified and headers cached for key 

Definition at line 201 of file cache.py.

00201 
00202 def _get_headers(request, key):
00203     """ get last_modified and headers cached for key """
00204     meta_cache = caching.CacheEntry(request, cache_arena, key+'.meta', cache_scope, do_locking=do_locking, use_pickle=True)
00205     meta = meta_cache.content()
00206     return meta['httpdate_last_modified'], meta['headers']
00207 

Here is the caller graph for this function:

def MoinMoin.action.cache.execute (   pagename,
  request 
)

Definition at line 249 of file cache.py.

00249 
00250 def execute(pagename, request):
00251     do = request.values.get('do')
00252     key = request.values.get('key')
00253     _do(request, do, key)
00254 

Here is the call graph for this function:

def MoinMoin.action.cache.exists (   request,
  key,
  strict = False 
)
Check if a cached object for this key exists.

@param request: the request object
@param key: non-guessable key into cache (str)
@param strict: if True, also check the data cache, not only meta (bool, default: False)
@return: is object cached? (bool)

Definition at line 168 of file cache.py.

00168 
00169 def exists(request, key, strict=False):
00170     """
00171     Check if a cached object for this key exists.
00172 
00173     @param request: the request object
00174     @param key: non-guessable key into cache (str)
00175     @param strict: if True, also check the data cache, not only meta (bool, default: False)
00176     @return: is object cached? (bool)
00177     """
00178     if strict:
00179         data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
00180         data_cached = data_cache.exists()
00181     else:
00182         data_cached = True  # we assume data will be there if meta is there
00183 
00184     meta_cache = caching.CacheEntry(request, cache_arena, key+'.meta', cache_scope, do_locking=do_locking, use_pickle=True)
00185     meta_cached = meta_cache.exists()
00186 
00187     return meta_cached and data_cached
00188 

def MoinMoin.action.cache.key (   request,
  wikiname = None,
  itemname = None,
  attachname = None,
  content = None,
  secret = None 
)
Calculate a (hard-to-guess) cache key.

Important key properties:
* The key must be hard to guess (this is because do=get does no ACL checks,
  so whoever got the key [e.g. from html rendering of an ACL protected wiki
  page], will be able to see the cached content.
* The key must change if the (original) content changes. This is because
  ACLs on some item may change and even if somebody was allowed to see some
  revision of some item, it does not implicate that he is allowed to see
  any other revision also. There will be no harm if he can see exactly the
  same content again, but there could be harm if he could access a revision
  with different content.

If content is supplied, we will calculate and return a hMAC of the content.

If wikiname, itemname, attachname is given, we don't touch the content (nor do
we read it ourselves from the attachment file), but we just calculate a key
from the given metadata values and some metadata we get from the filesystem.

Hint: if you need multiple cache objects for the same source content (e.g.
      thumbnails of different sizes for the same image), calculate the key
      only once and then add some different prefixes to it to get the final
      cache keys.

@param request: the request object
@param wikiname: the name of the wiki (if not given, will be read from cfg)
@param itemname: the name of the page
@param attachname: the filename of the attachment
@param content: content data as unicode object (e.g. for page content or
                parser section content)
@param secret: secret for hMAC calculation (default: use secret from cfg)

Definition at line 54 of file cache.py.

00054 
00055 def key(request, wikiname=None, itemname=None, attachname=None, content=None, secret=None):
00056     """
00057     Calculate a (hard-to-guess) cache key.
00058 
00059     Important key properties:
00060     * The key must be hard to guess (this is because do=get does no ACL checks,
00061       so whoever got the key [e.g. from html rendering of an ACL protected wiki
00062       page], will be able to see the cached content.
00063     * The key must change if the (original) content changes. This is because
00064       ACLs on some item may change and even if somebody was allowed to see some
00065       revision of some item, it does not implicate that he is allowed to see
00066       any other revision also. There will be no harm if he can see exactly the
00067       same content again, but there could be harm if he could access a revision
00068       with different content.
00069 
00070     If content is supplied, we will calculate and return a hMAC of the content.
00071 
00072     If wikiname, itemname, attachname is given, we don't touch the content (nor do
00073     we read it ourselves from the attachment file), but we just calculate a key
00074     from the given metadata values and some metadata we get from the filesystem.
00075 
00076     Hint: if you need multiple cache objects for the same source content (e.g.
00077           thumbnails of different sizes for the same image), calculate the key
00078           only once and then add some different prefixes to it to get the final
00079           cache keys.
00080 
00081     @param request: the request object
00082     @param wikiname: the name of the wiki (if not given, will be read from cfg)
00083     @param itemname: the name of the page
00084     @param attachname: the filename of the attachment
00085     @param content: content data as unicode object (e.g. for page content or
00086                     parser section content)
00087     @param secret: secret for hMAC calculation (default: use secret from cfg)
00088     """
00089     if secret is None:
00090         secret = request.cfg.secrets['action/cache']
00091     if content:
00092         hmac_data = content
00093     elif itemname is not None and attachname is not None:
00094         wikiname = wikiname or request.cfg.interwikiname or request.cfg.siteid
00095         fuid = filesys.fuid(AttachFile.getFilename(request, itemname, attachname))
00096         hmac_data = u''.join([wikiname, itemname, attachname, repr(fuid)])
00097     else:
00098         raise AssertionError('cache_key called with unsupported parameters')
00099 
00100     hmac_data = hmac_data.encode('utf-8')
00101     key = hmac_new(secret, hmac_data).hexdigest()
00102     return key
00103 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.cache.put (   request,
  key,
  data,
  filename = None,
  content_type = None,
  content_disposition = None,
  content_length = None,
  last_modified = None,
  original = None 
)
Put an object into the cache to send it with cache action later.

@param request: the request object
@param key: non-guessable key into cache (str)
@param data: content data (str or open file-like obj)
@param filename: filename for content-disposition header and for autodetecting
                 content_type (unicode, default: None)
@param content_type: content-type header value (str, default: autodetect from filename)
@param content_disposition: type for content-disposition header (str, default: None)
@param content_length: data length for content-length header (int, default: autodetect)
@param last_modified: last modified timestamp (int, default: autodetect)
@param original: location of original object (default: None) - this is just written to
                 the metadata cache "as is" and could be used for cache cleanup,
                 use (wikiname, itemname, attachname or None))

Definition at line 110 of file cache.py.

00110 
00111         original=None):
00112     """
00113     Put an object into the cache to send it with cache action later.
00114 
00115     @param request: the request object
00116     @param key: non-guessable key into cache (str)
00117     @param data: content data (str or open file-like obj)
00118     @param filename: filename for content-disposition header and for autodetecting
00119                      content_type (unicode, default: None)
00120     @param content_type: content-type header value (str, default: autodetect from filename)
00121     @param content_disposition: type for content-disposition header (str, default: None)
00122     @param content_length: data length for content-length header (int, default: autodetect)
00123     @param last_modified: last modified timestamp (int, default: autodetect)
00124     @param original: location of original object (default: None) - this is just written to
00125                      the metadata cache "as is" and could be used for cache cleanup,
00126                      use (wikiname, itemname, attachname or None))
00127     """
00128     import os.path
00129     from MoinMoin.util import timefuncs
00130 
00131     if filename:
00132         # make sure we just have a simple filename (without path)
00133         filename = os.path.basename(filename)
00134 
00135         if content_type is None:
00136             # try autodetect
00137             mt, enc = mimetypes.guess_type(filename)
00138             if mt:
00139                 content_type = mt
00140 
00141     if content_type is None:
00142         content_type = 'application/octet-stream'
00143 
00144     data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
00145     data_cache.update(data)
00146     content_length = content_length or data_cache.size()
00147     last_modified = last_modified or data_cache.mtime()
00148 
00149     httpdate_last_modified = timefuncs.formathttpdate(int(last_modified))
00150     headers = [('Content-Type', content_type),
00151                ('Last-Modified', httpdate_last_modified),
00152                ('Content-Length', content_length),
00153               ]
00154     if content_disposition and filename:
00155         # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
00156         # There is no solution that is compatible to IE except stripping non-ascii chars
00157         filename = filename.encode(config.charset)
00158         headers.append(('Content-Disposition', '%s; filename="%s"' % (content_disposition, filename)))
00159 
00160     meta_cache = caching.CacheEntry(request, cache_arena, key+'.meta', cache_scope, do_locking=do_locking, use_pickle=True)
00161     meta_cache.update({
00162         'httpdate_last_modified': httpdate_last_modified,
00163         'last_modified': last_modified,
00164         'headers': headers,
00165         'original': original,
00166     })
00167 

Here is the caller graph for this function:

def MoinMoin.action.cache.remove (   request,
  key 
)
delete headers/data cache for key 

Definition at line 189 of file cache.py.

00189 
00190 def remove(request, key):
00191     """ delete headers/data cache for key """
00192     meta_cache = caching.CacheEntry(request, cache_arena, key+'.meta', cache_scope, do_locking=do_locking, use_pickle=True)
00193     meta_cache.remove()
00194     data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
00195     data_cache.remove()
00196 

Here is the caller graph for this function:

def MoinMoin.action.cache.url (   request,
  key,
  do = 'get' 
)
return URL for the object cached for key 

Definition at line 197 of file cache.py.

00197 
00198 def url(request, key, do='get'):
00199     """ return URL for the object cached for key """
00200     return request.href(action=action_name, do=do, key=key)

Here is the caller graph for this function:


Variable Documentation

tuple MoinMoin.action.cache.action_name = __name__.split('.')

Definition at line 42 of file cache.py.

string MoinMoin.action.cache.cache_arena = 'sendcache'

Definition at line 45 of file cache.py.

Definition at line 50 of file cache.py.

Definition at line 52 of file cache.py.

Definition at line 31 of file cache.py.