Compare commits

..

No commits in common. "2514fabd3811311f2c243fd4736da5178d90b29a" and "03a122c41f1018a01aa2f114c6d39a2cb7f3cf8f" have entirely different histories.

1 changed files with 37 additions and 46 deletions

View File

@ -626,41 +626,34 @@ class ParserJSON(ParserBase):
return out.replace('\n', '<br/>') if out else out return out.replace('\n', '<br/>') if out else out
def wrap_uniq(wrapper_fn_name): class Uniq(object):
" Wraps the output of the function with the specified function " _map = {}
# This is called when parsing "wrap_uniq('wrap_item')" _id = None
def decorator(func): def __new__(cls, *args, **kwargs):
# This is called when parsing "@wrap_uniq('wrap_item')" # check if a wrapper was already created for it
# if so, reuse it
# if not, create a new one
# note that the item itself (the tree node) is created beforehands
def wrapped_func(self, *args, **kwargs): tmp_id = cls._gen_id(*args, **kwargs)
# This is called when the wrapped function is called if tmp_id in cls._map:
return cls._map[tmp_id]
output = func(self, *args, **kwargs)
output_id = id(output)
try:
return self._map[output_id]
except (KeyError, AttributeError):
if not hasattr(self, '_map'):
self._map = {}
wrapper_fn = getattr(self, wrapper_fn_name)
obj = wrapper_fn(output)
self._map[output_id] = obj
else:
obj = object.__new__(cls) #, *args, **kwargs)
cls._map[tmp_id] = obj
return obj return obj
return wrapped_func
return decorator
class Feed(object): class Feed(object):
itemsClass = property(lambda x: Item) # because Item is define below, i.e. afterwards itemsClass = 'Item'
dic = ('title', 'desc', 'items') dic = ('title', 'desc', 'items')
def wrap_items(self, items):
itemsClass = globals()[self.itemsClass]
return [itemsClass(x, self.rules, self) for x in items]
title = property( title = property(
lambda f: f.get('title'), lambda f: f.get('title'),
lambda f,x: f.set('title', x), lambda f,x: f.set('title', x),
@ -676,7 +669,10 @@ class Feed(object):
self.rule_create(self.rules['items']) self.rule_create(self.rules['items'])
item = self.items[-1] item = self.items[-1]
for attr in self.itemsClass.dic: if new is None:
return
for attr in globals()[self.itemsClass].dic:
try: try:
setattr(item, attr, getattr(new, attr)) setattr(item, attr, getattr(new, attr))
@ -687,14 +683,8 @@ class Feed(object):
except (IndexError, TypeError): except (IndexError, TypeError):
pass pass
return item
def wrap_item(self, item):
return self.itemsClass(item, self.rules, self)
@wrap_uniq('wrap_item')
def __getitem__(self, key): def __getitem__(self, key):
return self.get_raw('items')[key] return self.wrap_items(self.get_raw('items'))[key]
def __delitem__(self, key): def __delitem__(self, key):
self[key].remove() self[key].remove()
@ -703,7 +693,7 @@ class Feed(object):
return len(self.get_raw('items')) return len(self.get_raw('items'))
class Item(object): class Item(Uniq):
dic = ('title', 'link', 'desc', 'content', 'time', 'updated') dic = ('title', 'link', 'desc', 'content', 'time', 'updated')
def __init__(self, xml=None, rules=None, parent=None): def __init__(self, xml=None, rules=None, parent=None):
@ -742,12 +732,8 @@ class Item(object):
lambda f: f.rmv('item_updated') ) lambda f: f.rmv('item_updated') )
class ItemXML(Item, ParserXML):
pass
class FeedXML(Feed, ParserXML): class FeedXML(Feed, ParserXML):
itemsClass = ItemXML itemsClass = 'ItemXML'
def root_siblings(self): def root_siblings(self):
out = [] out = []
@ -775,12 +761,20 @@ class FeedXML(Feed, ParserXML):
return etree.tostring(self.root.getroottree(), encoding=encoding, method='xml', **k) return etree.tostring(self.root.getroottree(), encoding=encoding, method='xml', **k)
class ItemHTML(Item, ParserHTML): class ItemXML(Item, ParserXML):
pass pass
class FeedHTML(Feed, ParserHTML): class FeedHTML(Feed, ParserHTML):
itemsClass = ItemHTML itemsClass = 'ItemHTML'
class ItemHTML(Item, ParserHTML):
pass
class FeedJSON(Feed, ParserJSON):
itemsClass = 'ItemJSON'
class ItemJSON(Item, ParserJSON): class ItemJSON(Item, ParserJSON):
@ -795,9 +789,6 @@ class ItemJSON(Item, ParserJSON):
cur = cur[node] cur = cur[node]
class FeedJSON(Feed, ParserJSON):
itemsClass = ItemJSON
if __name__ == '__main__': if __name__ == '__main__':
from . import crawler from . import crawler