1 """
2 The classes defined in this module should correspond 1-to-1 to the
3 specifications in the PamFax API docs. See the link below for more info:
4
5 https://sandbox-apifrontend.pamfax.biz/summary/processors/
6
7 Users should not need to instantiate this class in applications using PamFax.
8 Instead, just call the action directly on the PamFax object, and it will be
9 delegated to the correct processor automatically.
10 """
11
12 try:
13 import cjson as jsonlib
14 jsonlib.dumps = jsonlib.encode
15 jsonlib.loads = jsonlib.decode
16 except ImportError:
17 try:
18 from django.utils import simplejson as jsonlib
19 except ImportError:
20 try:
21 import simplejson as jsonlib
22 except ImportError:
23 import json as jsonlib
24
25 from httplib import HTTPException
26 from urllib import urlencode
27
28 import mimetypes
29 import socket
30
31 IP_ADDR = socket.gethostbyname(socket.gethostname())
32 USER_AGENT = 'dynaptico-pamfax'
33 ORIGIN = 'script'
34 CONTENT_TYPE = 'content-type'
35 CONTENT_TYPE_JSON = 'application/json'
36
37
38
39
40
41 -def _get_url(base_url, action, api_credentials, **kwargs):
42 """Construct the URL that corresponds to a given action.
43 All kwargs whose value is None are filtered out.
44
45 Arguments:
46 base_url -- The base of the URL corresponding to the PamFax processor name
47 action -- The PamFax method to append to the base URL
48 api_credentials -- The API credentials including user token extracted from /Session/VerifyUser
49
50 Keyword arguments:
51 **kwargs -- optional HTTP parameters to send to the PamFax URL
52
53 """
54 url = '%s/%s%s' % (base_url, action, api_credentials)
55 if len(kwargs) == 0:
56 return url
57 query = {}
58 for arg in kwargs:
59 kwarg = kwargs[arg]
60 if kwarg is not None:
61 if isinstance(kwarg, list):
62 for i in range(0, len(kwarg)):
63 query['%s[%d]' % (arg, i)] = kwarg[i]
64 else:
65 query[arg] = kwarg
66 url = '%s&%s' % (url, urlencode(query))
67 return url
68
70 """Wait for the HTTP response and throw an exception if the return
71 status is not OK. Return either a dict based on the
72 HTTP response in JSON, or if the response is not in JSON format,
73 return a tuple containing the data in the body and the content type.
74
75 """
76 response = http.getresponse()
77 codes = (response.status, response.reason)
78 print codes
79 if response.status != 200:
80 raise HTTPException("Response from server not OK: %s %s" % codes)
81 content_type = response.getheader(CONTENT_TYPE, None)
82 if content_type is not None and content_type.startswith(CONTENT_TYPE_JSON):
83 return jsonlib.loads(response.read())
84 else:
85 return (response.read(), content_type)
86
87 -def _get(http, url, body=''):
88 """Gets the specified url and returns the response."""
89 print "getting url '%s' with body '%s'" % (url, body)
90 http.request('GET', url, body)
91 return _get_and_check_response(http)
92
93 -def _post(http, url, body, headers={}):
94 """Posts to the specified url and returns the response."""
95 print "posting to url '%s' with body '%s'" % (url, body)
96 http.request('POST', url, body, headers)
97 return _get_and_check_response(http)
98
126
127
128
129
130
132 """Class encapsulating common actions for the PamFax API"""
133
134 - def __init__(self, api_credentials, http):
135 """Instantiates the Common class"""
136 self.base_url = '/Common'
137 self.api_credentials = api_credentials
138 self.http = http
139
141 """Returns the current settings for timezone and currency.
142 This is the format/timezone ALL return values of the API are in. These are taken from the user
143 (if logged in, the api user's settings or the current ip address)
144
145 """
146 url = _get_url(self.base_url, 'GetCurrentSettings', self.api_credentials)
147 return _get(self.http, url)
148
150 """Returns file content.
151
152 Will return binary data and headers that give the filename and mimetype.
153 Note: User identified by usertoken must be owner of the file or
154 the owner must have shared this file to the requesting user.
155 Share dependencies are resolved (dependend on the type) via the
156 fax_inbox, fax_history_files or user_covers table.
157
158 Arguments:
159 file_uuid -- The uuid of the file to get
160
161 """
162 url = _get_url(self.base_url, 'GetFile', self.api_credentials, file_uuid=file_uuid)
163 return _get(self.http, url)
164
174
175 - def get_page_preview(self, uuid, page_no, max_width=None, max_height=None):
176 """Returns a preview page for a fax.
177
178 May be in progress, sent or from inbox.
179
180 Arguments:
181 uuid -- The uuid of the fax to get preview for
182 page_no -- Page number to get (1,2,...)
183 max_width -- Maximum width in Pixel
184 max_height -- Maximum height in Pixel
185
186 """
187 url = _get_url(self.base_url, 'GetPagePreview', self.api_credentials, uuid=uuid, page_no=page_no, max_width=max_width, max_height=max_height)
188 return _get(self.http, url)
189
191 """DEPRECATED"""
192 return None
193
195 """Returns all countries with their translated names and the default zone"""
196 url = _get_url(self.base_url, 'ListCountries', self.api_credentials)
197 return _get(self.http, url)
198
200 """Returns all countries in the given zone
201
202 Result includes their translated names, countrycode and country-prefix.
203
204 Arguments:
205 zone -- Zone of the country which is wanted (1-7)
206
207 """
208 url = _get_url(self.base_url, 'ListCountriesForZone', self.api_credentials, zone=zone)
209 return _get(self.http, url)
210
212 """Returns the list of supported currencies.
213
214 Result contains convertion rates too.
215 If code is given will only return the specified currency's information.
216
217 Keyword arguments:
218 code -- CurrencyCode
219
220 """
221 url = _get_url(self.base_url, 'ListCurrencies', self.api_credentials, code=code)
222 return _get(self.http, url)
223
225 """List all available languages.
226
227 Result may be filtered tso that only languages are returned that are
228 at least translated $min_percent_translated %
229
230 Keyward arguments:
231 min_percent_translated -- the percentage value the languages have to be translated
232
233 """
234 url = _get_url(self.base_url, 'ListLanguages', self.api_credentials, min_percent_translated=min_percent_translated)
235 return _get(self.http, url)
236
238 """Returns a list of strings translated into the given language.
239
240 Arguments:
241 ids -- array of String identifiers. You may also pass a comma separated list as $ids[0] (ids[0]=BTN_YES,BTN_NO).
242
243 Keyword arguments:
244 culture -- culture identifier, defaults to users culture. Accepts full culture-codes like en-US, de-DE and just a language code like en, de, ...
245
246 """
247 url = _get_url(self.base_url, 'ListStrings', self.api_credentials, ids=ids, culture=culture)
248 return _get(self.http, url)
249
251 """Returns the supported file types for documents that can be faxed."""
252 url = _get_url(self.base_url, 'ListSupportedFileTypes', self.api_credentials)
253 return _get(self.http, url)
254
256 """List all supported timezones"""
257 url = _get_url(self.base_url, 'ListTimezones', self.api_credentials)
258 return _get(self.http, url)
259
261 """Lists the current Versions.
262 Result contains versions for the PamFax Gadget, Client etc and returns
263 the version and update url
264 """
265 url = _get_url(self.base_url, 'ListVersions', self.api_credentials)
266 return _get(self.http, url)
267
269 """Returns price and price_pro for a given zone"""
270 url = _get_url(self.base_url, 'ListZones', self.api_credentials)
271 return _get(self.http, url)
272
273
274
275
276
278 """Class encapsulating actions related to fax history for this account"""
279
280 - def __init__(self, api_credentials, http):
281 """Instantiates the FaxHistory class"""
282 self.base_url = '/FaxHistory'
283 self.api_credentials = api_credentials
284 self.http = http
285
286 - def add_fax_note(self, fax_uuid, note):
287 """Add a note (free text) to the fax
288
289 Arguments:
290 fax_uuid -- uuid of the fax
291 note -- text to add to the fax
292
293 """
294 url = _get_url(self.base_url, 'AddFaxNote', self.api_credentials, fax_uuid=fax_uuid, note=note)
295 return _get(self.http, url)
296
297 - def count_faxes(self, type):
298 """Returns the number of faxes from users history with a specific state.
299
300 Arguments:
301 type -- Possible values: history, inbox, inbox_unread, outbox or unpaid
302
303 """
304 url = _get_url(self.base_url, 'CountFaxes', self.api_credentials, type=type)
305 return _get(self.http, url)
306
307 - def delete_fax(self):
308 """DEPRECATED! Use DeleteFaxes instead"""
309 return None
310
312 """DEPRECATED! Use DeleteFaxesFromTrash instead"""
313 return None
314
315 - def delete_faxes(self, uuids, siblings_too=None):
316 """Moves faxes to the trash.
317
318 If siblings_too is true will perform for the given faxes and all other recipients
319 from the same fax jobs.
320 siblings_too will only be evaluated for uuids beloging to an outgoing fax and will be
321 ignored for incoming faxes uuids
322
323 """
324 url = _get_url(self.base_url, 'DeleteFaxes', self.api_credentials, uuids=uuids, siblings_too=siblings_too)
325 return _get(self.http, url)
326
328 """Removes faxes from trash
329
330 This method is similar to EmptyTrash() which deletes all the faxes from trash
331
332 Arguments:
333 uuids -- ids of faxes to be removed vom trash
334
335 """
336 url = _get_url(self.base_url, 'DeleteFaxesFromTrash', self.api_credentials, uuids=uuids)
337 return _get(self.http, url)
338
339 - def empty_trash(self):
340 """Removes all faxes from trash for user and if user is member of a company and has delete rights also for the owners inbox faxes"""
341 url = _get_url(self.base_url, 'EmptyTrash', self.api_credentials)
342 return _get(self.http, url)
343
344 - def get_fax_details(self, uuid):
345 """Returns the details of a fax in progress.
346
347 Arguments:
348 uuid -- UUID of the fax to show
349
350 """
351 url = _get_url(self.base_url, 'GetFaxDetails', self.api_credentials, uuid=uuid)
352 return _get(self.http, url)
353
354 - def get_fax_group(self, uuid):
355 """Returns a fax groups details.
356
357 Arguments:
358 uuid -- Uuid of one of the faxes in the group.
359
360 """
361 url = _get_url(self.base_url, 'GetFaxGroup', self.api_credentials, uuid=uuid)
362 return _get(self.http, url)
363
364 - def get_inbox_fax(self, uuid, mark_read=None):
365 """Returns the details of a fax in the inbox.
366
367 Arguments:
368 uuid -- UUID of the fax to show
369 mark_read -- If true marks the fax as read (default: false).
370
371 """
372 url = _get_url(self.base_url, 'GetInboxFax', self.api_credentials, uuid=uuid, mark_read=mark_read)
373 return _get(self.http, url)
374
376 """Get a .pdf-Version of a transmission report.
377
378 On the transmission report basic data of the fax and a preview of the first page is shown.
379 Should always be called with API_MODE_PASSTHRU, as the result is the pdf as binary data
380
381 Arguments:
382 uuid -- @attribute[RequestParam('uuid','string')]
383
384 """
385 url = _get_url(self.base_url, 'GetTransmissionReport', self.api_credentials, uuid=uuid)
386 return _get(self.http, url)
387
388 - def list_fax_group(self, uuid, current_page=None, items_per_page=None):
389 """Lists all faxes in a group (that are sent as on job).
390
391 Arguments:
392 uuid -- Uuid of one of the faxes in the group.
393
394 Keyword arguments:
395 current_page -- The page which should be shown
396 items_per_page -- How many items are shown per page
397
398 """
399 url = _get_url(self.base_url, 'ListFaxGroup', self.api_credentials, uuid=uuid, current_page=current_page, items_per_page=items_per_page)
400 return _get(self.http, url)
401
402 - def list_fax_notes(self, fax_uuid):
403 """Lists all notes for the given fax in reverse order (latest first)
404
405 Arguments:
406 fax_uuid -- uuid of the fax to list notes for
407
408 """
409 url = _get_url(self.base_url, 'ListFaxNotes', self.api_credentials, fax_uuid=fax_uuid)
410 return _get(self.http, url)
411
412 - def list_inbox_faxes(self, current_page=None, items_per_page=None):
413 """List all faxes in the inbox of the current user.
414
415 Keyword arguments:
416 current_page -- The page which should be shown
417 items_per_page -- How many items are shown per page
418
419 """
420 url = _get_url(self.base_url, 'ListInboxFaxes', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
421 return _get(self.http, url)
422
423 - def list_outbox_faxes(self, current_page=None, items_per_page=None):
424 """Faxes in the outbox that are currently in the sending process
425
426 Keyword arguments:
427 current_page -- The page which should be shown
428 items_per_page -- How many items are shown per page
429
430 """
431 url = _get_url(self.base_url, 'ListOutboxFaxes', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
432 return _get(self.http, url)
433
434 - def list_recent_faxes(self, count=None, data_to_list=None):
435 """Returns a list of latest faxes for the user.
436
437 Does not contain deleted and delayed faxes (See ListTrash for deleted faxes).
438
439 Keyword arguments:
440 count -- The count of items to return. Valid values are between 1 and 100
441 data_to_list -- Any message types you want this function to return. Allowed models are 'sent', 'inbox', 'outbox'. Leave empty to get faxes of any type.
442
443 """
444 url = _get_url(self.base_url, 'ListRecentFaxes', self.api_credentials, count=count, data_to_list=data_to_list)
445 return _get(self.http, url)
446
447 - def list_sent_faxes(self, current_page=None, items_per_page=None):
448 """List all sent faxes (successful or not)
449
450 Keyword arguments:
451 current_page -- The page which should be shown
452 items_per_page -- How many items are shown per page
453
454 """
455 url = _get_url(self.base_url, 'ListSentFaxes', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
456 return _get(self.http, url)
457
458 - def list_trash(self, current_page=None, items_per_page=None):
459 """List all faxes in trash
460
461 Keyword arguments:
462 current_page -- The page which should be shown
463 items_per_page -- How many items are shown per page
464
465 """
466 url = _get_url(self.base_url, 'ListTrash', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
467 return _get(self.http, url)
468
469 - def list_unpaid_faxes(self, current_page=None, items_per_page=None):
470 """Lists all unpaid faxes that are waiting for a payment.
471
472 When this user makes a transaction to add credit, these faxes will be sent automatically
473 if they are younger that 2 hours.
474
475 Keyword arguments:
476 current_page -- The page which should be shown
477 items_per_page -- How many items are shown per page
478
479 """
480 url = _get_url(self.base_url, 'ListUnpaidFaxes', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
481 return _get(self.http, url)
482
483 - def restore_fax(self, uuid):
484 """Restores a fax from the trash.
485
486 Arguments:
487 uuid -- uuid of fax to restore
488
489 """
490 url = _get_url(self.base_url, 'RestoreFax', self.api_credentials, uuid=uuid)
491 return _get(self.http, url)
492
493 - def set_fax_read(self, uuid):
494 """Sets a fax' read date to current time.
495
496 Fax needs to be a fax in the inbox.
497
498 Arguments:
499 uuid -- uuid of fax to set as read
500
501 """
502 url = _get_url(self.base_url, 'SetFaxRead', self.api_credentials, uuid=uuid)
503 return _get(self.http, url)
504
505 - def set_faxes_as_read(self, uuids):
506 """Sets the read date of all the faxes to the current time
507
508 Arguments:
509 uuids -- array of uuids for faxes to set as read
510
511 """
512 url = _get_url(self.base_url, 'SetFaxesAsRead', self.api_credentials, uuids=uuids)
513 return _get(self.http, url)
514
515 - def set_spam_state_for_faxes(self, uuids, is_spam=None):
516 """Sets the spamscore for all the faxes depending on the flag "is_spam"
517 Takes an array of faxes UUIDs and marks them a spam if the second argument (is_spam) is true.
518 Removes the Spam state if is_spam is false.
519 If 15 or more faxes of the same sender has been marked as spam, all incoming faxes are directly moved to the trash.
520 This is user specific, so if user A reports 15 faxes of one sender, then only all incoming faxes from the sender to
521 him are directly sent to the trash.
522
523 """
524 url = _get_url(self.base_url, 'SetSpamStateForFaxes', self.api_credentials, uuids=uuids, is_spam=is_spam)
525 return _get(self.http, url)
526
527
528
529
530
532 """Class encapsulating a specific fax job"""
533
534 - def __init__(self, api_credentials, http):
535 """Instantiates the FaxJob class"""
536 self.base_url = '/FaxJob'
537 self.api_credentials = api_credentials
538 self.http = http
539
540 - def add_file(self, filename, origin=None):
541 """Adds a file to the current fax.
542
543 Requires the file to be uploaded as POST paramter named 'file' as a standard HTTP upload. This could be either Content-type: multipart/form-data with file content as base64-encoded data or as Content-type: application/octet-stream with just the binary data.
544 See http://www.faqs.org/rfcs/rfc1867.html for documentation on file uploads.
545
546 Arguments:
547 filename -- Name of the file. You can also use the same file name for each file (i.e "fax.pdf")
548
549 Keyword arguments:
550 origin -- Optional file origin (ex: photo, scan,... - maximum length is 20 characters).
551
552 """
553 file = open(filename, 'rb')
554 content_type, body = _encode_multipart_formdata([('filename', filename)], [('file', filename, filename)])
555 url = _get_url(self.base_url, 'AddFile', self.api_credentials, filename=filename, origin=origin)
556 return _post(self.http, url, body, {'Content-Type': content_type, 'Content-Length': str(len(body))})
557
559 """Add a file identified by an online storage identifier.
560
561 You'll have to use the OnlineStorageApi to identify a user for an online storage provider first
562 and then get listings of his files. These will contain the file identifiers used by this method.
563
564 Arguments:
565 provider -- Identifies the provider used (see OnlineStorageApi)
566 uuid -- Identifies the file to be added (see OnlineStorageApi)
567
568 """
569 url = _get_url(self.base_url, 'AddFileFromOnlineStorage', self.api_credentials, provider=provider, uuid=uuid)
570 return _get(self.http, url)
571
573 """Adds a recipient to the current fax."""
574 url = _get_url(self.base_url, 'AddRecipient', self.api_credentials, number=number, name=name)
575 return _get(self.http, url)
576
578 """Adds recipients to the current fax.
579 The given recipients will be added to current recipients.
580
581 """
582 url = _get_url(self.base_url, 'AddRecipients', self.api_credentials, numbers=numbers, names=names)
583 return _get(self.http, url)
584
586 """Add a remote file to the fax.
587 url may contain username:password for basic http auth, but this is the only supported
588 authentication method.
589 URL Examples:
590 http://myusername:andpassord
591
592 """
593 url = _get_url(self.base_url, 'AddRemoteFile', self.api_credentials, url=url)
594 return _get(self.http, url)
595
596 - def cancel(self, uuid, siblings_too=None):
597 """Cancels fax sending for a fax recipient or a whole fax job.
598 If siblings_too is true will cancel all faxes in the job the
599 fax with uuid belongs to.
600
601 """
602 url = _get_url(self.base_url, 'Cancel', self.api_credentials, uuid=uuid, siblings_too=siblings_too)
603 return _get(self.http, url)
604
606 """Clones an already sent fax in the API backend and returns it.
607
608 Arguments:
609 uuid -- The uuid of the source fax
610
611 Keyword arguments:
612 user_ip -- The IP address of the client (if available). Put your own IP address otherwise.
613 user_agent -- User agent string of the client device. If not available, put something descriptive (like "iPhone OS 2.2")
614
615 """
616 url = _get_url(self.base_url, 'CloneFax', self.api_credentials, uuid=uuid, user_ip=user_ip, user_agent=user_agent)
617 return _get(self.http, url)
618
620 """Creates a new fax in the API backend and returns it.
621
622 If a fax job is currently in edit mode in this session, this fax job is returned instead.
623 Note: This is not an error. It provides you with the possibility to continue with the fax.
624
625 Keyword arguments:
626 user_ip -- The IP address of the client (if available). Put your own IP address otherwise.
627 user_agent -- User agent string of the client device. If not available, put something descriptive (like "iPhone OS 2.2")
628 origin -- From where was this fax started? i.e. "printer", "desktop", "home", ... For reporting and analysis purposes.
629
630 """
631 url = _get_url(self.base_url, 'Create', self.api_credentials, user_ip=user_ip, user_agent=user_agent, origin=origin)
632 return _get(self.http, url)
633
635 """Returns the state of the current fax."""
636 url = _get_url(self.base_url, 'GetFaxState', self.api_credentials)
637 return _get(self.http, url)
638
640 """Returns the states of all preview pages."""
641 url = _get_url(self.base_url, 'GetPreview', self.api_credentials)
642 return _get(self.http, url)
643
645 """Returns a list of all coverpages the user may use.
646 Result includes the "no cover" if the fax job already contains a file as in that case
647 there's no need to add a cover.
648 """
649 url = _get_url(self.base_url, 'ListAvailableCovers', self.api_credentials)
650 return _get(self.http, url)
651
653 """Get all uploaded files for the current fax"""
654 url = _get_url(self.base_url, 'ListFaxFiles', self.api_credentials)
655 return _get(self.http, url)
656
658 """Returns the recipients for the current fax.
659
660 Keyword arguments:
661 current_page -- The page which should be shown
662 items_per_page -- How many items are shown per page
663
664 """
665 url = _get_url(self.base_url, 'ListRecipients', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
666 return _get(self.http, url)
667
669 """Remove all uploaded files from the current fax"""
670 url = _get_url(self.base_url, 'RemoveAllFiles', self.api_credentials)
671 return _get(self.http, url)
672
674 """Removes all recipients for the current fax."""
675 url = _get_url(self.base_url, 'RemoveAllRecipients', self.api_credentials)
676 return _get(self.http, url)
677
679 """Removes the cover from fax"""
680 url = _get_url(self.base_url, 'RemoveCover', self.api_credentials)
681 return _get(self.http, url)
682
684 """Remove a file from the current fax."""
685 url = _get_url(self.base_url, 'RemoveFile', self.api_credentials, file_uuid=file_uuid)
686 return _get(self.http, url)
687
689 """Removes a recipient from the current fax"""
690 url = _get_url(self.base_url, 'RemoveRecipient', self.api_credentials, number=number)
691 return _get(self.http, url)
692
693 - def send(self, send_at=None):
694 """Start the fax sending.
695
696 Only successful if all necessary data is set to the fax: at least 1 recipient and a cover page or a file uploaded.
697 Will only work if user has enough credit to pay for the fax.
698 You may pass in a datetime when the fax shall be sent. This must be a string formatted in the users chosen culture
699 (so exactly as you would show it to him) and may not be in the past nor be greater than 'now + 14days'.
700
701 """
702 url = _get_url(self.base_url, 'Send', self.api_credentials, send_at=send_at)
703 return _get(self.http, url)
704
706 """Send a previously delayed fax now.
707
708 Use this method if you want to send a fax right now that was initially delayed (by giving a send_at value into Send).
709
710 """
711 url = _get_url(self.base_url, 'SendDelayedFaxNow', self.api_credentials, uuid=uuid)
712 return _get(self.http, url)
713
715 """Put the fax in the unpaid faxes queue.
716
717 Only possible if user has NOT enough credit to send this fax directly.
718 You may pass in a datetime when the fax shall be sent. This must be a string formatted in the users chosen culture
719 (so exactly as you would show it to him) and may not be in the past nor be greater than 'now + 14days'.
720
721 """
722 url = _get_url(self.base_url, 'SendLater', self.api_credentials, send_at=send_at)
723 return _get(self.http, url)
724
726 """DEPRECATED! Use SendUnpaidFaxes instead"""
727 return None
728
730 """Send unpaid faxes
731
732 Will work until credit reaches zero.
733 Will return two lists: SentFaxes and UnpaidFaxes that contain the
734 faxes that could or not be sent.
735
736 """
737 url = _get_url(self.base_url, 'SendUnpaidFaxes', self.api_credentials, uuids=uuids)
738 return _get(self.http, url)
739
740 - def set_cover(self, template_id, text=None):
741 """Sets the cover template for the current fax."""
742 url = _get_url(self.base_url, 'SetCover', self.api_credentials, template_id=template_id, text=text)
743 return _get(self.http, url)
744
745 - def set_notifications(self, notifications, group_notification=None, error_notification=None, save_defaults=None):
746 """Sets the notification options for the current fax.
747
748 Notification options that are not in the array will not be changed/resetted.
749 Note: defaults for notification settings will be taken from users account, so potentially not need
750 to call this on every fax.
751
752 Keyword arguments:
753 save_defaults -- Save Notification-Settings to user's Profile
754
755 """
756 url = _get_url(self.base_url, 'SetNotifications', self.api_credentials, notifications=notifications, group_notification=group_notification, error_notification=error_notification, save_defaults=save_defaults)
757 return _get(self.http, url)
758
760 """Creates recipients for the current fax.
761
762 All recipients are replaced with the given ones!
763
764 """
765 url = _get_url(self.base_url, 'SetRecipients', self.api_credentials, numbers=numbers, names=names)
766 return _get(self.http, url)
767
769 """Starts creating the preview for this fax.
770
771 Call after fax is ready (GetFaxState returns FAX_READY_TO_SEND)
772
773 """
774 url = _get_url(self.base_url, 'StartPreviewCreation', self.api_credentials)
775 return _get(self.http, url)
776
777
778
779
780
782 """Class encapsulating information for a given fax number"""
783
784 - def __init__(self, api_credentials, http):
785 """Instantiates the NumberInfo class"""
786 self.base_url = '/NumberInfo'
787 self.api_credentials = api_credentials
788 self.http = http
789
791 """Get some information about a fax number.
792
793 Result contains zone, type, city, ...
794 Validates and corrects the number too.
795
796 Arguments:
797 faxnumber -- The faxnumber to query (incl countrycode: +12139851886, min length: 8)
798
799 """
800 url = _get_url(self.base_url, 'GetNumberInfo', self.api_credentials, faxnumber=faxnumber)
801 return _get(self.http, url)
802
803 - def get_page_price(self, faxnumber):
804 """Calculate the expected price per page to a given fax number.
805
806 Use GetNumberInfo when you do not need pricing information, as calculating expected price takes longer then just looking up the info for a number.
807
808 Arguments:
809 faxnumber -- The faxnumber to query (incl countrycode: +12139851886, min length: 8). Login user first to get personalized prices.
810
811 """
812 url = _get_url(self.base_url, 'GetPagePrice', self.api_credentials, faxnumber=faxnumber)
813 return _get(self.http, url)
814
815
816
817
818
820 """Class encapsulating actions related to online storage"""
821
822 - def __init__(self, api_credentials, http):
823 """Instantiates the OnlineStorage class"""
824 self.base_url = '/OnlineStorage'
825 self.api_credentials = api_credentials
826 self.http = http
827
829 """Authenticate the current user for a Provider.
830
831 This is a one-time process and must be done only once for each user.
832 PamFax API will perform the login and store only an authentication token which
833 will be enaugh for future use of the service.
834
835 Arguments:
836 provider -- Provider name. See OnlineStorage::ListProviders for available providers.
837 username -- The user's name/login for the provider
838 password -- User's password to access his data at the provider side
839
840 """
841 url = _get_url(self.base_url, 'Authenticate', self.api_credentials, provider=provider, username=username, password=password)
842 return _get(self.http, url)
843
845 """Will drop the users authentication for the given provider.
846
847 This will permanently erase all data related to the account!
848
849 """
850 url = _get_url(self.base_url, 'DropAuthentication', self.api_credentials, provider=provider)
851 return _get(self.http, url)
852
854 """Outputs a providers logo in a given size.
855
856 Call ListProviders for valid sizes per Provider.
857
858 """
859 url = _get_url(self.base_url, 'GetProviderLogo', self.api_credentials, provider=provider, size=size)
860 return _get(self.http, url)
861
862 - def list_folder_contents(self, provider, folder=None, clear_cache=None):
863 """Lists all files and folders inside a given folder.
864
865 Leave folder empty to get the contents of the root folder.
866 User must be autheticated for the provider given here to be able to recieve listings (see Authenticate method).
867 If clear_cache is set to true all subitems will be deleted and must be refetched (previously cached UUIDs are invalid)
868
869 """
870 url = _get_url(self.base_url, 'ListFolderContents', self.api_credentials, provider=provider, folder=folder, clear_cache=clear_cache)
871 return _get(self.http, url)
872
874 """Returns a list of supported providers."""
875 url = _get_url(self.base_url, 'ListProviders', self.api_credentials, attach_settings=attach_settings)
876 return _get(self.http, url)
877
879 """Manually sets auth token for the current user.
880
881 token must contain an associative array including the tokens.
882 sample (google):
883 'auth_token_cp'=>DQAAAHoAAADCrkpB7Ip_vuelbla2UKE9s_ObVKTNA_kT6Ej26SwddJvMUmEz_9qbLlZJnsAdm583Sddp_0FYS9QmmwoUpf51RHxkgPUL20OqsdAP5OnCgY_TdVbvXX8tMQBBX30V4_NhTcE_0sI6zhba5Y3yZWV5nljliG98eA36ybekKucuhQ
884 'auth_token_writely'=>DQAAAHoAAADCrkpB7Ip_vuelbla2UKE9s_ObVKTNA_kT6Ej62SDwdJvMUmEz_9qbLlZJnsAdm583Sddp_0FYS9QmmwoUpf51RHxkgPUL20OqsdAP5OnCgY_TdVbvXX8tMQBBX30V4_NhTcE_0sI6zhba5Y3yZWV5nljliG98eA36ybekKucuhQ
885 'auth_token_wise'=>DQAAAHoAAADCrkpB7Ip_vuelbla2UKE9s_ObVKTNA_kT6Ej26SDdwJvMUmEz_9qbLlZJnsAdm583Sddp_0FYS9QmmwoUpf51RHxkgPUL20OqsdAP5OnCgY_TdVbvXX8tMQBBX30V4_NhTcE_0sI6zhba5Y3yZWV5nljliG98eA36ybekKucuhQ
886 'auth_token_lh2'=>DQAAAHoAAADCrkpB7Ip_vuelbla2UKE9s_ObkvTNA_kT6Ej26SDwdJvMUmEz_9qbLlZJnsAdm583Sddp_0FYS9QmmwoUpf51RHxkgPUL20OqsdAP5OnCgY_TdVbvXX8tMQBBX30V4_NhTcE_0sI6zhba5Y3yZWV5nljliG98eA36ybekKucuhQ
887
888 Arguments:
889 provider -- Provider name
890 token -- Associative array with token information
891 username -- Optional username (for displaying purposes)
892
893 """
894 url = _get_url(self.base_url, 'SetAuthToken', self.api_credentials, provider=provider, token=token, username=username)
895 return _get(self.http, url)
896
897
898
899
900
902 """Class encapsulating a PamFax session"""
903
904 - def __init__(self, api_credentials, http):
905 """Instantiates the Session class."""
906 self.base_url = '/Session'
907 self.api_credentials = api_credentials
908 self.http = http
909
911 """Creates an identifier for the current user, which then can be passed to the portal to directly log in the user: https://portal.pamfax.biz/?_id=
912
913 Be aware that these identifiers are case sensitive. Identifiers with ttl > 0 can only be used once.
914
915 Keyword arguments:
916 user_ip -- The IP address of the client on which this identifier will be bound to. Using the identfier from a different ip address will fail
917 timetolifeminutes -- Optional a lifetime of this identifier. Defaults to 60 seconds. If <= 0 is given, the identifier does not expire and can be used more then once, but are tied to your current API key and can not be passed to online shop, portal, ... in the url
918
919 """
920 url = _get_url(self.base_url, 'CreateLoginIdentifier', self.api_credentials, user_ip=user_ip, timetolifeminutes=timetolifeminutes)
921 return _get(self.http, url)
922
924 """Returns all changes in the system that affect the currently logged in user. This could be changes to the user's profile, credit, settings, ...
925
926 Changes will be deleted after you received them once via this call, so use it wisely ;)
927
928 """
929 url = _get_url(self.base_url, 'ListChanges', self.api_credentials)
930 return _get(self.http, url)
931
933 """Terminate the current session. Log out."""
934 url = _get_url(self.base_url, 'Logout', self.api_credentials)
935 return _get(self.http, url)
936
938 """Just keeps a session alive. If there is no activity in a Session for 5 minutes, it will be terminated.
939
940 You then would need to call Session::VerifyUser again and start a new FaxJob
941
942 """
943 url = _get_url(self.base_url, 'Ping', self.api_credentials)
944 return _get(self.http, url)
945
947 """Registers listeners for the current session. Any change of the listened types will then be available via Session::ListChanges function
948
949 Arguments:
950 listener_types -- Array of types to be registered ('faxall','faxsending','faxsucceeded','faxfailed','faxretrying')
951
952 """
953 url = _get_url(self.base_url, 'RegisterListener', self.api_credentials, listener_types=listener_types, append=append)
954 return _get(self.http, url)
955
957 """Returns the current user object.
958
959 Use this if you need to ensure that your locally stored user
960 object is up to date.
961
962 """
963 url = _get_url(self.base_url, 'ReloadUser', self.api_credentials)
964 return _get(self.http, url)
965
967 """Verifies a user via username/password
968
969 Arguments:
970 username -- Username of the user or the md5 of user's username. That's what he has entered when he registered
971 password -- The password (or the md5 of the password) that the user entered in the registration process for the given username (case sensitive)
972
973 """
974 url = _get_url(self.base_url, 'VerifyUser', self.api_credentials, username=username, password=password)
975 return _get(self.http, url)
976
977
978
979
980
1073
1074
1075
1076
1077
1079 """Class encapsulating user info"""
1080
1081 - def __init__(self, api_credentials, http):
1082 """Instantiates the UserInfo class"""
1083 self.base_url = '/UserInfo'
1084 self.api_credentials = api_credentials
1085 self.http = http
1086
1087 - def create_user(self, name, username, password, email, culture, externalprofile=None, campaign_id=None):
1088 """Create a new PamFax user and logs him in
1089
1090 Arguments:
1091 name -- First and last name of the user
1092 username -- Unique username. Call will fail with bad_username error if the username already exists. Min 6 chars, max 60 chars. Can be left empty if externalprofile is given. Then the username will be generated from externalprofile. You could use UserInfo::ValidateNewUsername to create a unique username first and then pass it to this call
1093 password -- a password for the user. If left empty, a new password will be generated. Min 8 chars, max 20 chars. If length is 32, it's assumed as md5 of original password. Please then check min and max length by yourself!
1094 email -- A valid email address for this user.
1095 culture -- The culture of the user (en-US, de-DE, ...)
1096
1097 Keyword arguments:
1098 externalprofile -- External profile data. externalprofile["type"] is the type of data: skype. externalprofile["client_ip"] should be set to the user's ip address
1099 campaign_id -- is used to payout recommendation bonus to given user uuid. i.e if user clicked on links like http://www.pamfax.biz/?ref=b36d019d53ba, the b36d019d53ba should be passed as campaign_id
1100
1101 """
1102 url = _get_url(self.base_url, 'CreateUser', self.api_credentials, name=name, username=username, password=password, email=email, culture=culture, externalprofile=externalprofile, campaign_id=campaign_id)
1103 return _get(self.http, url)
1104
1106 """Deletes the currently logged in users account.
1107
1108 All assigned numbers and data will be deleted too!
1109 Warning: User will be deleted permanently without any chance to recover his data!
1110
1111 """
1112 url = _get_url(self.base_url, 'DeleteUser', self.api_credentials)
1113 return _get(self.http, url)
1114
1116 """Returns the users culture information"""
1117 url = _get_url(self.base_url, 'GetCultureInfo', self.api_credentials)
1118 return _get(self.http, url)
1119
1121 """Returns avatars for current user
1122
1123 Keyword arguments:
1124 provider -- Provider to load Image from
1125
1126 """
1127 url = _get_url(self.base_url, 'GetUsersAvatar', self.api_credentials, provider=provider)
1128 return _get(self.http, url)
1129
1131 """Return if Avatar is available or not"""
1132 url = _get_url(self.base_url, 'HasAvatar', self.api_credentials)
1133 return _get(self.http, url)
1134
1136 """Check if the user has a Plan.
1137
1138 This would NOT include other fax numbers user has access to. Will return NONE if no plan, PRO or BASIC otherwise
1139
1140 """
1141 url = _get_url(self.base_url, 'HasPlan', self.api_credentials)
1142 return _get(self.http, url)
1143
1145 """Returns expirations from current user
1146
1147 if type==false all Expirations are Returned
1148 else CREDIT, PROPLAN and
1149
1150 """
1151 url = _get_url(self.base_url, 'ListExpirations', self.api_credentials, type=type)
1152 return _get(self.http, url)
1153
1154 - def list_inboxes(self, expired_too=None, shared_too=None):
1155 """Return the inboxes of the user with some additional data (like expiration).
1156
1157 Keyword arguments:
1158 expired_too -- If true, lists all expired numbers too.
1159
1160 """
1161 url = _get_url(self.base_url, 'ListInboxes', self.api_credentials, expired_too=expired_too, shared_too=shared_too)
1162 return _get(self.http, url)
1163
1164 - def list_orders(self, current_page=None, items_per_page=None):
1165 """Returns a list of orders for this user"""
1166 url = _get_url(self.base_url, 'ListOrders', self.api_credentials, current_page=current_page, items_per_page=items_per_page)
1167 return _get(self.http, url)
1168
1170 """Read the full profile of the user."""
1171 url = _get_url(self.base_url, 'ListProfiles', self.api_credentials)
1172 return _get(self.http, url)
1173
1175 """Returns a list of user-agents the user has used to sent faxes.
1176
1177 List will be sorted by amount of faxes sent, so it is a top max list.
1178
1179 Keyword arguments:
1180 max -- How many results (5-20, default 5)
1181
1182 """
1183 url = _get_url(self.base_url, 'ListUserAgents', self.api_credentials, max=max)
1184 return _get(self.http, url)
1185
1187 """Returns a list of activities for the user
1188
1189 This list contains report about what has been happened lately in users account
1190 (like messages sent to the user, faxes sent, faxes received, orders placed, ...)
1191
1192 Keyword arguments:
1193 count -- The count of items to return. Valid values are between 1 and 100
1194 data_to_list -- Any message types you want this function to return. Allowed models are 'faxsent', 'faxin', 'faxout', 'payment', 'message' and 'news'. Leave empty to get messages of any type.
1195
1196 """
1197 url = _get_url(self.base_url, 'ListWallMessages', self.api_credentials, count=count, data_to_list=data_to_list)
1198 return _get(self.http, url)
1199
1200 - def save_user(self, user=None, profile=None):
1201 """Saves user profile
1202
1203 Keyword arguments:
1204 user -- Users settings as associative array
1205 profile -- UserProfiles properties as associative array
1206
1207 """
1208 url = _get_url(self.base_url, 'SaveUser', self.api_credentials, user=user, profile=profile)
1209 return _get(self.http, url)
1210
1211 - def send_message(self, body, type=None, recipient=None, subject=None):
1212 """Send a message to the user
1213
1214 Arguments:
1215 body -- The message body
1216
1217 Keyword arguments:
1218 type -- Type of message to send. Currently implemented: email, skypechat or sms
1219 recipient -- Recipient of the message. Might be an email address, IM username or phone number depending on the message type
1220 subject -- Optionally a subject. Not used in all message types (likely not used in SMS and chat)
1221
1222 """
1223 url = _get_url(self.base_url, 'SendMessage', self.api_credentials, body=body, type=type, recipient=recipient, subject=subject)
1224 return _get(self.http, url)
1225
1227 """Send a password reset message to a user
1228
1229 Arguments:
1230 username -- PamFax username to send the message to
1231
1232 """
1233 url = _get_url(self.base_url, 'SendPasswordResetMessage', self.api_credentials, username=username, user_ip=user_ip)
1234 return _get(self.http, url)
1235
1237 """Sets users OnlineStorage settings.
1238
1239 Expects the settings to be given as key-value pairs.
1240 Currently supported settings are:
1241 - inbox_enabled: Store incoming faxes (0|1, required)
1242 - inbox_path: Path to store incoming faxes to (path as string folders separated by '/', leading and trailing '/' optional, required)
1243
1244 Arguments:
1245 provider -- Provider store settings for (see OnlineStorageApi::ListProviders)
1246 settings -- Key-value pairs of settings.
1247
1248 """
1249 url = _get_url(self.base_url, 'SetOnlineStorageSettings', self.api_credentials, provider=provider, settings=settings)
1250 return _get(self.http, url)
1251
1252 - def set_password(self, password, hashFunction=None, old_password=None):
1253 """Set a new login password for the currently logged in user.
1254
1255 You may use md5 encrypted passwords by setting the value of hashFunction to 'md5'.
1256 Note: password values must be lower case when using a hashFunction other than 'plain'!
1257
1258 Arguments:
1259 password -- The new password. Needs to be between 6 and 60 chars long
1260
1261 Keyword arguments:
1262 hashFunction -- The function used to enrycpt the password. Allowed values: plain or md5.
1263 old_password -- The current password. This is optional for the moment but will be required in future versions. Note that the $hashFunction value applies to this argument too.
1264
1265 """
1266 url = _get_url(self.base_url, 'SetPassword', self.api_credentials, password=password, hashFunction=hashFunction, old_password=old_password)
1267 return _get(self.http, url)
1268
1270 """Saves values to an extended user profile
1271
1272 Users may have different profiles. Use this method to store values in them.
1273 Profiles will be created if not present yet.
1274
1275 Arguments:
1276 properties -- key=>value pairs of all profiles properties to save
1277
1278 Keyword arguments:
1279 ignoreerrors -- If a field can not be found in the profile object, just ignore it. Otherwise returns an error
1280
1281 """
1282 url = _get_url(self.base_url, 'SetProfileProperties', self.api_credentials, profile=profile, properties=properties, ignoreerrors=ignoreerrors)
1283 return _get(self.http, url)
1284
1286 """Validate a username for a new user.
1287
1288 Returns a list of suggestions for the username if given username is already in use. Call this prior to UserInfo/CreateUser to show alternative usernames to the user if the entered username is already occupied or invalid.
1289
1290 Arguments:
1291 username -- Unique username to validate. Call will fail with bad_username error if the username already exists. Min 6 chars, max 60 chars.
1292
1293 """
1294 url = _get_url(self.base_url, 'ValidateNewUsername', self.api_credentials, username=username, dictionary=dictionary)
1295 return _get(self.http, url)
1296