@@ -17,7 +17,7 @@ from itertools import ifilter, izip, tee, product | |||||
from operator import attrgetter | from operator import attrgetter | ||||
class Tag(object): | |||||
class Tag(Expando): | |||||
""" | """ | ||||
A simple object that represents a tag. | A simple object that represents a tag. | ||||
""" | """ | ||||
@@ -113,7 +113,7 @@ class TaggerPlugin(Plugin): | |||||
tags[tagname] = tag | tags[tagname] = tag | ||||
tag.resources.append(resource) | tag.resources.append(resource) | ||||
add_method(Node, | add_method(Node, | ||||
'walk_resources_tagged_with_%s' % tag, | |||||
'walk_resources_tagged_with_%s' % tagname, | |||||
walk_resources_tagged_with, | walk_resources_tagged_with, | ||||
tag=tag) | tag=tag) | ||||
else: | else: | ||||
@@ -121,7 +121,19 @@ class TaggerPlugin(Plugin): | |||||
if not hasattr(resource, 'tags'): | if not hasattr(resource, 'tags'): | ||||
setattr(resource, 'tags', []) | setattr(resource, 'tags', []) | ||||
resource.tags.append(tags[tagname]) | resource.tags.append(tags[tagname]) | ||||
try: | |||||
tag_meta = self.site.config.tagger.tags.to_dict() | |||||
except AttributeError: | |||||
tag_meta = {} | |||||
for tagname, meta in tag_meta.iteritems(): | |||||
# Don't allow name and resources in meta | |||||
if 'resources' in meta: | |||||
del(meta['resources']) | |||||
if 'name' in meta: | |||||
del(meta['name']) | |||||
if tagname in tags: | |||||
tags[tagname].update(meta) | |||||
self.site.tagger = Expando(dict(tags=tags)) | self.site.tagger = Expando(dict(tags=tags)) | ||||
def site_complete(self): | def site_complete(self): | ||||
@@ -38,7 +38,7 @@ class Expando(object): | |||||
for key, value in d.items(): | for key, value in d.items(): | ||||
self.set_expando(key, value) | self.set_expando(key, value) | ||||
elif isinstance(d, Expando): | elif isinstance(d, Expando): | ||||
self.update(d.__dict__) | |||||
self.update(d.to_dict()) | |||||
def set_expando(self, key, value): | def set_expando(self, key, value): | ||||
""" | """ | ||||
@@ -47,6 +47,7 @@ class Expando(object): | |||||
""" | """ | ||||
setattr(self, str(key).encode('utf-8'), self.transform(value)) | setattr(self, str(key).encode('utf-8'), self.transform(value)) | ||||
def transform(self, primitive): | def transform(self, primitive): | ||||
""" | """ | ||||
Creates an expando object, a sequence of expando objects or just | Creates an expando object, a sequence of expando objects or just | ||||
@@ -60,19 +61,25 @@ class Expando(object): | |||||
else: | else: | ||||
return primitive | return primitive | ||||
def __repr__(self): | |||||
return str(self.to_dict()) | |||||
def to_dict(self): | def to_dict(self): | ||||
""" | """ | ||||
Reverse transform an expando to dict | Reverse transform an expando to dict | ||||
""" | """ | ||||
result = {} | |||||
d = self.__dict__ | d = self.__dict__ | ||||
for k, v in d.iteritems(): | |||||
for k, v in d.items(): | |||||
if isinstance(v, Expando): | if isinstance(v, Expando): | ||||
d[k] = v.to_dict() | |||||
result[k] = v.to_dict() | |||||
elif isinstance(v, (tuple, list, set, frozenset)): | elif isinstance(v, (tuple, list, set, frozenset)): | ||||
seq = type(v) | seq = type(v) | ||||
d[k] = seq(item.to_dict() if isinstance(item, Expando) | |||||
result[k] = seq(item.to_dict() if isinstance(item, Expando) | |||||
else item for item in v) | else item for item in v) | ||||
return d | |||||
else: | |||||
result[k] = v | |||||
return result | |||||
class Context(object): | class Context(object): | ||||
@@ -32,7 +32,7 @@ class TestTagger(object): | |||||
gen = Generator(self.s) | gen = Generator(self.s) | ||||
gen.load_site_if_needed() | gen.load_site_if_needed() | ||||
gen.generate_all() | gen.generate_all() | ||||
assert hasattr(self.s, 'tagger') | assert hasattr(self.s, 'tagger') | ||||
assert hasattr(self.s.tagger, 'tags') | assert hasattr(self.s.tagger, 'tags') | ||||
assert self.s.tagger.tags | assert self.s.tagger.tags | ||||
@@ -43,7 +43,7 @@ class TestTagger(object): | |||||
for tag in ['sad', 'happy', 'angry', 'thoughts', 'events']: | for tag in ['sad', 'happy', 'angry', 'thoughts', 'events']: | ||||
assert tag in tags | assert tag in tags | ||||
sad_posts = [post.name for post in tags['sad'].resources] | |||||
sad_posts = [post.name for post in tags['sad']['resources']] | |||||
assert len(sad_posts) == 2 | assert len(sad_posts) == 2 | ||||
assert "sad-post.html" in sad_posts | assert "sad-post.html" in sad_posts | ||||
assert "another-sad-post.html" in sad_posts | assert "another-sad-post.html" in sad_posts | ||||
@@ -119,33 +119,39 @@ class TestTagger(object): | |||||
def test_tagger_metadata(self): | def test_tagger_metadata(self): | ||||
conf = { | conf = { | ||||
"sad" : { | |||||
"emotions": ["Dissappointed", "Lost"] | |||||
}, | |||||
"Angry": { | |||||
"emotions": ["Irritated", "Annoyed", "Disgusted"] | |||||
"tagger":{ | |||||
"tags": { | |||||
"sad" : { | |||||
"emotions": ["Dissappointed", "Lost"] | |||||
}, | |||||
"angry": { | |||||
"emotions": ["Irritated", "Annoyed", "Disgusted"] | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
self.s.config.tagger.meta = Expando(conf) | |||||
gen = Generator(self.s) | |||||
s = Site(TEST_SITE) | |||||
s.config.update(conf) | |||||
gen = Generator(s) | |||||
gen.load_site_if_needed() | gen.load_site_if_needed() | ||||
gen.generate_all() | gen.generate_all() | ||||
assert hasattr(self.s, 'tagger') | |||||
assert hasattr(self.s.tagger, 'tags') | |||||
assert self.s.tagger.tags | |||||
tags = self.s.tagger.tags.to_dict() | |||||
sad_tag = tags["sad"] | |||||
assert sad_tag | |||||
assert hasattr(s, 'tagger') | |||||
assert hasattr(s.tagger, 'tags') | |||||
assert s.tagger.tags | |||||
tags = s.tagger.tags | |||||
sad_tag = tags.sad | |||||
assert hasattr(sad_tag, "emotions") | assert hasattr(sad_tag, "emotions") | ||||
assert sad_tag.emotions == self.s.config.tagger.meta.sad.emotions | |||||
happy_tag = tags["happy"] | |||||
assert happy_tag | |||||
assert hasattr(happy_tag, "emotions") | |||||
assert happy_tag.emotions == self.s.config.tagger.meta.happy.emotions | |||||
assert sad_tag.emotions == s.config.tagger.tags.sad.emotions | |||||
assert hasattr(tags, "angry") | |||||
angry_tag = tags.angry | |||||
assert angry_tag | |||||
assert hasattr(angry_tag, "emotions") | |||||
assert angry_tag.emotions == s.config.tagger.tags.angry.emotions | |||||
for tagname in ['angry', 'thoughts', 'events']: | |||||
tag = tags[tagname] | |||||
for tagname in ['happy', 'thoughts', 'events']: | |||||
tag = getattr(tags, tagname) | |||||
assert tag | assert tag | ||||
assert not hasattr(tag, "emotions") | assert not hasattr(tag, "emotions") |