paul@18 | 1 | # -*- coding: iso-8859-1 -*- |
paul@18 | 2 | """ |
paul@18 | 3 | MoinMoin - MoinRemoteSupport library |
paul@18 | 4 | |
paul@18 | 5 | @copyright: 2011, 2012 by Paul Boddie <paul@boddie.org.uk> |
paul@18 | 6 | @license: GNU GPL (v2 or later), see COPYING.txt for details. |
paul@18 | 7 | """ |
paul@18 | 8 | |
paul@18 | 9 | from MoinMoin.action import cache |
paul@18 | 10 | from MoinMoin import caching |
paul@21 | 11 | import urllib2, time |
paul@18 | 12 | |
paul@18 | 13 | def getCachedResource(request, url, arena, scope, max_cache_age): |
paul@18 | 14 | |
paul@18 | 15 | """ |
paul@18 | 16 | Using the given 'request', return the resource data for the given 'url', |
paul@18 | 17 | accessing a cache entry with the given 'arena' and 'scope' where the data |
paul@18 | 18 | has already been downloaded. The 'max_cache_age' indicates the length in |
paul@18 | 19 | seconds that a cache entry remains valid. |
paul@20 | 20 | |
paul@20 | 21 | If the resource cannot be downloaded and cached, None is returned. |
paul@22 | 22 | Otherwise, the form of the data is as follows: |
paul@22 | 23 | |
paul@22 | 24 | url <newline> content-type-header <newline> content-body |
paul@18 | 25 | """ |
paul@18 | 26 | |
paul@18 | 27 | # See if the URL is cached. |
paul@18 | 28 | |
paul@18 | 29 | cache_key = cache.key(request, content=url) |
paul@18 | 30 | cache_entry = caching.CacheEntry(request, arena, cache_key, scope=scope) |
paul@18 | 31 | |
paul@18 | 32 | # If no entry exists, or if the entry is older than the specified age, |
paul@18 | 33 | # create one with the response from the URL. |
paul@18 | 34 | |
paul@18 | 35 | now = time.time() |
paul@18 | 36 | mtime = cache_entry.mtime() |
paul@18 | 37 | |
paul@18 | 38 | # NOTE: The URL could be checked and the 'If-Modified-Since' header |
paul@18 | 39 | # NOTE: (see MoinMoin.action.pollsistersites) could be checked. |
paul@18 | 40 | |
paul@18 | 41 | if not cache_entry.exists() or now - mtime >= max_cache_age: |
paul@18 | 42 | |
paul@18 | 43 | # Access the remote data source. |
paul@18 | 44 | |
paul@18 | 45 | cache_entry.open(mode="w") |
paul@18 | 46 | |
paul@18 | 47 | try: |
paul@18 | 48 | f = urllib2.urlopen(url) |
paul@18 | 49 | try: |
paul@18 | 50 | cache_entry.write(url + "\n") |
paul@18 | 51 | cache_entry.write((f.headers.get("content-type") or "") + "\n") |
paul@18 | 52 | cache_entry.write(f.read()) |
paul@18 | 53 | finally: |
paul@18 | 54 | cache_entry.close() |
paul@18 | 55 | f.close() |
paul@18 | 56 | |
paul@20 | 57 | # In case of an exception, return None. |
paul@18 | 58 | |
paul@18 | 59 | except IOError: |
paul@18 | 60 | if cache_entry.exists(): |
paul@18 | 61 | cache_entry.remove() |
paul@20 | 62 | return None |
paul@18 | 63 | |
paul@18 | 64 | # Open the cache entry and read it. |
paul@18 | 65 | |
paul@18 | 66 | cache_entry.open() |
paul@18 | 67 | try: |
paul@18 | 68 | return cache_entry.read() |
paul@18 | 69 | finally: |
paul@18 | 70 | cache_entry.close() |
paul@18 | 71 | |
paul@18 | 72 | # vim: tabstop=4 expandtab shiftwidth=4 |