ODFPY  1.2.0
 All Classes Namespaces Files Functions Variables
userfield.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2006-2009 Søren Roug, European Environment Agency
4 #
5 # This is free software. You may redistribute it under the terms
6 # of the Apache license and the GNU General Public License Version
7 # 2 or at your option any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public
15 # License along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 #
18 # Contributor(s): Michael Howitz, gocept gmbh & co. kg
19 #
20 # $Id: userfield.py 447 2008-07-10 20:01:30Z roug $
21 
22 ##
23 # Class to show and manipulate user fields in odf documents.
24 
25 import sys
26 import zipfile
27 
28 from odf.text import UserFieldDecl
29 from odf.namespaces import OFFICENS
30 from odf.opendocument import load
31 import io, sys
32 
33 if sys.version_info.major==3:
34  unicode=str
35 
36 OUTENCODING = "utf-8"
37 
38 
39 # OpenDocument v.1.0 section 6.7.1
40 VALUE_TYPES = {
41  u'float': (OFFICENS, u'value'),
42  u'percentage': (OFFICENS, u'value'),
43  u'currency': (OFFICENS, u'value'),
44  u'date': (OFFICENS, u'date-value'),
45  u'time': (OFFICENS, u'time-value'),
46  u'boolean': (OFFICENS, u'boolean-value'),
47  u'string': (OFFICENS, u'string-value'),
48  }
49 
50 
51 ##
52 # List, view and manipulate user fields.
54 
55  # these attributes can be a filename or a file like object
56  src_file = None
57  dest_file = None
58 
59  ##
60  # Constructor
61  #
62  # @param src open file in binary mode: source document,
63  # or filename as a unicode string, or None for stdin.
64  # @param dest opendile in binary mode: destination document,
65  # or filename as a unicode string, or None for stdout.
66  #
67  def __init__(self, src=None, dest=None):
68  assert(src==None or 'rb' in repr(src) or 'BufferedReader' in repr(src) or 'BytesIO' in repr(src) or type(src)==type(u""))
69  assert(dest==None or 'wb' in repr(dest) or 'BufferedWriter' in repr(dest) or 'BytesIO' in repr(dest) or type(dest)==type(u""))
70  self.src_file = src
71  self.dest_file = dest
72  self.document = None
73 
74  def loaddoc(self):
75  if (sys.version_info.major==3 and (isinstance(self.src_file, str) or (isinstance(self.src_file, io.IOBase)))) or (sys.version_info.major==2 and isinstance(self.src_file, basestring)):
76  # src_file is a filename, check if it is a zip-file
77  if not zipfile.is_zipfile(self.src_file):
78  raise TypeError(u"%s is no odt file." % self.src_file)
79  elif self.src_file is None:
80  # use stdin if no file given
81  self.src_file = sys.stdin
82 
83  self.document = load(self.src_file)
84 
85  def savedoc(self):
86  # write output
87  if self.dest_file is None:
88  # use stdout if no filename given
89  self.document.save(u'-')
90  else:
91  self.document.save(self.dest_file)
92 
93  ##
94  # List (extract) all known user-fields.
95  #
96  # @return list of user-field names as unicode strings.
97  #
98  def list_fields(self):
99  return [x[0] for x in self.list_fields_and_values()]
100 
101  ##
102  # List (extract) user-fields with type and value.
103  #
104  # @param field_names list of field names as unicode strings
105  # to show, or None for all.
106  #
107  # @return list of tuples (<field name>, <field type>, <value>)
108  # as type (unicode string, stringified type, unicode string).
109  #
110  #
111  def list_fields_and_values(self, field_names=None):
112  self.loaddoc()
113  found_fields = []
114  all_fields = self.document.getElementsByType(UserFieldDecl)
115  for f in all_fields:
116  value_type = f.getAttribute(u'valuetype')
117  if value_type == u'string':
118  value = f.getAttribute(u'stringvalue')
119  else:
120  value = f.getAttribute(u'value')
121  field_name = f.getAttribute(u'name')
122 
123  if field_names is None or field_name in field_names:
124  found_fields.append((field_name,
125  value_type,
126  value))
127  return found_fields
128 
129  ##
130  # Extract the contents of given field names from the file.
131  #
132  # @param field_names list of field names as unicode strings
133  #
134  # @return list of field values as unicode strings.
135  #
136  #
137  def list_values(self, field_names):
138  return [x[2] for x in self.list_fields_and_values(field_names)]
139 
140  ##
141  # Extract the contents of this field from the file.
142  # @param field_name unicode string: name of a field
143  # @return field value as a unicode string or None if field does not exist.
144  #
145  #
146  def get(self, field_name):
147  assert(type(field_name)==type(u""))
148  values = self.list_values([field_name])
149  if not values:
150  return None
151  return values[0]
152 
153  ##
154  # Extract the type and contents of this field from the file.
155  # @param field_name unicode string: name of a field
156  # @return tuple (<type>, <field-value>) as a pair of unicode strings
157  # or None if field does not exist.
158  #
159  #
160  def get_type_and_value(self, field_name):
161  assert(type(field_name)==type(u""))
162  fields = self.list_fields_and_values([field_name])
163  if not fields:
164  return None
165  field_name, value_type, value = fields[0]
166  return value_type, value
167 
168  ##
169  # Set the value of user fields. The field types will be the same.
170  #
171  # data ... dict, with field name as key, field value as value
172  #
173  # Returns None
174  #
175  #
176  def update(self, data):
177  self.loaddoc()
178  all_fields = self.document.getElementsByType(UserFieldDecl)
179  for f in all_fields:
180  field_name = f.getAttribute(u'name')
181  if field_name in data:
182  value_type = f.getAttribute(u'valuetype')
183  value = data.get(field_name)
184  if value_type == u'string':
185  f.setAttribute(u'stringvalue', value)
186  else:
187  f.setAttribute(u'value', value)
188  self.savedoc()
189 
def update
Set the value of user fields.
Definition: userfield.py:176
List, view and manipulate user fields.
Definition: userfield.py:53
def list_fields
List (extract) all known user-fields.
Definition: userfield.py:98
def get
Extract the contents of this field from the file.
Definition: userfield.py:146
def load
Load an ODF file into memory.
Definition: text.py:1
def list_values
Extract the contents of given field names from the file.
Definition: userfield.py:137
def get_type_and_value
Extract the type and contents of this field from the file.
Definition: userfield.py:160
def __init__
Constructor.
Definition: userfield.py:67
def list_fields_and_values
List (extract) user-fields with type and value.
Definition: userfield.py:111