Compare commits
3 Commits
03a122c41f
...
2514fabd38
Author | SHA1 | Date |
---|---|---|
pictuga | 2514fabd38 | |
pictuga | 8cb7002fe6 | |
pictuga | 6966e03bef |
|
@ -626,34 +626,41 @@ class ParserJSON(ParserBase):
|
||||||
return out.replace('\n', '<br/>') if out else out
|
return out.replace('\n', '<br/>') if out else out
|
||||||
|
|
||||||
|
|
||||||
class Uniq(object):
|
def wrap_uniq(wrapper_fn_name):
|
||||||
_map = {}
|
" Wraps the output of the function with the specified function "
|
||||||
_id = None
|
# This is called when parsing "wrap_uniq('wrap_item')"
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def decorator(func):
|
||||||
# check if a wrapper was already created for it
|
# This is called when parsing "@wrap_uniq('wrap_item')"
|
||||||
# if so, reuse it
|
|
||||||
# if not, create a new one
|
|
||||||
# note that the item itself (the tree node) is created beforehands
|
|
||||||
|
|
||||||
tmp_id = cls._gen_id(*args, **kwargs)
|
def wrapped_func(self, *args, **kwargs):
|
||||||
if tmp_id in cls._map:
|
# This is called when the wrapped function is called
|
||||||
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 = 'Item'
|
itemsClass = property(lambda x: Item) # because Item is define below, i.e. afterwards
|
||||||
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),
|
||||||
|
@ -669,10 +676,7 @@ class Feed(object):
|
||||||
self.rule_create(self.rules['items'])
|
self.rule_create(self.rules['items'])
|
||||||
item = self.items[-1]
|
item = self.items[-1]
|
||||||
|
|
||||||
if new is None:
|
for attr in self.itemsClass.dic:
|
||||||
return
|
|
||||||
|
|
||||||
for attr in globals()[self.itemsClass].dic:
|
|
||||||
try:
|
try:
|
||||||
setattr(item, attr, getattr(new, attr))
|
setattr(item, attr, getattr(new, attr))
|
||||||
|
|
||||||
|
@ -683,8 +687,14 @@ 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.wrap_items(self.get_raw('items'))[key]
|
return self.get_raw('items')[key]
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
self[key].remove()
|
self[key].remove()
|
||||||
|
@ -693,7 +703,7 @@ class Feed(object):
|
||||||
return len(self.get_raw('items'))
|
return len(self.get_raw('items'))
|
||||||
|
|
||||||
|
|
||||||
class Item(Uniq):
|
class Item(object):
|
||||||
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):
|
||||||
|
@ -732,8 +742,12 @@ class Item(Uniq):
|
||||||
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 = []
|
||||||
|
@ -761,20 +775,12 @@ 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 ItemXML(Item, ParserXML):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class FeedHTML(Feed, ParserHTML):
|
|
||||||
itemsClass = 'ItemHTML'
|
|
||||||
|
|
||||||
|
|
||||||
class ItemHTML(Item, ParserHTML):
|
class ItemHTML(Item, ParserHTML):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FeedJSON(Feed, ParserJSON):
|
class FeedHTML(Feed, ParserHTML):
|
||||||
itemsClass = 'ItemJSON'
|
itemsClass = ItemHTML
|
||||||
|
|
||||||
|
|
||||||
class ItemJSON(Item, ParserJSON):
|
class ItemJSON(Item, ParserJSON):
|
||||||
|
@ -789,6 +795,9 @@ 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
|
||||||
|
|
Loading…
Reference in New Issue