Test coverage report: markupmirror.fields

# markupmirror.fields: 100 total statements, 51.7% covered

Generated: Wed 2012-04-11 05:19 CDT

Source file: /home/buechler/Sites/django-markupmirror/markupmirror/fields.py

Stats: 45 executed, 42 missed, 13 excluded, 132 ignored

1. `from django.core.exceptions import ImproperlyConfigured`
2. `from django.db import models`
3. `from django.utils.html import escape`
4. `from django.utils.safestring import mark_safe`
5. ``
6. `from markupmirror import widgets`
7. `from markupmirror.markup.base import markup_pool`
8. ``
9. ``
10. `# suffixes for rendered and markup_type fields`
11. `_rendered_field_name = lambda name: '%s_rendered' % name`
12. `_markup_type_field_name = lambda name: '%s_markup_type' % name`
13. ``
14. ``
15. `class Markup(object):`
16. `"""Wrapper class for markup content output.`
17. ``
18. `Stores the names of the associated field, the rendered field and the`
19. `markup_type field to make assignment possible.`
20. ``
21. `"""`
22. `def __init__(self, instance, field_name,`
23. `rendered_field_name, markup_type_field_name):`
24. `self.instance = instance`
25. `self.field_name = field_name`
26. `self.rendered_field_name = rendered_field_name`
27. `self.markup_type_field_name = markup_type_field_name`
28. ``
29. `@property`
30. `def raw(self):`
31. `return self.instance.__dict__[self.field_name]`
32. ``
33. `@raw.setter`
34. `def raw(self, value):`
35. `return setattr(self.instance, self.field_name, value)`
36. ``
37. `@property`
38. `def markup_type(self):`
39. `return self.instance.__dict__[self.markup_type_field_name]`
40. ``
41. `@markup_type.setter`
42. `def markup_type(self, value):`
43. `return setattr(self.instance, self.markup_type_field_name, value)`
44. ``
45. `@property`
46. `def rendered(self):`
47. `return getattr(self.instance, self.rendered_field_name)`
48. ``
49. `def __unicode__(self):`
50. `"""Allows display via templates to work without safe filter."""`
51. `return mark_safe(self.rendered)`
52. ``
53. ``
54. `class MarkupMirrorFieldDescriptor(object):`
55. `"""Descriptor class for field functionality."""`
56. ``
57. `def __init__(self, field):`
58. `self.field = field`
59. `self.rendered_field_name = _rendered_field_name(self.field.name)`
60. `self.markup_type_field_name = _markup_type_field_name(self.field.name)`
61. ``
62. `def __get__(self, instance, owner):`
63. `if instance is None:`
64. `raise AttributeError("Can only be accessed via an instance.")`
65. `markup = instance.__dict__[self.field.name]`
66. `if markup is None:`
67. `return None`
68. `return Markup(instance, self.field.name,`
69. `self.rendered_field_name, self.markup_type_field_name)`
70. ``
71. `def __set__(self, obj, value):`
72. `if isinstance(value, Markup):`
73. `obj.__dict__[self.field.name] = value.raw`
74. `setattr(obj, self.rendered_field_name, value.rendered)`
75. `setattr(obj, self.markup_type_field_name, value.markup_type)`
76. `else:`
77. `obj.__dict__[self.field.name] = value`
78. ``
79. ``
80. `class MarkupMirrorField(models.TextField):`
81. `"""Field to store markup content.`
82. ``
83. `MarkupMirrorField adds three fields to the model it is used in.`
84. ``
85. `* One field for the raw markup content.`
86. `* One field for the rendered HTML content.`
87. `* One field that specifies the markup type.`
88. ``
89. `"""`
90. `def __init__(self, verbose_name=None, name=None,`
91. `markup_type=None, default_markup_type=None,`
92. `escape_html=False, **kwargs):`
93. `if markup_type and default_markup_type:`
94. `raise ImproperlyConfigured(`
95. `"Cannot specify both markup_type and default_markup_type")`
96. ``
97. `self.default_markup_type = markup_type or default_markup_type`
98. `self.markup_type_editable = markup_type is None`
99. `self.escape_html = escape_html`
100. ``
101. `if (self.default_markup_type and`
102. `self.default_markup_type not in markup_pool):`
103. `raise ImproperlyConfigured(`
104. `"Invalid default_markup_type for field '%r', "`
105. `"available types: %s" % (`
106. `name or verbose_name,`
107. `', '.join(sorted(markup_pool.markups.keys()))))`
108. ``
109. `# for South FakeORM compatibility: the frozen version of a`
110. `# MarkupMirrorField can't try to add a _rendered field, because the`
111. `# _rendered field itself is frozen as well. See introspection`
112. `# rules below.`
113. `self.rendered_field = not kwargs.pop('rendered_field', False)`
114. ``
115. `super(MarkupMirrorField, self).__init__(verbose_name, name, **kwargs)`
116. ``
117. `def contribute_to_class(self, cls, name):`
118. `"""Adds two additional fields for rendered HTML content and markup type`
119. `to the model.`
120. ``
121. `"""`
122. `if not cls._meta.abstract:`
123. `# markup_type`
124. `choices = [(markup_type, markup.title)`
125. `for markup_type, markup in markup_pool.markups.items()]`
126. `markup_type_field = models.CharField(`
127. `choices=choices, max_length=30,`
128. `default=self.default_markup_type, blank=self.blank,`
129. `editable=self.markup_type_editable)`
130. `markup_type_field.creation_counter = self.creation_counter + 1`
131. ``
132. `# rendered`
133. `rendered_field = models.TextField(`
134. `editable=False, blank=True, null=True)`
135. `rendered_field.creation_counter = self.creation_counter + 2`
136. ``
137. `# add fields to class`
138. `cls.add_to_class(_markup_type_field_name(name), markup_type_field)`
139. `cls.add_to_class(_rendered_field_name(name), rendered_field)`
140. ``
141. `super(MarkupMirrorField, self).contribute_to_class(cls, name)`
142. ``
143. `# use MarkupMirrorFieldDescriptor to access this field`
144. `setattr(cls, self.name, MarkupMirrorFieldDescriptor(self))`
145. ``
146. `def pre_save(self, model_instance, add):`
147. `value = super(MarkupMirrorField, self).pre_save(model_instance, add)`
148. ``
149. `# check for valid markup type`
150. `if value.markup_type not in markup_pool:`
151. `raise ValueError(`
152. `'Invalid markup type (%s), available types: %s' % (`
153. `value.markup_type,`
154. `', '.join(sorted(markup_pool.markups.keys()))))`
155. ``
156. `# escape HTML`
157. `if self.escape_html:`
158. `raw = escape(value.raw)`
159. `else:`
160. `raw = value.raw`
161. ``
162. `rendered = markup_pool[value.markup_type](raw)`
163. `setattr(model_instance, _rendered_field_name(self.attname), rendered)`
164. `return value.raw`
165. ``
166. `def get_prep_value(self, value):`
167. `if isinstance(value, Markup):`
168. `return value.raw`
169. `else:`
170. `return value`
171. ``
172. `def value_to_string(self, obj):`
173. `value = self._get_val_from_obj(obj)`
174. `return value.raw`
175. ``
176. `def formfield(self, **kwargs):`
177. `"""Adds attributes necessary for CodeMirror initialization to the`
178. `field's widget.`
179. ``
180. `The class "item-markupmirror" is used to identify textareas that should`
181. `be enhanced with the editor.`
182. ``
183. `The ``data-mode`` and ``data-markuptype`` attributes depend on a`
184. `selected ``default_markup_type``. If a field does not have a default`
185. `markup type selected, the attributes will be added in the widgets'`
186. ```render`` method by accessing the ``markup_type`` property of the`
187. `markup content wrapper ``markupmirror.fields.Markup``.`
188. ``
189. `"""`
190. `widget_attrs = {`
191. `'class': 'item-markupmirror',`
192. `}`
193. `if (self.default_markup_type and`
194. `self.default_markup_type in markup_pool):`
195. `widget_attrs['data-mode'] = markup_pool[`
196. `self.default_markup_type].codemirror_mode`
197. `widget_attrs['data-markuptype'] = self.default_markup_type`
198. ``
199. `defaults = {`
200. `'widget': widgets.MarkupMirrorTextarea(attrs=widget_attrs),`
201. `}`
202. ``
203. `defaults.update(kwargs)`
204. `return super(MarkupMirrorField, self).formfield(**defaults)`
205. ``
206. ``
207. `__all__ = ('Markup', 'MarkupMirrorFieldDescriptor', 'MarkupMirrorField')`
208. ``
209. ``
210. `# register MarkupMirrorField to use the custom widget in the Admin`
211. `from django.contrib.admin.options import FORMFIELD_FOR_DBFIELD_DEFAULTS`
212. ``
213. `FORMFIELD_FOR_DBFIELD_DEFAULTS[MarkupMirrorField] = {`
214. `'widget': widgets.AdminMarkupMirrorTextareaWidget,`
215. `}`
216. ``
217. ``
218. `# allow South to handle MarkupMirrorField smoothly`
219. `try:`
220. `from south.modelsinspector import add_introspection_rules`
221. `# For a normal MarkupMirrorField, the add_rendered_field attribute is`
222. `# always True, which means no_rendered_field arg will always be`
223. `# True in a frozen MarkupMirrorField, which is what we want.`
224. `add_introspection_rules(`
225. `rules=[`
226. `((MarkupMirrorField,), [], {`
227. `'rendered_field': ['rendered_field', {}],`
228. `})`
229. `],`
230. `patterns=['markupmirror\.fields\.MarkupMirrorField'])`
231. `except ImportError:`
232. `pass`