def paginate(lst, ipp, func=lambda x: x, salt=None, orphans=0): """paginate(lst, ipp, func=lambda x: x, salt=None, orphans=0) Yields a triple ((next, current, previous), list of entries, has changed) of a paginated entrylist. It will first filter by the specified function, then split the ist into several sublists and check wether the list or an entry has changed. :param lst: the entrylist containing Entry instances. :param ipp: items per page :param func: filter list of entries by this function :param salt: uses as additional identifier in memoize :param orphans: avoid N orphans on last page >>> for x, values, _, paginate(entryrange(20), 6, orphans=2): ... print x, values (None, 0, 1), [entries 1..6] (0, 1, 2), [entries 7..12] (1, 2, None), [entries 12..20]""" # apply filter function and prepare pagination with ipp res = filter(func, lst) res = list(batch(res, ipp)) if len(res) >= 2 and len(res[-1]) <= orphans: res[-2].extend(res[-1]) res.pop(-1) j = len(res) for i, entries in enumerate(res): i += 1 next = None if i == 1 else i-1 curr = i prev = None if i >= j else i+1 # get caller, so we can set a unique and meaningful hash-key frame = log.findCaller() if salt is None: hkey = '%s:%s-hash-%i' % (basename(frame[0]), frame[2], i) else: hkey = '%s:%s-hash-%s-%i' % (basename(frame[0]), frame[2], salt, i) # calculating hash value and retrieve memoized value hv = md5(*entries, attr=lambda o: o.md5) rv = cache.memoize(hkey) if rv == hv: # check if an Entry-instance has changed if any(filter(lambda e: e.has_changed, entries)): has_changed = True else: has_changed = False else: # save new value for next run cache.memoize(hkey, hv) has_changed = True yield (next, curr, prev), entries, has_changed
def paginate(lst, ipp, func=lambda x: x, salt=None, orphans=0): """paginate(lst, ipp, func=lambda x: x, salt=None, orphans=0) Yields a triple ((next, current, previous), list of entries, has changed) of a paginated entrylist. It will first filter by the specified function, then split the ist into several sublists and check wether the list or an entry has changed. :param lst: the entrylist containing Entry instances. :param ipp: items per page :param func: filter list of entries by this function :param salt: uses as additional identifier in memoize :param orphans: avoid N orphans on last page >>> for x, values, _, paginate(entryrange(20), 6, orphans=2): ... print x, values (None, 0, 1), [entries 1..6] (0, 1, 2), [entries 7..12] (1, 2, None), [entries 12..20]""" # apply filter function and prepare pagination with ipp res = filter(func, lst) res = list(batch(res, ipp)) if len(res) >= 2 and len(res[-1]) <= orphans: res[-2].extend(res[-1]) res.pop(-1) j = len(res) for i, entries in enumerate(res): i += 1 next = None if i == 1 else i - 1 curr = i prev = None if i >= j else i + 1 # get caller, so we can set a unique and meaningful hash-key frame = log.findCaller() if salt is None: hkey = '%s:%s-hash-%i' % (basename(frame[0]), frame[2], i) else: hkey = '%s:%s-hash-%s-%i' % (basename(frame[0]), frame[2], salt, i) # calculating hash value and retrieve memoized value hv = md5(*entries, attr=lambda o: o.md5) rv = cache.memoize(hkey) if rv == hv: # check if an Entry-instance has changed if any(filter(lambda e: e.has_changed, entries)): has_changed = True else: has_changed = False else: # save new value for next run cache.memoize(hkey, hv) has_changed = True yield (next, curr, prev), entries, has_changed
def load(*entries): """Initialize references, load previous state.""" global __orig_refs, __seen_refs, __entry_map __seen_refs = defaultdict(set) __orig_refs = cache.memoize('references') or defaultdict(set) __entry_map = dict((hash(entry), entry) for entry in chain(*entries))
def memoize(key, value=None): """Persistent memory for small values, set and get in a single function. :param key: get value saved to key, if key does not exist, return None. :param value: set key to value """ return cache.memoize(key, value)
def memoize(key, value=None): """Persistent memory for small values, set and get in a single function. If you set a value, it returns whether the new value is different to the previous. >>> memoize("Foo", 1) False >>> memoize("Foo", 1) True >>> memoize("Foo", 2) False >>> memoize("Foo") 2 :param key: get value saved to key, if key does not exist, return None. :param value: set key to value """ return cache.memoize(key, value)
def paginate(lst, ipp, salt="", orphans=0): """paginate(lst, ipp, func=lambda x: x, salt=None, orphans=0) Yields a triple ((next, current, previous), list of entries, has changed) of a paginated entrylist. It will first filter by the specified function, then split the ist into several sublists and check wether the list or an entry has changed. :param lst: the entrylist containing Entry instances. :param ipp: items per page :param salt: uses as additional identifier in memoize :param orphans: avoid N orphans on last page >>> for x, values, _, paginate(entryrange(20), 6, orphans=2): ... print(x, values) (None, 0, 1), [entries 1..6] (0, 1, 2), [entries 7..12] (1, 2, None), [entries 12..20]""" # detect removed or newly added entries modified = cache.memoize('paginate-' + salt, hash(*lst)) # slice into batches res = list(batch(lst, ipp)) if len(res) >= 2 and len(res[-1]) <= orphans: res[-2].extend(res[-1]) res.pop(-1) j = len(res) for i, entries in enumerate(res): i += 1 next = None if i == 1 else i-1 curr = i prev = None if i >= j else i+1 yield (next, curr, prev), entries, modified or any(e.modified for e in entries)
def save(): """Save new references state to disk.""" global __seen_refs cache.memoize('references', __seen_refs)
def memoize(key, value=None): """A shortcut to core.cache.memoize""" return cache.memoize(key, value)