Merge branch 'encukou'
[zzz-pokedex.git] / pokedex / db / markdown.py
index 928c3d4..257c8de 100644 (file)
@@ -56,9 +56,16 @@ class MarkdownString(object):
         """
         return self.source_text
 
+def _markdownify_effect_text(move, effect_text):
+    effect_text = effect_text.replace(
+        u'$effect_chance',
+        unicode(move.effect_chance),
+    )
+
+    return MarkdownString(effect_text)
 
 class MoveEffectProperty(object):
-    """Property that wraps a move effect.  Used like this:
+    """Property that wraps move effects.  Used like this:
 
         MoveClass.effect = MoveEffectProperty('effect')
 
@@ -67,19 +74,27 @@ class MoveEffectProperty(object):
 
     This class also performs simple substitution on the effect, replacing
     `$effect_chance` with the move's actual effect chance.
+
+    Use `MoveEffectPropertyMap` for dict-like association proxies.
     """
 
     def __init__(self, effect_column):
         self.effect_column = effect_column
 
-    def __get__(self, move, move_class):
-        effect_text = getattr(move.move_effect, self.effect_column)
-        effect_text = effect_text.replace(
-            u'$effect_chance',
-            unicode(move.effect_chance),
-        )
+    def __get__(self, obj, cls):
+        prop = getattr(obj.move_effect, self.effect_column)
+        return _markdownify_effect_text(obj, prop)
 
-        return MarkdownString(effect_text)
+class MoveEffectPropertyMap(MoveEffectProperty):
+    """Similar to `MoveEffectProperty`, but works on dict-like association
+    proxies.
+    """
+    def __get__(self, obj, cls):
+        prop = getattr(obj.move_effect, self.effect_column)
+        newdict = dict(prop)
+        for key in newdict:
+            newdict[key] = _markdownify_effect_text(obj, newdict[key])
+        return newdict
 
 class MarkdownColumn(sqlalchemy.types.TypeDecorator):
     """Generic SQLAlchemy column type for Markdown text.
@@ -91,6 +106,9 @@ class MarkdownColumn(sqlalchemy.types.TypeDecorator):
     impl = sqlalchemy.types.Unicode
 
     def process_bind_param(self, value, dialect):
+        if value is None:
+            return None
+
         if not isinstance(value, basestring):
             # Can't assign, e.g., MarkdownString objects yet
             raise NotImplementedError
@@ -98,4 +116,7 @@ class MarkdownColumn(sqlalchemy.types.TypeDecorator):
         return unicode(value)
 
     def process_result_value(self, value, dialect):
+        if value is None:
+            return None
+
         return MarkdownString(value)