@@ -0,0 +1,2709 @@
+import logging%0A%0Afrom tornado.httpclient import AsyncHTTPClient, HTTPRequest%0Afrom upload_util import encode_multipart_formdata%0A%0Alogger = logging.getLogger(__name__)%0A%0A%0Aclass ContactClient(object):%0A    '''%0A    Async HTTP client to make facilitate request sending to newebe contacts.%0A    '''%0A%0A    def __init__(self, activity):%0A        '''%0A        Register activity in which errors will be stored if a request to a%0A        contact failed.%0A        '''%0A        %0A        self.contacts = dict()%0A        self.client = AsyncHTTPClient()%0A        self.activity = activity%0A%0A%0A    def get(self, contact, path):%0A        '''%0A        Perform a GET request to given contact.%0A        '''%0A%0A        url = contact.url + path%0A        request = HTTPRequest(url)%0A        return self.client.fetch(self, request)%0A%0A%0A    def post(self, contact, path, body):%0A        '''%0A        Perform a POST request to given contact.%0A        '''%0A%0A        url = contact.url + path%0A        request = HTTPRequest(url, method=%22POST%22, body=body)%0A        self.contacts%5Brequest%5D = contact%0A        return self.client.fetch(request, self.on_contact_response)%0A%0A%0A    def post_files(self, contact, path, fields=%7B%7D, files=%7B%7D):%0A        '''%0A        Post file and fields to givent contact.%0A        '''%0A%0A        (contentType, body) = encode_multipart_formdata(fields=fields, %0A                                                        files=files)%0A        headers = %7B 'Content-Type': contentType %7D %0A%0A        url = contact.url + path%0A        request = HTTPRequest(url=url, method=%22POST%22, %0A                              body=body, headers=headers)%0A        self.contacts%5Brequest%5D = contact%0A        return self.client.fetch(request, self.on_contact_response)%0A%0A%0A    def delete(self, contact, path, body):%0A        '''%0A        Perform a DELETE request to given contact.%0A        '''%0A%0A        url = contact.url + path%0A        request = HTTPRequest(url, method=%22PUT%22, body=body)%0A        self.contacts%5Brequest%5D = contact%0A        return self.client.fetch(request, self.on_contact_response)%0A%0A%0A    def on_contact_response(self, response, **kwargs):%0A        '''%0A        Callback for requests sent to contacts. If error occurs it %0A        marks it inside the activity for which error occurs. Else %0A        it logs that micropost posting succeeds.%0A        '''%0A%0A        if response.error: %0A            logger.error(%22%22%22 Post picture to a contact failed, error infos %0A                             are stored inside activity.%22%22%22)            %0A            contact = self.contacts%5Bresponse.request%5D%0A            self.activity.add_error(contact)%0A            self.activity.save()%0A%0A        else: %0A            logger.info(%22Post successfully sent.%22)%0A        %0A        del self.contacts%5Bresponse.request%5D%0A%0A%0A

add tools to facilate communication with contacts