def __init__(self, sign_order=1, viewer=False, invitation_delivery_method=IDM.email, confirmation_delivery_method=CDM.email, authentication_method=AM.standard, allows_highlighting=False, sign_success_redirect_url=None, rejection_redirect_url=None): super(Signatory, self).__init__() self._id = None self._current = None self._sign_order = sign_order self._undelivered_invitation = None self._undelivered_email_invitation = None self._undelivered_sms_invitation = None self._delivered_invitation = None self._has_account = None self._invitation_delivery_method = invitation_delivery_method self._confirmation_delivery_method = confirmation_delivery_method self._viewer = viewer self._allows_highlighting = allows_highlighting self._author = False self._eleg_mismatch_message = None self._sign_time = None self._view_time = None self._invitation_view_time = None self._rejection_time = None self._rejection_message = None self._sign_success_redirect_url = sign_success_redirect_url self._rejection_redirect_url = rejection_redirect_url self._authentication_method = authentication_method self._sign_url = None self._fields = _set.ScriveSet() self._fields._elem_validator = tvu.instance(_field.Field) self._attachments = _set.ScriveSet() self._attachments._elem_validator = tvu.instance(SignatoryAttachment)
class SignatureField(Field): @tvu(name=tvu.tvus.Text, obligatory=tvu.instance(bool), should_be_filled_by_sender=tvu.instance(bool)) def __init__(self, name, obligatory=True, should_be_filled_by_sender=False): super(SignatureField, self).__init__( value=u'', obligatory=obligatory, should_be_filled_by_sender=should_be_filled_by_sender) self._type = u'signature' self._name = name @scrive_property def name(self): return self._name @name.setter @tvu(name=tvu.tvus.Text) def name(self, name): self._name = name @scrive_property def value(self): return self._value
class RemoteAuthorAttachment(_file.RemoteFile): @tvu(id_=_object.ID, name=tvu.tvus.NonEmptyText, mandatory=tvu.instance(bool), merge=tvu.instance(bool)) def __init__(self, id_, name, mandatory=False, merge=True): super(RemoteAuthorAttachment, self).__init__(id_, name) self._mandatory = mandatory self._merge = merge @classmethod def _from_json_obj(cls, json): return RemoteAuthorAttachment(id_=json[u'id'], name=json[u'name'], mandatory=json[u'required'], merge=json[u'add_to_sealed_file']) @scrive_property def mandatory(self): return self._mandatory @mandatory.setter @tvu(mandatory=tvu.instance(bool)) def mandatory(self, mandatory): self._mandatory = mandatory @scrive_property def merge(self): return self._merge @merge.setter @tvu(merge=tvu.instance(bool)) def merge(self, merge): self._merge = merge
def test_symmetric_difference_update(self): s = S([1, 2, 3]) s.symmetric_difference_update([2, 4]) self.assertEqual(3, len(s)) self.assertTrue(1 in s) self.assertTrue(3 in s) self.assertTrue(4 in s) s._set_read_only() with self.assertRaises(RO): s.symmetric_difference_update([]) s._set_invalid() with self.assertRaises(INV): s.symmetric_difference_update([]) s = S() s._elem_validator = tvu.instance(int) err_msg = u'iterable[2] must be int, not {}' with self.assertRaises(TypeError, err_msg): s.symmetric_difference_update([2, 3, {}]) s = S() with self.assertRaises(TypeError, u'iterable must be iterable, not None'): s.symmetric_difference_update(None)
def test_update(self): s = S([1, 2, 3]) s.update([2, 4], [1, 5], [6]) self.assertEqual(6, len(s)) self.assertTrue(1 in s) self.assertTrue(2 in s) self.assertTrue(3 in s) self.assertTrue(4 in s) self.assertTrue(5 in s) self.assertTrue(6 in s) s._set_read_only() with self.assertRaises(RO): s.update() s._set_invalid() with self.assertRaises(INV): s.update() s = S() s._elem_validator = tvu.instance(int) err_msg = u'iterables[1][2] must be int, not {}' with self.assertRaises(TypeError, err_msg): s.update([1], [2, 3, {}]) with self.assertRaises(TypeError, u'iterables[3] must be iterable, not 2'): s.update([], set(), S(), 2)
def test_add(self): s = S([1]) self.assertEqual(1, len(s)) self.assertTrue(1 in s) self.assertFalse(2 in s) self.assertFalse(3 in s) s.add(2) self.assertEqual(2, len(s)) self.assertTrue(1 in s) self.assertTrue(2 in s) self.assertFalse(3 in s) s._set_read_only() with self.assertRaises(RO): s.add(3) s._set_invalid() with self.assertRaises(INV): s.add(3) s = S() s._elem_validator = tvu.instance(int) err_msg = u'elem must be int, not []' with self.assertRaises(TypeError, err_msg): s.add([])
def test___isub__(self): s = S([1, 2, 3]) s -= S([2, 4]) s -= S([5]) self.assertEqual(2, len(s)) self.assertTrue(1 in s) self.assertFalse(2 in s) self.assertTrue(3 in s) self.assertFalse(4 in s) self.assertFalse(5 in s) s._set_read_only() with self.assertRaises(RO): s -= S() s._set_invalid() with self.assertRaises(INV): s -= S() s = S() s._elem_validator = tvu.instance(int) err_msg = u'other\[\d\] must be int, not None' with self.assertRaises(TypeError, err_msg, regex=True): s -= S([2, 3, None]) s = S() with self.assertRaises(TypeError, u'other must be set, not None'): s -= None
class StandardField(Field): @tvu(name=tvu.instance(StandardFieldType, enum=True), value=tvu.tvus.Text, obligatory=tvu.instance(bool), should_be_filled_by_sender=tvu.instance(bool)) def __init__(self, name, value=u'', obligatory=True, should_be_filled_by_sender=False): super(StandardField, self).__init__( value=value, obligatory=obligatory, should_be_filled_by_sender=should_be_filled_by_sender) self._type = u'standard' self._name = name
def nullable_soft_error_test(self): @tvu(x=tvu.nullable(tvu.instance(SampleEnum, enum=True))) def foo(x): pass err_msg = "x could be None or SampleEnum's variant name, not: 'bar'" with self.assertRaises(ValueError, err_msg): foo('bar')
def instance_test(self): @tvu(x=tvu.instance(int)) def foo(x): return x self.assertEqual(foo(1), 1) with self.assertRaises(TypeError, 'x must be int, not None'): foo(None)
def nullable_basic_test(self): @tvu(x=tvu.nullable(tvu.instance(int))) def foo(x): return x self.assertEqual(foo(1), 1) self.assertEqual(foo(None), None) with self.assertRaises(TypeError, "x must be int or None, not 'a'"): foo('a')
def __init__(self, value=u'', obligatory=True, should_be_filled_by_sender=False): super(Field, self).__init__() self._value = value self._closed = None self._obligatory = obligatory self._should_be_filled_by_sender = should_be_filled_by_sender self._placements = ScriveSet() self._placements._elem_validator = \ tvu.instance(_field_placement.FieldPlacement)
class AuthorAttachment(_file.File): @tvu(name=tvu.tvus.NonEmptyText, content=tvu.instance(bytes), mandatory=tvu.instance(bool), merge=tvu.instance(bool)) def __init__(self, name, content, mandatory=False, merge=True): super(AuthorAttachment, self).__init__(name) self._content = content self._mandatory = mandatory self._merge = merge def stream(self): return StringIO(self._content) @classmethod def from_file_obj(cls, name, file_obj): with closing(file_obj) as f: return AuthorAttachment(name, f.read()) @classmethod def from_file_path(cls, file_path): with open(file_path, 'rb') as f: return AuthorAttachment.from_file_obj( unicode(os.path.basename(file_path)), f) @scrive_property def mandatory(self): return self._mandatory @mandatory.setter @tvu(mandatory=tvu.instance(bool)) def mandatory(self, mandatory): self._mandatory = mandatory @scrive_property def merge(self): return self._merge @merge.setter @tvu(merge=tvu.instance(bool)) def merge(self, merge): self._merge = merge
def str_enum_test(self): class StrEnum(str, Enum): foo = 'bar' @tvu(x=tvu.instance(StrEnum, enum=True)) def foo(x): return x.value self.assertEqual(foo(StrEnum.foo), 'bar') self.assertEqual(foo('foo'), 'bar') err_msg = "x could be StrEnum's variant name, not: 'bar'" with self.assertRaises(ValueError, err_msg): foo('bar')
class CheckboxField(Field): _default_placement_tip = _field_placement.TipSide.left_tip @tvu(name=tvu.tvus.Text, value=tvu.instance(bool), obligatory=tvu.instance(bool), should_be_filled_by_sender=tvu.instance(bool)) def __init__(self, name, value=False, obligatory=False, should_be_filled_by_sender=False): super(CheckboxField, self).__init__( value=u'CHECKED' if value else u'', obligatory=obligatory, should_be_filled_by_sender=should_be_filled_by_sender) self._type = u'checkbox' self._name = name @scrive_property def name(self): return self._name @name.setter @tvu(name=tvu.tvus.Text) def name(self, name): self._name = name @scrive_property def value(self): return self._value.lower() == u'checked' @value.setter @tvu(value=tvu.instance(bool)) def value(self, value): self._value = u'CHECKED' if value else u''
def _private_init(self): super(Document, self).__init__() self._id = None self._title = u'' self._number_of_days_to_sign = 14 self._number_of_days_to_remind = None self._status = None self._modification_time = None self._creation_time = None self._signing_deadline = None self._autoremind_time = None self._current_sign_order = None self._is_template = False self._show_header = True self._show_pdf_download = True self._show_reject_option = True self._show_reject_reason = True self._show_footer = True self.invitation_message = None # setter has better logic self.confirmation_message = None # setter has better logic self._api_callback_url = None self._language = Language.swedish self._tags = _unicode_dict.UnicodeDict() self._saved_as_draft = False self._deletion_status = DeletionStatus.not_deleted self._signing_possible = None self._object_version = None self._timezone = u'Europe/Stockholm' self._viewed_by_author = None self._access_token = None self._signatories = _set.ScriveSet() self._signatories._elem_validator = tvu.instance(_signatory.Signatory) self._original_file = None self._sealed_document = None self._author_attachments = _set.ScriveSet() self._author_attachments._elem_validator = \ tvu.instance(AuthorAttachment)
def unicode_enum_test(self): class UnicodeEnum(text, Enum): foo = u'bar' @tvu(x=tvu.instance(UnicodeEnum, enum=True)) def foo(x): return x.value self.assertEqual(foo(UnicodeEnum.foo), u'bar') self.assertEqual(foo('foo'), u'bar') err_msg = "x could be UnicodeEnum's variant name, not: " + repr(u'bar') with self.assertRaises(ValueError, err_msg): foo(u'bar') err_msg = "x could be UnicodeEnum's variant name, not: 'bar'" with self.assertRaises(ValueError, err_msg): foo('bar')
def instance_enum_test(self): @tvu(x=tvu.instance(SampleEnum, enum=True)) def foo(x): return x.value self.assertEqual(foo(SampleEnum.one), 1) self.assertEqual(foo(SampleEnum.two), 2) self.assertEqual(foo(SampleEnum.three), 3) self.assertEqual(foo('one'), 1) self.assertEqual(foo('two'), 2) self.assertEqual(foo('three'), 3) with self.assertRaises(TypeError, 'x must be SampleEnum, not None'): foo(None) err_msg = "x could be SampleEnum's variant name, not: 'None'" with self.assertRaises(ValueError, err_msg): foo('None')
def _from_json_obj(cls, json): try: signatories = [ _signatory.Signatory._from_json_obj(signatory_json) for signatory_json in json[u'signatories'] ] lang_code = json[u'lang'] if lang_code == u'gb': lang_code = u'en' document = Document._private_ctor() document.title = json[u'title'] document.number_of_days_to_sign = json[u'daystosign'] document.number_of_days_to_remind = json[u'daystoremind'] document.is_template = json[u'template'] document.show_header = json[u'showheader'] document.show_pdf_download = json[u'showpdfdownload'] document.show_reject_option = json[u'showrejectoption'] document.show_reject_reason = json[u'allowrejectreason'] document.show_footer = json[u'showfooter'] document.invitation_message = json[u'invitationmessage'] or None document.confirmation_message = \ json[u'confirmationmessage'] or None document.api_callback_url = json[u'apicallbackurl'] document.language = Language(lang_code) document.saved_as_draft = json[u'saved'] document.timezone = json[u'timezone'] document.signatories.update(signatories) document.tags.update( {elem[u'name']: elem[u'value'] for elem in json[u'tags']}) document._id = json[u'id'] if json[u'time'] is not None: document._modification_time = dateparser.parse(json[u'time']) if json[u'ctime'] is not None: document._creation_time = dateparser.parse(json[u'ctime']) if json[u'timeouttime'] is not None: document._signing_deadline = \ dateparser.parse(json[u'timeouttime']) if json[u'autoremindtime'] is not None: document._autoremind_time = \ dateparser.parse(json[u'autoremindtime']) document._status = DocumentStatus(json[u'status']) document._current_sign_order = json[u'signorder'] deleted = json[u'deleted'] really_deleted = json[u'reallydeleted'] if deleted and really_deleted: document._deletion_status = DeletionStatus.deleted elif deleted: document._deletion_status = DeletionStatus.in_trash document._signing_possible = json[u'canperformsigning'] document._object_version = json[u'objectversion'] document._viewed_by_author = json[u'isviewedbyauthor'] document._access_token = json[u'accesstoken'] document._original_file = \ _file.RemoteFile._from_json_obj(json.get(u'file')) document._sealed_document = \ _file.RemoteFile._from_json_obj(json.get(u'sealedfile')) author_attachments = \ _set.ScriveSet([RemoteAuthorAttachment._from_json_obj(att_json) for att_json in json[u'authorattachments']]) author_attachments._elem_validator = tvu.instance(AuthorAttachment) document._author_attachments = author_attachments if document.status is not DocumentStatus.preparation: document._set_read_only() return document except (KeyError, TypeError, ValueError) as e: raise _exceptions.InvalidResponse(e, json)
TYPES = (float, int) def unify(self, value): return float(value) def validate(self, value): if not 0. <= value <= 1.: self.error(u'in the <0,1> range (inclusive)') class TipSide(unicode, enum.Enum): left_tip = u'left' right_tip = u'right' MaybeTipSide = tvu.nullable(tvu.instance(TipSide, enum=True)) class FieldPlacement(_object.ScriveObject): FONT_SIZE_SMALL = 12. / 943. FONT_SIZE_NORMAL = 16. / 943. FONT_SIZE_LARGE = 20. / 943. FONT_SIZE_HUGE = 24. / 943. @tvu(left=Ratio, top=Ratio, width=Ratio, height=Ratio, font_size=Ratio, page=tvu.tvus.PositiveInt, tip=MaybeTipSide) def __init__(self, left, top, width, height, font_size=FONT_SIZE_NORMAL, page=1, tip=None): super(FieldPlacement, self).__init__()
TYPES = (float, int) def unify(self, value): return float(value) def validate(self, value): if not 0. <= value <= 1.: self.error(u'in the <0,1> range (inclusive)') class TipSide(unicode, enum.Enum): left_tip = u'left' right_tip = u'right' MaybeTipSide = tvu.nullable(tvu.instance(TipSide, enum=True)) class FieldPlacement(_object.ScriveObject): FONT_SIZE_SMALL = 12. / 943. FONT_SIZE_NORMAL = 16. / 943. FONT_SIZE_LARGE = 20. / 943. FONT_SIZE_HUGE = 24. / 943. @tvu(left=Ratio, top=Ratio, width=Ratio, height=Ratio, font_size=Ratio, page=tvu.tvus.PositiveInt,
class UnicodeDict(dict, _object.ScriveObject): @tvu(iterable=TextMappingOrIterable, kwargs=TextMappingOrIterable) def __init__(self, iterable=(), **kwargs): dict.__init__(self, iterable, **kwargs) _object.ScriveObject.__init__(self) self._derived_objs = [] def _set_read_only(self): for obj in self._derived_objs: obj._set_read_only() super(UnicodeDict, self)._set_read_only() def _set_invalid(self): for obj in self._derived_objs: obj._set_invalid() super(UnicodeDict, self)._set_invalid() def clear(self): self._check_setter() return dict.clear(self) def copy(self): self._check_getter() result = UnicodeDict(self) self._derived_objs.append(result) if self._read_only: result._set_read_only() return result @classmethod @tvu(keys=tvu.tvus.iterable(), value=tvu.tvus.Text) def fromkeys(cls, keys, value=u''): keys = [ tvu.tvus.Text('keys[%d]' % (i, )).unify_validate(key) for i, key in enumerate(keys) ] return UnicodeDict([(key, value) for key in keys]) def get(self, key, default=None): self._check_getter() return dict.get(self, key, default) def __contains__(self, key): self._check_getter() return dict.__contains__(self, key) def items(self): self._check_getter() return dict.items(self) def iteritems(self): self._check_getter() return dict.iteritems(self) def iterkeys(self): self._check_getter() return dict.iterkeys(self) def itervalues(self): self._check_getter() return dict.itervalues(self) def keys(self): self._check_getter() return dict.keys(self) def values(self): self._check_getter() return dict.values(self) def viewkeys(self): self._check_getter() return dict.viewkeys(self) def viewvalues(self): self._check_getter() return dict.viewvalues(self) def viewitems(self): self._check_getter() return dict.viewitems(self) def pop(self, key, *default): self._check_setter() return dict.pop(self, key, *default) def popitem(self): self._check_setter() return dict.popitem(self) @tvu(default=tvu.tvus.Text) def setdefault(self, key, default=u''): self._check_setter() return dict.setdefault(self, key, default) @tvu(iterable=TextMappingOrIterable, kwargs=TextMappingOrIterable) def update(self, iterable=(), **kwargs): self._check_setter() return dict.update(self, iterable, **kwargs) def __delitem__(self, key): self._check_setter() return dict.__delitem__(self, key) @tvu(other=tvu.instance(dict)) def __eq__(self, other): self._check_getter() if not isinstance(other, UnicodeDict): return False return self._read_only == other._read_only and dict.__eq__(self, other) @tvu(other=tvu.instance(dict)) def __ne__(self, other): self._check_getter() if not isinstance(other, UnicodeDict): return True return self._read_only != other._read_only or dict.__ne__(self, other) @tvu(other=tvu.instance(dict)) def __ge__(self, other): self._check_getter() return dict.__ge__(self, other) @tvu(other=tvu.instance(dict)) def __le__(self, other): self._check_getter() return dict.__le__(self, other) @tvu(other=tvu.instance(dict)) def __gt__(self, other): self._check_getter() return dict.__gt__(self, other) @tvu(other=tvu.instance(dict)) def __lt__(self, other): self._check_getter() return dict.__lt__(self, other) def __getitem__(self, key): self._check_getter() return dict.__getitem__(self, key) @tvu(key=tvu.tvus.Text, value=tvu.tvus.Text) def __setitem__(self, key, value): self._check_setter() return dict.__setitem__(self, key, value) def __len__(self): self._check_getter() return dict.__len__(self) def __iter__(self): self._check_getter() return dict.__iter__(self)
def _from_json_obj(cls, json): try: signatories = [_signatory.Signatory._from_json_obj(signatory_json) for signatory_json in json[u'signatories']] lang_code = json[u'lang'] if lang_code == u'gb': lang_code = u'en' document = Document._private_ctor() document.title = json[u'title'] document.number_of_days_to_sign = json[u'daystosign'] document.number_of_days_to_remind = json[u'daystoremind'] document.is_template = json[u'template'] document.show_header = json[u'showheader'] document.show_pdf_download = json[u'showpdfdownload'] document.show_reject_option = json[u'showrejectoption'] document.show_reject_reason = json[u'allowrejectreason'] document.show_footer = json[u'showfooter'] document.invitation_message = json[u'invitationmessage'] or None document.confirmation_message = \ json[u'confirmationmessage'] or None document.api_callback_url = json[u'apicallbackurl'] document.language = Language(lang_code) document.saved_as_draft = json[u'saved'] document.timezone = json[u'timezone'] document.signatories.update(signatories) document.tags.update({elem[u'name']: elem[u'value'] for elem in json[u'tags']}) document._id = json[u'id'] if json[u'time'] is not None: document._modification_time = dateparser.parse(json[u'time']) if json[u'ctime'] is not None: document._creation_time = dateparser.parse(json[u'ctime']) if json[u'timeouttime'] is not None: document._signing_deadline = \ dateparser.parse(json[u'timeouttime']) if json[u'autoremindtime'] is not None: document._autoremind_time = \ dateparser.parse(json[u'autoremindtime']) document._status = DocumentStatus(json[u'status']) document._current_sign_order = json[u'signorder'] deleted = json[u'deleted'] really_deleted = json[u'reallydeleted'] if deleted and really_deleted: document._deletion_status = DeletionStatus.deleted elif deleted: document._deletion_status = DeletionStatus.in_trash document._signing_possible = json[u'canperformsigning'] document._object_version = json[u'objectversion'] document._viewed_by_author = json[u'isviewedbyauthor'] document._access_token = json[u'accesstoken'] document._original_file = \ _file.RemoteFile._from_json_obj(json.get(u'file')) document._sealed_document = \ _file.RemoteFile._from_json_obj(json.get(u'sealedfile')) author_attachments = \ _set.ScriveSet([RemoteAuthorAttachment._from_json_obj(att_json) for att_json in json[u'authorattachments']]) author_attachments._elem_validator = tvu.instance(AuthorAttachment) document._author_attachments = author_attachments if document.status is not DocumentStatus.preparation: document._set_read_only() return document except (KeyError, TypeError, ValueError) as e: raise _exceptions.InvalidResponse(e, json)
class Signatory(_object.ScriveObject): @tvu(sign_order=tvu.tvus.PositiveInt, invitation_delivery_method=tvu.instance(IDM, enum=True), confirmation_delivery_method=tvu.instance(CDM, enum=True), authentication_method=tvu.instance(AM, enum=True), viewer=tvu.instance(bool), allows_highlighting=tvu.instance(bool), sign_success_redirect_url=MaybeUnicode, rejection_redirect_url=MaybeUnicode) def __init__(self, sign_order=1, viewer=False, invitation_delivery_method=IDM.email, confirmation_delivery_method=CDM.email, authentication_method=AM.standard, allows_highlighting=False, sign_success_redirect_url=None, rejection_redirect_url=None): super(Signatory, self).__init__() self._id = None self._current = None self._sign_order = sign_order self._undelivered_invitation = None self._undelivered_email_invitation = None self._undelivered_sms_invitation = None self._delivered_invitation = None self._has_account = None self._invitation_delivery_method = invitation_delivery_method self._confirmation_delivery_method = confirmation_delivery_method self._viewer = viewer self._allows_highlighting = allows_highlighting self._author = False self._eleg_mismatch_message = None self._sign_time = None self._view_time = None self._invitation_view_time = None self._rejection_time = None self._rejection_message = None self._sign_success_redirect_url = sign_success_redirect_url self._rejection_redirect_url = rejection_redirect_url self._authentication_method = authentication_method self._sign_url = None self._fields = _set.ScriveSet() self._fields._elem_validator = tvu.instance(_field.Field) self._attachments = _set.ScriveSet() self._attachments._elem_validator = tvu.instance(SignatoryAttachment) @classmethod def _from_json_obj(cls, json): try: fields = [ _field.Field._from_json_obj(field_json) for field_json in json[u'fields'] ] attachments = [ SignatoryAttachment._from_json_obj(att_json) for att_json in json[u'attachments'] ] signatory = \ Signatory(sign_order=json[u'signorder'], invitation_delivery_method=IDM(json[u'delivery']), confirmation_delivery_method=CDM( json[u'confirmationdelivery']), authentication_method=AM(json[u'authentication']), viewer=not json[u'signs'], allows_highlighting=json[u'allowshighlighting'], sign_success_redirect_url=( json[u'signsuccessredirect']), rejection_redirect_url=json[u'rejectredirect']) signatory.fields.update(fields) signatory.attachments.update(attachments) signatory._id = json[u'id'] signatory._author = json[u'author'] signatory._current = json[u'current'] signatory._undelivered_invitation = json[u'undeliveredInvitation'] signatory._undelivered_email_invitation = \ json[u'undeliveredMailInvitation'] signatory._undelivered_sms_invitation = \ json[u'undeliveredSMSInvitation'] signatory._delivered_invitation = \ json[u'deliveredInvitation'] signatory._has_account = \ json[u'saved'] signatory._eleg_mismatch_message = \ json[u'datamismatch'] if json[u'signdate'] is not None: signatory._sign_time = dateparser.parse(json[u'signdate']) if json[u'seendate'] is not None: signatory._view_time = dateparser.parse(json[u'seendate']) if json[u'readdate'] is not None: signatory._invitation_view_time = \ dateparser.parse(json[u'readdate']) if json[u'rejecteddate'] is not None: signatory._rejection_time = \ dateparser.parse(json[u'rejecteddate']) signatory._rejection_message = json[u'rejectionreason'] signatory._sign_url = json.get(u'signlink') return signatory except (KeyError, TypeError, ValueError) as e: raise _exceptions.InvalidResponse(e) def _set_invalid(self): # invalidate fields first, before getter stops working self.fields._set_invalid() self.attachments._set_invalid() super(Signatory, self)._set_invalid() def _set_read_only(self): super(Signatory, self)._set_read_only() self.fields._set_read_only() self.attachments._set_read_only() def _set_api(self, api, document): super(Signatory, self)._set_api(api, document) for attachment in self.attachments: attachment._set_api(api, document) def _to_json_obj(self): result = { u'fields': list(self.fields), u'attachments': list(self.attachments), u'signorder': self.sign_order, u'delivery': self.invitation_delivery_method.value, u'confirmationdelivery': self.confirmation_delivery_method.value, u'authentication': self.authentication_method.value, u'signs': not self.viewer, u'allowshighlighting': self.allows_highlighting, u'author': self.author, u'signsuccessredirect': self.sign_success_redirect_url, u'rejectredirect': self.rejection_redirect_url } if self.id is not None: result[u'id'] = self.id return result @scrive_property def fields(self): return self._fields @scrive_property def attachments(self): return self._attachments @scrive_property def id(self): return self._id @scrive_property def current(self): return self._current @scrive_property def sign_order(self): return self._sign_order @sign_order.setter @tvu(sign_order=tvu.tvus.PositiveInt) def sign_order(self, sign_order): self._sign_order = sign_order @scrive_property def undelivered_invitation(self): return self._undelivered_invitation @scrive_property def undelivered_email_invitation(self): return self._undelivered_email_invitation @scrive_property def undelivered_sms_invitation(self): return self._undelivered_sms_invitation @scrive_property def delivered_invitation(self): return self._delivered_invitation @scrive_property def invitation_delivery_method(self): return self._invitation_delivery_method @invitation_delivery_method.setter @tvu(invitation_delivery_method=tvu.instance(IDM, enum=True)) def invitation_delivery_method(self, invitation_delivery_method): self._invitation_delivery_method = invitation_delivery_method @scrive_property def confirmation_delivery_method(self): return self._confirmation_delivery_method @confirmation_delivery_method.setter @tvu(confirmation_delivery_method=tvu.instance(CDM, enum=True)) def confirmation_delivery_method(self, confirmation_delivery_method): self._confirmation_delivery_method = confirmation_delivery_method @scrive_property def viewer(self): return self._viewer @viewer.setter @tvu(viewer=tvu.instance(bool)) def viewer(self, viewer): self._viewer = viewer @scrive_property def allows_highlighting(self): return self._allows_highlighting @allows_highlighting.setter @tvu(allows_highlighting=tvu.instance(bool)) def allows_highlighting(self, allows_highlighting): self._allows_highlighting = allows_highlighting @scrive_property def author(self): return self._author @scrive_property def has_account(self): return self._has_account @scrive_property def eleg_mismatch_message(self): return self._eleg_mismatch_message @scrive_property def sign_time(self): return self._sign_time @scrive_property def view_time(self): return self._view_time @scrive_property def invitation_view_time(self): return self._invitation_view_time @scrive_property def rejection_time(self): return self._rejection_time @scrive_property def rejection_message(self): return self._rejection_message @scrive_property def sign_success_redirect_url(self): return self._sign_success_redirect_url @sign_success_redirect_url.setter @tvu(sign_success_redirect_url=MaybeUnicode) def sign_success_redirect_url(self, sign_success_redirect_url): self._sign_success_redirect_url = sign_success_redirect_url @scrive_property def rejection_redirect_url(self): return self._rejection_redirect_url @rejection_redirect_url.setter @tvu(rejection_redirect_url=MaybeUnicode) def rejection_redirect_url(self, rejection_redirect_url): self._rejection_redirect_url = rejection_redirect_url @scrive_property def authentication_method(self): return self._authentication_method @authentication_method.setter @tvu(authentication_method=tvu.instance(AM, enum=True)) def authentication_method(self, authentication_method): self._authentication_method = authentication_method @scrive_property def sign_url(self): return self._sign_url def absolute_sign_url(self): self._check_getter() if self._sign_url is None: return None if self._api is None: raise _exceptions.Error(u'API not set') proto = b'https' if self._api.https else b'http' return proto + b'://' + self._api.api_hostname + self._sign_url @scrive_property def full_name(self): fst_name_fields = filter(lambda f: f.name == SFT.first_name, self.fields) last_name_fields = filter(lambda f: f.name == SFT.last_name, self.fields) first_name_part = u'' try: first_name_part = fst_name_fields[0].value except IndexError: pass last_name_part = u'' try: last_name_part = last_name_fields[0].value except IndexError: pass if first_name_part != u'' and last_name_part != u'': return first_name_part + u' ' + last_name_part elif first_name_part != u'': return first_name_part elif last_name_part != u'': return last_name_part else: return u'' @full_name.setter @tvu(full_name=tvu.tvus.Text) def full_name(self, full_name): fst_name_fields = filter(lambda f: f.name == SFT.first_name, self.fields) try: fst_name_field = fst_name_fields[0] except IndexError: fst_name_field = SF(name=SFT.first_name, value=u'') self.fields.add(fst_name_field) last_name_fields = filter(lambda f: f.name == SFT.last_name, self.fields) try: last_name_field = last_name_fields[0] except IndexError: last_name_field = SF(name=SFT.last_name, value=u'') self.fields.add(last_name_field) if u' ' in full_name: name_parts = full_name.split(u' ') fst_name = name_parts[0] last_name = u' '.join(name_parts[1:]) elif full_name != u' ': fst_name = full_name last_name = u'' else: fst_name = u'' last_name = u'' fst_name_field.value = fst_name last_name_field.value = last_name
class ScriveSet(set, _object.ScriveObject): @tvu(iterable=tvu.tvus.iterable()) def __init__(self, iterable=()): set.__init__(self, iterable) _object.ScriveObject.__init__(self) self.__init_scrive_set__() def __init_scrive_set__(self): self._derived_objs = [] self._elem_validator = None def add(self, elem): self._check_setter() if self._elem_validator is not None: elem = self._elem_validator('elem').unify_validate(elem) return set.add(self, elem) def copy(self): self._check_getter() result = set.copy(self) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) if self._read_only: result._set_read_only() return result @tvu(iterables=tvu.tvus.iterable(tvu.tvus.iterable())) def difference_update(self, *iterables): self._check_setter() return set.difference_update(self, *iterables) @tvu(args=tvu.tvus.iterable(tvu.tvus.iterable())) def intersection(self, *args): self._check_getter() result = set.intersection(self, *args) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(iterable=tvu.tvus.iterable()) def isdisjoint(self, iterable): self._check_getter() return set.isdisjoint(self, iterable) @tvu(iterable=tvu.tvus.iterable()) def issuperset(self, iterable): self._check_getter() return set.issuperset(self, iterable) def remove(self, elem): self._check_setter() return set.remove(self, elem) @tvu(iterable=tvu.tvus.iterable()) def symmetric_difference(self, iterable): self._check_getter() result = set.symmetric_difference(self, iterable) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(iterable=tvu.tvus.iterable()) def symmetric_difference_update(self, iterable): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator iterable = \ [validator('iterable[%s]' % (i,)).unify_validate(elem) for i, elem in enumerate(iterable)] return set.symmetric_difference_update(self, iterable) @tvu(iterables=tvu.tvus.iterable(tvu.tvus.iterable())) def update(self, *iterables): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator iterables = \ [[validator('iterables[%s][%s]' % (i, j)).unify_validate(elem) for j, elem in enumerate(iterable)] for i, iterable in enumerate(iterables)] return set.update(self, *iterables) def clear(self): self._check_setter() return set.clear(self) @tvu(args=tvu.tvus.iterable(tvu.tvus.iterable())) def difference(self, *args): self._check_getter() result = set.difference(self, *args) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result def discard(self, elem): self._check_setter() return set.discard(self, elem) @tvu(args=tvu.tvus.iterable(tvu.tvus.iterable())) def intersection_update(self, *args): self._check_setter() return set.intersection_update(self, *args) @tvu(iterable=tvu.tvus.iterable()) def issubset(self, iterable): self._check_getter() return set.issubset(self, iterable) def pop(self): self._check_setter() return set.pop(self) @tvu(args=tvu.tvus.iterable(tvu.tvus.iterable())) def union(self, *args): self._check_getter() result = set.union(self, *args) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __and__(self, other): self._check_getter() result = set.__and__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __xor__(self, other): self._check_getter() result = set.__xor__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __sub__(self, other): self._check_getter() result = set.__sub__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __or__(self, other): self._check_getter() result = set.__or__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __ge__(self, other): self._check_getter() return set.__ge__(self, other) @tvu(other=tvu.instance(set)) def __le__(self, other): self._check_getter() return set.__le__(self, other) # this redirects to __or__ anyway, so no need for tvu wrapper def __ior__(self, other): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator other = \ [validator('other[%s]' % (i,)).unify_validate(elem) for i, elem in enumerate(other)] return set.__ior__(self, other) # this redirects to __and__ anyway, so no need for tvu wrapper def __iand__(self, other): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator other = \ [validator('other[%s]' % (i,)).unify_validate(elem) for i, elem in enumerate(other)] return set.__iand__(self, other) # this redirects to __sub__ anyway, so no need for tvu wrapper def __isub__(self, other): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator other = \ [validator('other[%s]' % (i,)).unify_validate(elem) for i, elem in enumerate(other)] return set.__isub__(self, other) # this redirects to __xor__ anyway, so no need for tvu wrapper def __ixor__(self, other): self._check_setter() if self._elem_validator is not None: validator = self._elem_validator other = \ [validator('other[%s]' % (i,)).unify_validate(elem) for i, elem in enumerate(other)] return set.__ixor__(self, other) def __contains__(self, item): self._check_getter() return set.__contains__(self, item) @tvu(other=tvu.instance(set)) def __gt__(self, other): self._check_getter() return set.__gt__(self, other) @tvu(other=tvu.instance(set)) def __lt__(self, other): self._check_getter() return set.__lt__(self, other) @tvu(other=tvu.instance(set)) def __eq__(self, other): self._check_getter() if not isinstance(other, ScriveSet): return False return self._read_only == other._read_only and set.__eq__(self, other) @tvu(other=tvu.instance(set)) def __ne__(self, other): self._check_getter() if not isinstance(other, ScriveSet): return True return self._read_only != other._read_only or set.__ne__(self, other) def __len__(self): self._check_getter() return set.__len__(self) def __iter__(self): self._check_getter() return set.__iter__(self) def _set_read_only(self): for item in itertools.chain( set.__iter__(self), # iterate even if self already invalid/ro iter(self._derived_objs)): if isinstance(item, _object.ScriveObject): item._set_read_only() super(ScriveSet, self)._set_read_only() def _set_invalid(self): for item in itertools.chain( set.__iter__(self), # iterate even if self already invalid/ro iter(self._derived_objs)): if isinstance(item, _object.ScriveObject): item._set_invalid() super(ScriveSet, self)._set_invalid() @tvu(other=tvu.instance(set)) def __rxor__(self, other): self._check_getter() # proxy to __xor__, it's ok cause it's symmetric result = set.__xor__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __rand__(self, other): self._check_getter() # proxy to __and__, it's ok cause it's symmetric result = set.__and__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __ror__(self, other): self._check_getter() # proxy to __or__, it's ok cause it's symmetric result = set.__or__(self, other) result.__init_scrive_set__() _object.ScriveObject.__init__(result) self._derived_objs.append(result) return result @tvu(other=tvu.instance(set)) def __rsub__(self, other): self._check_getter() # __sub__ isn't symmetric, we have to be creative result = ScriveSet(other) result -= self self._derived_objs.append(result) return result def get_by_attrs(self, **kwargs): ''' Return first object matching all key=val attributes. or None. ''' self._check_getter() for x in self: matches = True for key, val in kwargs.items(): try: if getattr(x, key) != val: matches = False break except AttributeError: matches = False break if matches: return x return None
class Field(_object.ScriveObject): _default_placement_tip = _field_placement.TipSide.right_tip @tvu(value=tvu.tvus.Text, obligatory=tvu.instance(bool), should_be_filled_by_sender=tvu.instance(bool)) def __init__(self, value=u'', obligatory=True, should_be_filled_by_sender=False): super(Field, self).__init__() self._value = value self._closed = None self._obligatory = obligatory self._should_be_filled_by_sender = should_be_filled_by_sender self._placements = ScriveSet() self._placements._elem_validator = \ tvu.instance(_field_placement.FieldPlacement) def __str__(self): return u'%s(value=%s, %d placements)' % \ (unicode(self.__class__.__name__), self.value, len(self.placements())) @classmethod def _from_json_obj(cls, json): try: type_ = json[u'type'] name = json[u'name'] value = json[u'value'] closed = json.get(u'closed') obligatory = json[u'obligatory'] should_be_filled_by_sender = json[u'shouldbefilledbysender'] placements = \ [_field_placement.FieldPlacement._from_json_obj( placement_json) for placement_json in json[u'placements']] if type_ == u'standard': field = StandardField(name=StandardFieldType(name), value=value) elif type_ == u'custom': field = CustomField(name=name, value=value) elif type_ == u'signature': field = SignatureField(name=name) if not isinstance(value, unicode): raise _exceptions.InvalidResponse(u'bad field value') field._value = value elif type_ == u'checkbox': field = CheckboxField(name=name, value=value.lower() == u'checked') else: raise _exceptions.InvalidResponse(u'bad field type') field.obligatory = obligatory field.should_be_filled_by_sender = should_be_filled_by_sender field.placements.update(placements) if isinstance(closed, (bool, type(None))): field._closed = closed else: raise _exceptions.InvalidResponse() return field except (KeyError, TypeError, ValueError) as e: raise _exceptions.InvalidResponse(e) def _set_invalid(self): # invalidate placements first, before getter stops working self.placements._set_invalid() super(Field, self)._set_invalid() def _set_read_only(self): super(Field, self)._set_read_only() self.placements._set_read_only() def _to_json_obj(self): for placement in self.placements: placement._resolve_default_tip(self._default_placement_tip) return { u'name': self.name, u'obligatory': self.obligatory, u'shouldbefilledbysender': self.should_be_filled_by_sender, u'type': self.type, # checkbox stores different type than getter returns u'value': self._value, u'placements': list(self.placements) } @scrive_property def type(self): return self._type @scrive_property def name(self): return self._name @scrive_property def value(self): return self._value @value.setter @tvu(value=tvu.tvus.Text) def value(self, value): self._value = value @scrive_property def closed(self): return self._closed @scrive_property def obligatory(self): return self._obligatory @obligatory.setter @tvu(obligatory=tvu.instance(bool)) def obligatory(self, obligatory): self._obligatory = obligatory @scrive_property def should_be_filled_by_sender(self): return self._should_be_filled_by_sender @should_be_filled_by_sender.setter @tvu(should_be_filled_by_sender=tvu.instance(bool)) def should_be_filled_by_sender(self, should_be_filled_by_sender): self._should_be_filled_by_sender = should_be_filled_by_sender @scrive_property def placements(self): return self._placements
class Document(_object.ScriveObject): def __init__(self): raise TypeError( u'Dont create Document objects directly. Use Scrive object.') @classmethod def _private_ctor(cls): instance = _object.ScriveObject.__new__(cls) instance._private_init() return instance def _private_init(self): super(Document, self).__init__() self._id = None self._title = u'' self._number_of_days_to_sign = 14 self._number_of_days_to_remind = None self._status = None self._modification_time = None self._creation_time = None self._signing_deadline = None self._autoremind_time = None self._current_sign_order = None self._is_template = False self._show_header = True self._show_pdf_download = True self._show_reject_option = True self._show_reject_reason = True self._show_footer = True self.invitation_message = None # setter has better logic self.confirmation_message = None # setter has better logic self._api_callback_url = None self._language = Language.swedish self._tags = _unicode_dict.UnicodeDict() self._saved_as_draft = False self._deletion_status = DeletionStatus.not_deleted self._signing_possible = None self._object_version = None self._timezone = u'Europe/Stockholm' self._viewed_by_author = None self._access_token = None self._signatories = _set.ScriveSet() self._signatories._elem_validator = tvu.instance(_signatory.Signatory) self._original_file = None self._sealed_document = None self._author_attachments = _set.ScriveSet() self._author_attachments._elem_validator = \ tvu.instance(AuthorAttachment) @classmethod def _from_json_obj(cls, json): try: signatories = [ _signatory.Signatory._from_json_obj(signatory_json) for signatory_json in json[u'signatories'] ] lang_code = json[u'lang'] if lang_code == u'gb': lang_code = u'en' document = Document._private_ctor() document.title = json[u'title'] document.number_of_days_to_sign = json[u'daystosign'] document.number_of_days_to_remind = json[u'daystoremind'] document.is_template = json[u'template'] document.show_header = json[u'showheader'] document.show_pdf_download = json[u'showpdfdownload'] document.show_reject_option = json[u'showrejectoption'] document.show_reject_reason = json[u'allowrejectreason'] document.show_footer = json[u'showfooter'] document.invitation_message = json[u'invitationmessage'] or None document.confirmation_message = \ json[u'confirmationmessage'] or None document.api_callback_url = json[u'apicallbackurl'] document.language = Language(lang_code) document.saved_as_draft = json[u'saved'] document.timezone = json[u'timezone'] document.signatories.update(signatories) document.tags.update( {elem[u'name']: elem[u'value'] for elem in json[u'tags']}) document._id = json[u'id'] if json[u'time'] is not None: document._modification_time = dateparser.parse(json[u'time']) if json[u'ctime'] is not None: document._creation_time = dateparser.parse(json[u'ctime']) if json[u'timeouttime'] is not None: document._signing_deadline = \ dateparser.parse(json[u'timeouttime']) if json[u'autoremindtime'] is not None: document._autoremind_time = \ dateparser.parse(json[u'autoremindtime']) document._status = DocumentStatus(json[u'status']) document._current_sign_order = json[u'signorder'] deleted = json[u'deleted'] really_deleted = json[u'reallydeleted'] if deleted and really_deleted: document._deletion_status = DeletionStatus.deleted elif deleted: document._deletion_status = DeletionStatus.in_trash document._signing_possible = json[u'canperformsigning'] document._object_version = json[u'objectversion'] document._viewed_by_author = json[u'isviewedbyauthor'] document._access_token = json[u'accesstoken'] document._original_file = \ _file.RemoteFile._from_json_obj(json.get(u'file')) document._sealed_document = \ _file.RemoteFile._from_json_obj(json.get(u'sealedfile')) author_attachments = \ _set.ScriveSet([RemoteAuthorAttachment._from_json_obj(att_json) for att_json in json[u'authorattachments']]) author_attachments._elem_validator = tvu.instance(AuthorAttachment) document._author_attachments = author_attachments if document.status is not DocumentStatus.preparation: document._set_read_only() return document except (KeyError, TypeError, ValueError) as e: raise _exceptions.InvalidResponse(e, json) def _set_invalid(self): # invalidate subobjects first, before getter stops working self.signatories._set_invalid() self.tags._set_invalid() self.author_attachments._set_invalid() if self.original_file is not None: self.original_file._set_invalid() if self.sealed_document is not None: self.sealed_document._set_invalid() super(Document, self)._set_invalid() def _set_read_only(self): super(Document, self)._set_read_only() self.signatories._set_read_only() self.tags._set_read_only() self.author_attachments._set_read_only() if self.original_file is not None: self.original_file._set_read_only() if self.sealed_document is not None: self.sealed_document._set_read_only() def _to_json_obj(self): return { u'title': self.title, u'daystosign': self.number_of_days_to_sign, u'daystoremind': self.number_of_days_to_remind, u'template': self.is_template, u'showheader': self.show_header, u'showpdfdownload': self.show_pdf_download, u'showrejectoption': self.show_reject_option, u'allowrejectreason': self.show_reject_reason, u'showfooter': self.show_footer, u'invitationmessage': self.invitation_message or u'', u'confirmationmessage': self.confirmation_message or u'', u'apicallbackurl': self.api_callback_url, u'lang': self.language.value, u'tags': [{ u'name': key, u'value': val } for key, val in self.tags.items()], u'saved': self.saved_as_draft, u'timezone': self.timezone, u'authorattachments': list(self.author_attachments), u'signatories': list(self.signatories) } @scrive_property def signatories(self): return self._signatories def other_parties(self): ''' Return all signatories except the author. ''' self._check_getter() for s in self._signatories: if not s.author: yield s def other_signatories(self): ''' Return all signing signatories except the author. ''' self._check_getter() for s in self._signatories: if not s.author and not s.viewer: yield s def other_signatory(self): ''' Return non-author signing signatory (if there's just one). Raises errors, if there's less/more than one. ''' self._check_getter() others = list(self.other_signatories()) if not others: raise _exceptions.Error(u'No other signatories') elif len(others) > 1: raise _exceptions.Error(u'Multiple signatories') else: return others[0] @scrive_property def id(self): return self._id @scrive_property def title(self): return self._title @title.setter @tvu(title=tvu.tvus.Text) def title(self, title): self._title = title @scrive_property def number_of_days_to_sign(self): return self._number_of_days_to_sign @number_of_days_to_sign.setter @tvu(number_of_days_to_sign=tvu.tvus.bounded_int(1, 90)) def number_of_days_to_sign(self, number_of_days_to_sign): self._number_of_days_to_sign = number_of_days_to_sign @scrive_property def status(self): return self._status @scrive_property def modification_time(self): return self._modification_time @scrive_property def creation_time(self): return self._creation_time @scrive_property def signing_deadline(self): return self._signing_deadline @scrive_property def autoremind_time(self): return self._autoremind_time @scrive_property def current_sign_order(self): return self._current_sign_order @scrive_property def authentication_method(self): signatories = list(self.signatories) if not signatories: return u'mixed' # at least 1 signatory first_signatory = signatories.pop(0) result = first_signatory.authentication_method for signatory in signatories: if signatory.authentication_method != result: # signatories use various auth methods return u'mixed' # all signatories have the same auth method return result.value @scrive_property def invitation_delivery_method(self): signatories = list(self.signatories) if not signatories: return u'mixed' # at least 1 signatory first_signatory = signatories.pop(0) result = first_signatory.invitation_delivery_method for signatory in signatories: if signatory.invitation_delivery_method != result: # signatories use various invitation delivery methods return u'mixed' # all signatories have the same invitation delivery method return result.value @scrive_property def is_template(self): return self._is_template @is_template.setter @tvu(is_template=tvu.instance(bool)) def is_template(self, is_template): self._is_template = is_template @scrive_property def number_of_days_to_remind(self): return self._number_of_days_to_remind @number_of_days_to_remind.setter @tvu(number_of_days_to_remind=tvu.nullable(tvu.tvus.PositiveInt)) def number_of_days_to_remind(self, number_of_days_to_remind): self._number_of_days_to_remind = number_of_days_to_remind @scrive_property def show_header(self): return self._show_header @show_header.setter @tvu(show_header=tvu.instance(bool)) def show_header(self, show_header): self._show_header = show_header @scrive_property def show_pdf_download(self): return self._show_pdf_download @show_pdf_download.setter @tvu(show_pdf_download=tvu.instance(bool)) def show_pdf_download(self, show_pdf_download): self._show_pdf_download = show_pdf_download @scrive_property def show_reject_option(self): return self._show_reject_option @show_reject_option.setter @tvu(show_reject_option=tvu.instance(bool)) def show_reject_option(self, show_reject_option): self._show_reject_option = show_reject_option @scrive_property def show_reject_reason(self): return self._show_reject_reason @show_reject_reason.setter @tvu(show_reject_reason=tvu.instance(bool)) def show_reject_reason(self, show_reject_reason): self._show_reject_reason = show_reject_reason @scrive_property def show_footer(self): return self._show_footer @show_footer.setter @tvu(show_footer=tvu.instance(bool)) def show_footer(self, show_footer): self._show_footer = show_footer @scrive_property def invitation_message(self): return self._invitation_message @invitation_message.setter @tvu(invitation_message=MaybeUnicode) def invitation_message(self, invitation_message): if invitation_message is not None and invitation_message.isspace(): invitation_message = None self._invitation_message = invitation_message @scrive_property def confirmation_message(self): return self._confirmation_message @confirmation_message.setter @tvu(confirmation_message=MaybeUnicode) def confirmation_message(self, confirmation_message): if confirmation_message is not None and confirmation_message.isspace(): confirmation_message = None self._confirmation_message = confirmation_message @scrive_property def api_callback_url(self): return self._api_callback_url @api_callback_url.setter @tvu(api_callback_url=MaybeUnicode) def api_callback_url(self, api_callback_url): self._api_callback_url = api_callback_url @scrive_property def language(self): return self._language @language.setter @tvu(language=tvu.instance(Language, enum=True)) def language(self, language): self._language = language @scrive_property def tags(self): return self._tags @scrive_property def saved_as_draft(self): return self._saved_as_draft @saved_as_draft.setter @tvu(saved_as_draft=tvu.instance(bool)) def saved_as_draft(self, saved_as_draft): self._saved_as_draft = saved_as_draft @scrive_property def deletion_status(self): return self._deletion_status @scrive_property def signing_possible(self): return self._signing_possible @scrive_property def object_version(self): return self._object_version @scrive_property def timezone(self): return self._timezone @timezone.setter @tvu(timezone=tvu.instance(unicode)) def timezone(self, timezone): self._timezone = timezone @scrive_property def viewed_by_author(self): return self._viewed_by_author @scrive_property def access_token(self): return self._access_token @scrive_property def original_file(self): return self._original_file @scrive_property def sealed_document(self): return self._sealed_document @scrive_property def author_attachments(self): return self._author_attachments @scrive_property def author(self): authors = filter(lambda s: s.author, self.signatories) if not authors: raise _exceptions.Error(u'No author') if len(authors) > 1: raise _exceptions.Error(u'Multiple authors') else: return authors[0] def _set_api(self, api, _document): super(Document, self)._set_api(api, self) if self.original_file is not None: self.original_file._set_api(api, self) if self.sealed_document is not None: self.sealed_document._set_api(api, self) for file_ in self.author_attachments: file_._set_api(api, self) for signatory in self.signatories: signatory._set_api(api, self)