1 ## This file is part of Crapvine.
3 ## Copyright (C) 2007 Andrew Sayman <lorien420@myrealbox.com>
5 ## Crapvine is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or
8 ## (at your option) any later version.
10 ## Crapvine is distributed in the hope that it will be useful,
11 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ## GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with this program. If not, see <http://www.gnu.org/licenses/>.
18 from __future__
import with_statement
20 from xml
.sax
.saxutils
import quoteattr
, unescape
21 from xml
.sax
import sax2exts
22 from xml
.sax
.handler
import feature_namespaces
, property_lexical_handler
23 from dateutil
.parser
import parse
24 from datetime
import datetime
26 from attribute
import AttributeBuilder
, classmaker
28 class AttributeReader
:
29 def __init__(self
, attrs
):
32 def boolean(self
, name
, default
=False):
33 if self
.attrs
.has_key(name
):
34 bool_val
= self
.attrs
.get(name
)
37 elif bool_val
== 'no':
40 raise AttributeError('Boolean xml field set to invalid value |%s|' % (bool_val
))
42 def b(self
, name
, default
=False):
43 return self
.boolean(name
, default
)
45 def text(self
, name
, default
=''):
46 if self
.attrs
.has_key(name
):
47 return self
.attrs
.get(name
)
49 def t(self
, name
, default
=''):
50 return self
.text(name
, default
)
52 def number_as_text(self
, name
, default
='0'):
53 # Should eventually verify that it's a number
54 return text(name
, default
)
55 def nat(self
, name
, default
='0'):
56 return self
.number_as_text(name
, default
)
58 def date(self
, name
, default
='unknown'):
59 # Should eventually parse the date?
60 return text(name
, default
)
61 def d(self
, name
, default
='unknown'):
62 return self
.date(name
, default
)
64 class Attributed(object):
65 __metaclass__
= AttributeBuilder
66 def read_attributes(self
, attrs
):
67 r
= AttributeReader(attrs
)
68 for attr
in attrs
.keys():
69 if hasattr(self
, attr
):
70 setattr(self
, attr
, unescape(attrs
.get(attr
)))
72 def __attr_default(self
, name
):
73 return getattr(self
.__class
__, name
).default
== getattr(self
, name
)
75 def __get_attrs_names(self
, attrs
):
76 list = getattr(self
, attrs
, [])
79 if isinstance(elem
, tuple):
80 ret_list
.append(elem
[0])
84 def __get_required_attrs(self
):
85 return self
.__get
_attrs
_names
('required_attrs')
86 def __get_text_attrs(self
):
87 return self
.__get
_attrs
_names
('text_attrs')
88 def __get_number_as_text_attrs(self
):
89 return self
.__get
_attrs
_names
('number_as_text_attrs')
90 def __get_date_attrs(self
):
91 return self
.__get
_attrs
_names
('date_attrs')
92 def __get_bool_attrs(self
):
93 return self
.__get
_attrs
_names
('bool_attrs')
95 def get_attrs_xml(self
):
97 attrs_strs
.extend(['%s=%s' % (name
, quoteattr(self
[name
])) for name
in self
.__get
_required
_attrs
() if not self
.__attr
_default
(name
)])
98 attrs_strs
.extend(['%s=%s' % (name
, quoteattr(self
[name
])) for name
in self
.__get
_text
_attrs
() if not self
.__attr
_default
(name
)])
99 attrs_strs
.extend(['%s=%s' % (name
, quoteattr(getattr(self
, name
))) for name
in self
.__get
_number
_as
_text
_attrs
() if not self
.__attr
_default
(name
)])
100 attrs_strs
.extend(['%s=%s' % (name
, quoteattr(str(self
[name
]))) for name
in self
.__get
_date
_attrs
() if not self
.__attr
_default
(name
)])
101 for bool_attr
in self
.__get
_bool
_attrs
():
102 if not self
.__attr
_default
(bool_attr
):
103 my_bool
= 'yes' if self
[bool_attr
] else 'no'
104 attrs_strs
.append('%s="%s"' % (bool_attr
, my_bool
))
105 return ' '.join(attrs_strs
)
107 def __setitem__(self
, name
, value
):
108 return setattr(self
, name
, value
)
109 def __getitem__(self
, name
):
110 return getattr(self
, name
)
112 class AttributedListModel(Attributed
, gtk
.GenericTreeModel
):
113 __metaclass__
= classmaker()
116 Attributed
.__init
__(self
)
117 gtk
.GenericTreeModel
.__init
__(self
)
118 def get_item(self
, index
):
119 return self
.list[index
]
120 def get_item_from_path(self
, path
):
121 return self
.list[path
[0]]
122 def on_get_flags(self
):
123 return gtk
.TREE_MODEL_LIST_ONLY
124 def on_get_n_columns(self
):
125 return len(self
.column_attrs
)
126 def on_get_column_type(self
, index
):
127 return self
.column_attr_types
[index
]
128 def on_get_path(self
, iter):
129 if len(self
.list) == 0:
132 def on_get_iter(self
, path
):
133 if len(self
.list) == 0:
136 def on_get_value(self
, index
, column
):
137 if len(self
.list) == 0:
139 list = self
.list[index
]
140 return list[self
.column_attrs
[column
]]
141 def on_iter_next(self
, index
):
142 if index
>= (len(self
.list) - 1):
145 def on_iter_children(self
, node
):
147 def on_iter_has_child(self
, node
):
149 def on_iter_n_children(self
, iter):
152 return len(self
.list)
153 def on_iter_nth_child(self
, parent
, n
):
162 def on_iter_parent(self
, node
):
168 self
.chronicle_loader
= None
170 def load_from_file(self
, filename
):
171 from chronicle_loader
import ChronicleLoader
172 self
.filename
= filename
173 self
.chronicle_loader
= ChronicleLoader()
175 parser
= sax2exts
.make_parser()
176 parser
.setFeature(feature_namespaces
, 0)
177 parser
.setContentHandler(self
.chronicle_loader
)
178 parser
.setProperty(property_lexical_handler
, self
.chronicle_loader
)
180 parser
.parse(self
.filename
)
182 def save_contents_to_file(self
, filename
):
183 all_character_xml
= [c
.get_xml(' ') for c
in self
.chronicle_loader
.vampires
.values()]
184 out
= ['<?xml version="1.0"?>',
185 '<grapevine version="3">']
186 out
.extend(all_character_xml
)
187 out
.append('</grapevine>')
188 with
file(filename
, 'w') as f
:
189 f
.write("\n".join(out
))