136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
|
import datetime
|
||
|
|
||
|
from wordpress_xmlrpc.compat import xmlrpc_client
|
||
|
|
||
|
|
||
|
class FieldMap(object):
|
||
|
"""
|
||
|
Container for settings mapping a WordPress XML-RPC request/response struct
|
||
|
to a Python, programmer-friendly class.
|
||
|
|
||
|
Parameters:
|
||
|
`inputName`: name of the field in XML-RPC response.
|
||
|
`outputNames`: (optional) list of field names to use when generating new XML-RPC request. defaults to `[inputName]`
|
||
|
`default`: (optional) default value to use when none is supplied in XML-RPC response. defaults to `None`
|
||
|
`conversion`: (optional) function to convert Python value to XML-RPC value for XML-RPC request.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, inputName, outputNames=None, default=None, conversion=None):
|
||
|
self.name = inputName
|
||
|
self.output_names = outputNames or [inputName]
|
||
|
self.default = default
|
||
|
self.conversion = conversion
|
||
|
|
||
|
def convert_to_python(self, xmlrpc=None):
|
||
|
"""
|
||
|
Extracts a value for the field from an XML-RPC response.
|
||
|
"""
|
||
|
if xmlrpc:
|
||
|
return xmlrpc.get(self.name, self.default)
|
||
|
elif self.default:
|
||
|
return self.default
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
def convert_to_xmlrpc(self, input_value):
|
||
|
"""
|
||
|
Convert a Python value to the expected XML-RPC value type.
|
||
|
"""
|
||
|
if self.conversion:
|
||
|
return self.conversion(input_value)
|
||
|
else:
|
||
|
return input_value
|
||
|
|
||
|
def get_outputs(self, input_value):
|
||
|
"""
|
||
|
Generate a set of output values for a given input.
|
||
|
"""
|
||
|
output_value = self.convert_to_xmlrpc(input_value)
|
||
|
|
||
|
output = {}
|
||
|
for name in self.output_names:
|
||
|
output[name] = output_value
|
||
|
|
||
|
return output
|
||
|
|
||
|
|
||
|
class IntegerFieldMap(FieldMap):
|
||
|
"""
|
||
|
FieldMap pre-configured for handling integer fields.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
if 'conversion' not in kwargs:
|
||
|
kwargs['conversion'] = int
|
||
|
|
||
|
super(IntegerFieldMap, self).__init__(*args, **kwargs)
|
||
|
|
||
|
|
||
|
class DateTimeFieldMap(FieldMap):
|
||
|
"""
|
||
|
FieldMap pre-configured for handling DateTime fields.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, *args, **kwargs):
|
||
|
if 'conversion' not in kwargs:
|
||
|
kwargs['conversion'] = xmlrpc_client.DateTime
|
||
|
|
||
|
super(DateTimeFieldMap, self).__init__(*args, **kwargs)
|
||
|
|
||
|
def convert_to_python(self, xmlrpc=None):
|
||
|
if xmlrpc:
|
||
|
# make sure we have an `xmlrpc_client.DateTime` instance
|
||
|
raw_value = xmlrpc.get(self.name, self.default)
|
||
|
if not isinstance(raw_value, xmlrpc_client.DateTime):
|
||
|
raw_value = xmlrpc_client.DateTime(raw_value)
|
||
|
|
||
|
# extract its timetuple and convert to datetime
|
||
|
try:
|
||
|
tt = raw_value.timetuple()
|
||
|
except ValueError:
|
||
|
# Workaround for a combination of Python and WordPress bug
|
||
|
# which would return a null date for Draft posts. This is not
|
||
|
# the case for recent versions of WP, but drafts created a that
|
||
|
# time still have a null date.
|
||
|
# The python bug is http://bugs.python.org/issue2623 and
|
||
|
# affects xmlrpclib when fed a timezone aware DateTime
|
||
|
if str(raw_value) == "00000000T00:00:00Z":
|
||
|
raw_value = xmlrpc_client.DateTime("00010101T00:00:00")
|
||
|
tt = raw_value.timetuple()
|
||
|
else:
|
||
|
raise
|
||
|
return datetime.datetime(*tuple(tt)[:6])
|
||
|
elif self.default:
|
||
|
return self.default
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
|
||
|
class TermsListFieldMap(FieldMap):
|
||
|
"""
|
||
|
FieldMap that converts to/from WordPress objects.
|
||
|
"""
|
||
|
def __init__(self, object_class, *args, **kwargs):
|
||
|
self.object_class = object_class
|
||
|
super(TermsListFieldMap, self).__init__(*args, **kwargs)
|
||
|
|
||
|
def convert_to_python(self, xmlrpc=None):
|
||
|
if xmlrpc and self.name in xmlrpc:
|
||
|
values = []
|
||
|
for value in xmlrpc.get(self.name):
|
||
|
values.append(self.object_class(value))
|
||
|
return values
|
||
|
else:
|
||
|
return []
|
||
|
|
||
|
def convert_to_xmlrpc(self, input_value):
|
||
|
if input_value:
|
||
|
values = {}
|
||
|
for term in input_value:
|
||
|
if term.taxonomy not in values:
|
||
|
values[term.taxonomy] = []
|
||
|
values[term.taxonomy].append(int(term.id))
|
||
|
return values
|
||
|
else:
|
||
|
return None
|