def __init__(self, tenant = None, sessionId=None, endpoint=None, 
                 username=None, password=None, token=None, partner_wsdl=None):

        self.tenant = tenant
        self.sfclient = None
        self.db = None

        if partner_wsdl is None:
            partner_wsdl = os.path.join(os.path.dirname(__file__), "partnerwsdl.xml")

        if username and password:
            login = salesforce_oauth_request.login(username=username, password=password, 
                                                    token=token, cache_session=True)
            if 'access_token' in login:
                sessionId = login['access_token']
                endpoint = login['endpoint']
            else:
                raise RuntimeError("SF Login error: {0}".format(login))

        if sessionId:
            """This is the trick to use an OAuth access_token as the session id in the SOAP client."""
            self.h = SforcePartnerClient(partner_wsdl)

            self.h._sessionId = sessionId
            self.h._setEndpoint(endpoint)
            header = self.h.generateHeader('SessionHeader')
            header.sessionId = sessionId
            self.h.setSessionHeader(header)
            self.sfclient = self.h
예제 #2
0
 def __init__(self, token):
     self.token = token
     profile = requests.post(token.id_url, data={'access_token': self.token.access_token})
     self.partner_url = profile.json()['urls']['partner'].replace('{version}', '35.0')
     self.client = SforcePartnerClient('integrations/salesforce/partner.wsdl')
     self.force_oauth_login(self.token.access_token, self.partner_url)
     self.merge_batches = []
     self.merge_queue = []
     self.log = open_s3(token.user.email + '-merge_log', 'wb')
     self.log_writer = csv.writer(self.log)
     self.log_writer.writerow(['Record group', 'Record ID', 'Master ID', 'Canonical'])
     self.merge_count = 0
예제 #3
0
    def __get_partner_client(self):
        if int(float(util.SFDC_API_VERSION)) >= 29:
            wsdl_location = os.path.join(util.WSDL_PATH, 'partner-29.xml')
        else:
            wsdl_location = os.path.join(util.WSDL_PATH, 'partner.xml')
        try:
            if os.path.exists(os.path.join(config.project.location,'config','partner.xml')):
                wsdl_location = os.path.join(config.project.location,'config','partner.xml')
        except:
            pass
        client = SforcePartnerClient(
            wsdl_location, 
            apiVersion=util.SFDC_API_VERSION, 
            environment=self.org_type, 
            sid=self.sid, 
            metadata_server_url=self.metadata_server_url, 
            server_url=self.endpoint)

        callOptions = client.generateHeader('CallOptions')
        callOptions.client = self.client_name
        client.setCallOptions(callOptions)
        return client
예제 #4
0
    def __get_partner_client(self):
        wsdl_location = os.path.join(mm_util.WSDL_PATH, 'partner.xml')
        try:
            if os.path.exists(
                    os.path.join(config.connection.project.location, 'config',
                                 'partner.xml')):
                wsdl_location = os.path.join(
                    config.connection.project.location, 'config',
                    'partner.xml')
        except:
            pass

        return SforcePartnerClient(
            wsdl_location,
            apiVersion=mm_util.SFDC_API_VERSION,
            environment=self.org_type,
            sid=self.sid,
            metadata_server_url=self.metadata_server_url,
            server_url=self.endpoint)
	def pushToSFUsingWS(self):
		self.log.info("In pushToSFUsingWS method")
		from sforce.partner import SforcePartnerClient	
	
		self.login = "******"
		self.password = "******"
		self.securityToken = "XXXXXXXXXXX"
		safety = self.config.get('security', 'safety').strip()
                self.log.info("Safety field : %s When safety = on use Decrypt to decode the credentials"%safety)
                if safety == "on":
                        self.login = self.config.get('credentials', 'login')
                        self.password = self.config.get('credentials', 'password')
                        self.securityToken = self.config.get('credentials', 'securityToken')
                        self.log.info("Encrypted -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))
                        self.dec = Decrypt(self.configFile)
                        self.login = self.dec.decode(self.login)
                        self.password = self.dec.decode(self.password)
                        self.securityToken = self.dec.decode(self.securityToken)
                        self.log.info("Decrypted -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))

                self.log.info("Actual Credentials -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))		
		self.client = SforcePartnerClient(self.partnerWSDL)
		loginResponse = self.logIn(self.login, self.password, self.securityToken)
		if loginResponse == self.FAILED:
			return self.FAILED
		response = self.createLeadUsingWS()
		if response == self.FAILED:
			return self.FAILED
		else:
			self.log.info("Operation on lead successful!. %s"%response)		
		leadId = response.id
		response = self.upsertLeadUsingWS(leadId)
		if response == self.FAILED:
			return self.FAILED
		else:
			self.log.info("Operation on lead successful!. %s"%response)		
		logoutResponse = self.logOut()
		if logoutResponse == self.FAILED:
			return self.FAILED
예제 #6
0
 def connect2SForce(self):
     self.env.log.debug('--- Called connect2SForce: %s, %s, %s, %s' % \
       (self.username, self.password, self.sectoken, self.wsdlPath))
     self.sf = SforcePartnerClient(self.wsdlPath)
     self.sf.login(self.username, self.password, self.sectoken)
예제 #7
0
class Ticket2SForce(Component):
    implements(ITicketManipulator, ITicketChangeListener)

    # map Trac ticket field names to Salesforce custom object Ticket__c field names
    fieldMap = \
      {'id': 'Trac_Ticket_Id__c',
       'status': 'Status__c',
       'summary': 'Summary__c',
       'reporter': 'Reporter__c',
       'cc': 'Cc__c',
       'changetime': 'Last_Update_Time__c',
       'time': 'Time__c',
       'description': 'Description__c',
       'component': 'Component__c',
       'priority': 'Priority__c',
       'owner': 'Owner_cc',
       'version': 'Version__c',
       'milestone': 'Milestone__c',
       'keywords': 'Keywords__c',
       'type': 'Type__c'}

    def connect2SForce(self):
        self.env.log.debug('--- Called connect2SForce: %s, %s, %s, %s' % \
          (self.username, self.password, self.sectoken, self.wsdlPath))
        self.sf = SforcePartnerClient(self.wsdlPath)
        self.sf.login(self.username, self.password, self.sectoken)
        #self.env.log.debug('**** SessionId: ' + self.sf._sessionHeader.sessionId)

    def __init__(self):
        self.env.log.debug('--------------- Ticket2SForce init')
        self.wsdlPath = 'file://' + self.env.config.getpath(
            'ticket2sforce', 'wsdl')
        self.username = self.config.get('ticket2sforce', 'username', '')
        self.password = self.config.get('ticket2sforce', 'password', '')
        self.sectoken = self.config.get('ticket2sforce', 'sectoken', '')
        self.delete_closed_ticket = self.config.get('ticket2sforce',
                                                    'delete_closed_ticket',
                                                    'false')
        self.connect2SForce()

    def prepare_ticket(self, req, ticket, fields, actions):
        """Not currently called, but should be provided for future
    compatibility.
    """

    def validate_ticket(self, req, ticket):
        """Validate a ticket after it's been populated from user input.
    Must return a list of `(field, message)` tuples, one for each problem
    """
        self.env.log.debug("******** Called validate_ticket ***")
        caseNumber = ticket['case_number']
        if caseNumber == None or len(caseNumber) < 1:
            return [('case_number', 'case_number is required')]

        qstr = u"select Id, CaseNumber from Case where CaseNumber = '%s'" \
          % (caseNumber)
        result = self.sf.query(qstr)
        if result.size < 1:
            return [('case_number', 'case_number is not in the configured Org')
                    ]

        self.caseId = result.records[0].Id
        return []

    def createCaseTicketLink(self, caseId, ticketId):
        """
      Create M2M link Case <==> Ticket
    """
        link = self.sf.generateObject('CaseTicketLink__c')
        link.Case__c = caseId
        link.Ticket__c = ticketId
        result = self.sf.create(link)

        if result.success != True:
            msg = "Error: Can't create CaseTicketLink record for %s, result was %s" \
              % (str(link), result)
            raise Exception(msg)
        return result

    def createComment(self, author, comment_text):
        """
    Create Comment_cc and link object, to be linked to Ticket__cc
    """
        comment = self.sf.generateObject('Comment__c')
        comment.Author__c = author
        comment.Comment__c = comment_text
        result = self.sf.create(comment)

        if result.success != True:
            msg = "Error: Can't create Comment record for %s, result was %s" \
              % (str(link), result)
            raise Exception(msg)
        return result

    def createTicketCommentLink(self, ticketId, commentId):
        """
      Create M2M link Ticket <==> Comment
    """
        link = self.sf.generateObject('TicketCommentLink__c')
        link.Ticket__c = ticketId
        link.Comment__c = commentId
        result = self.sf.create(link)

        if result.success != True:
            msg = "Error: Can't create TicketCommentLink record for %s, result was %s" \
              % (str(link), result)
            raise Exception(msg)
        return result

    def createTicket(self, record):
        """
      Create a Ticket__c record, associated with the ticket in Trac
    """
        ticket = self.sf.generateObject('Ticket__c')
        ticket.Trac_Ticket_Id__c = record.id
        ticket.Name = record.id
        ticket.Status__c = record['status']
        ticket.Summary__c = record['summary']
        ticket.Reporter__c = record['reporter']
        ticket.Cc__c = record['cc']
        ticket.Last_Update_Time__c = record['changetime'].isoformat()
        ticket.Time__c = record['time'].isoformat()
        ticket.Description__c = record['description']
        ticket.Component__c = record['component']
        ticket.Priority__c = record['priority']
        ticket.Owner__c = record['owner']
        ticket.Version__c = record['version']
        ticket.Milestone__c = record['milestone']
        ticket.Keywords__c = record['keywords']
        ticket.Type__c = record['type']
        result = self.sf.create(ticket)

        if result.success != True:
            msg = "Error: Can't create Ticket record for %s, result was %s" \
              % (str(record), result)
            raise Exception(msg)

        return result

    def updateTicket(self, ticketId, ticket, old_values):
        """
      Update existing Ticket - only fields that changed
    """

        fieldList = ','.join(
            [Ticket2SForce.fieldMap[fld] for fld in old_values.iterkeys()])
        sfTicket = self.sf.retrieve(fieldList, 'Ticket__c', ticketId)
        for fld in old_values.iterkeys():
            sfTicket[Ticket2SForce.fieldMap[fld]] = ticket.values[fld]

        result = self.sf.update(sfTicket)

        if result.success != True:
            msg = "Error: Can't update Ticket record for %s, result was %s" \
              % (str(sfTicket), result)
            raise Exception(msg)

        return result

    def create_sfticket(self, ticket):
        self.env.log.debug('--------------- create_sfticket')
        self.env.log.debug(ticket['priority'])
        result = self.createTicket(ticket)
        ticketId = result.id
        result = self.createCaseTicketLink(self.caseId, ticketId)

    def change_sfticket(self, ticket, comment, author, old_values):
        self.env.log.debug('--------------- change_sfticket')
        qstr = u"select Id, Trac_Ticket_Id__c from Ticket__c where Trac_Ticket_Id__c = '%s'" \
          % (ticket.id)
        result = self.sf.query(qstr)
        if result.size < 1:
            msg = "Error: Can't locate Ticket record for %s, result was %s" \
              % (str(ticket), result)
            raise Exception(msg)

        ticketId = result.records[0].Id
        ticketNumber = result.records[0].Trac_Ticket_Id__c

        if len(comment) > 0:
            result = self.createComment(author, comment)
            commentId = result.id
            result = self.createTicketCommentLink(ticketId, commentId)
        if len(old_values) > 0:
            self.updateTicket(ticketId, ticket, old_values)

    def complete_sfticket(self, ticket):
        self.env.log.debug('--------------- complete_sfticket')
        #self.rtm_instance.complete_task(ticket)

    # ITicketChangeListener
    def ticket_created(self, ticket):
        #self.env.log.debug("*** ticket: %d: %s %s\n" % (ticket.id, type(ticket.values['changetime']), str(ticket.values)))
        #for key, value in ticket.values.iteritems():
        #   self.env.log.debug("    %s: %s\n" % (key, value))
        self.create_sfticket(ticket)

    def ticket_changed(self, ticket, comment, author, old_values):
        self.env.log.debug('################ ticket_changed')
        self.env.log.debug('>>>>>>>>>> ' + comment)
        self.env.log.debug(ticket['status'])
        self.env.log.debug(old_values)
        #for key, value in old_values.iteritems():
        #  self.env.log.debug("    %s: %s\n" % (key, value))

        for key, value in ticket.values.iteritems():
            self.env.log.debug("    %s: %s" % (key, value))

        if ticket['status'] == 'closed' and old_values['status'] != 'closed':
            self.complete_sfticket(ticket)
        else:
            self.change_sfticket(ticket, comment, author, old_values)

    def ticket_deleted(self, ticket):
        self.env.log.debug('################ ticket_deleted')
        self.complete_sfticket(ticket)
예제 #8
0
class SalesforceSOAP(object):
    def __init__(self, token):
        self.token = token
        profile = requests.post(token.id_url, data={'access_token': self.token.access_token})
        self.partner_url = profile.json()['urls']['partner'].replace('{version}', '35.0')
        self.client = SforcePartnerClient('integrations/salesforce/partner.wsdl')
        self.force_oauth_login(self.token.access_token, self.partner_url)
        self.merge_batches = []
        self.merge_queue = []
        self.log = open_s3(token.user.email + '-merge_log', 'wb')
        self.log_writer = csv.writer(self.log)
        self.log_writer.writerow(['Record group', 'Record ID', 'Master ID', 'Canonical'])
        self.merge_count = 0

    def refresh_token(self):
        self.token.refresh()
        self.force_oauth_login(self.token.access_token, self.partner_url)

    def force_oauth_login(self, access_token, soap_endpoint):
        self.client._setHeaders('login')
        header = self.client.generateHeader('SessionHeader')
        header.sessionId = access_token
        self.client.setSessionHeader(header)
        self.client._sessionId = access_token
        self.client._setEndpoint(soap_endpoint)

    def append_merge(self, merge_request):
        self.merge_queue.append(merge_request)
        if len(self.merge_queue) > 6:
            self.merge_batches.append(self.merge_queue)
            self.merge_queue = []

    def commit_merges(self):
        if self.merge_queue:
            self.merge_batches.append(self.merge_queue)
        self.merge_queue = []

        for batch in self.merge_batches:
            self.refresh_token()

            try:
                result = self.client.merge(batch)
            except Exception as e:
                print 'SF SOAP merge batch failed with message: {0}'.format(e.message)  # TODO: log this somewhere
                yield []
            else:
                yield result

    def merge_group(self, group, canonical, updateable):
        self.merge_count += 1
        master = self.client.generateObject('Lead')
        master.Id = group[0]['Id'].decode('utf-8')
        for key, value in canonical.viewitems():
            if value and key in updateable:
                value = value.decode('utf-8')
                setattr(master, key, value)
        self.log_writer.writerow([self.merge_count, group[0]['Id'], '', json.dumps(canonical)])
        for i in range(1, len(group), 2):
            merge_request = self.client.generateObject('MergeRequest')
            merge_request.masterRecord = master
            merge_request.recordToMergeIds = [group[i]['Id'].decode('utf-8')]
            self.log_writer.writerow([self.merge_count, group[i]['Id'], master.Id, json.dumps(canonical)])
            try:
                merge_request.recordToMergeIds.append(group[i + 1]['Id'].decode('utf-8'))
                self.log_writer.writerow([self.merge_count, group[i + 1]['Id'], master.Id, json.dumps(canonical)])
            except IndexError:
                pass
            self.append_merge(merge_request)
class SalesforceBatch(object):
    def __init__(self, tenant = None, sessionId=None, endpoint=None, 
                 username=None, password=None, token=None, partner_wsdl=None):

        self.tenant = tenant
        self.sfclient = None
        self.db = None

        if partner_wsdl is None:
            partner_wsdl = os.path.join(os.path.dirname(__file__), "partnerwsdl.xml")

        if username and password:
            login = salesforce_oauth_request.login(username=username, password=password, 
                                                    token=token, cache_session=True)
            if 'access_token' in login:
                sessionId = login['access_token']
                endpoint = login['endpoint']
            else:
                raise RuntimeError("SF Login error: {0}".format(login))

        if sessionId:
            """This is the trick to use an OAuth access_token as the session id in the SOAP client."""
            self.h = SforcePartnerClient(partner_wsdl)

            self.h._sessionId = sessionId
            self.h._setEndpoint(endpoint)
            header = self.h.generateHeader('SessionHeader')
            header.sessionId = sessionId
            self.h.setSessionHeader(header)
            self.sfclient = self.h

    @property
    def sessionId(self):
        return self.h._sessionId

    @property
    def endpoint(self):
        return self.h._location

    @property
    def host(self):
        o = urlparse.urlparse(self.h._location)
        return o.hostname.replace("-api","")

    def sf_client(self):
        """

        @return: SforcePartnerClient
        """
        # if not self.sfclient:
        #     system = self.tenant.default_salesforce
        #     sfadapter = SFAdapter.init_from_system(system)
        #     sfadapter.login()
        #     self.sfclient = sfadapter.h

        return self.sfclient

    def query_salesforce(self, object_name, fields=["Id"], limit = 200, where=None):
        client = self.sf_client()
        clauses = ["IsDeleted = False"] if object_name != "User" else []
        if where:
            clauses.append(where)

        if len(clauses) > 0:
            where = "WHERE %s" % " AND ".join(clauses)
        else:
            where = ""

        return client.queryAll("SELECT %s from %s %s LIMIT %d" % (",".join(fields), object_name, where, limit))

    def query_salesforce_id_set(self, object_name, count, where=None):
        client = self.sf_client()

        qOpts = client.generateHeader('QueryOptions')
        qOpts.batchSize = 200
        client.setQueryOptions(qOpts)

        clauses = [] if object_name == 'User' else ["IsDeleted = False"]
        if where:
            clauses.append(where)

        if len(clauses) > 0:
            where = "WHERE %s" % " AND ".join(clauses)
        else:
            where = ""

        results = client.queryAll("SELECT Id from %s %s LIMIT %d" % (object_name, where, count))
        ids = [r.Id for r in results.records if hasattr(r, 'Id')]
        while not results.done:
            results = client.queryMore(results.queryLocator)
            ids += [r.Id for r in results.records if hasattr(r, 'Id')]

        return ids

    def batches(self, items):
        for x in range(0, len(items), 200):
            yield items[x:x+200]

    def batch_client(self, service, items):
        client = self.sf_client()
        results = []
        for tranch in self.batches(items):
            results += getattr(client, service)(tranch)

        return results

    def update_salesforce(self, object_name, **kwargs):
        client = self.sf_client()

        limit = kwargs.pop('limit', 10)
        where = kwargs.pop('where', None)
        updates = []

        for id in self.query_salesforce_id_set(object_name, limit, where=where):
            record = client.generateObject(object_name)
            record.Id = id
            for field, val in kwargs.iteritems():
                setattr(record, field, val)
            updates.append(record)

        uresult = self.batch_client('update', updates)
        self.show_results(uresult)

    def show_results(self, sf_results):
        try:
            if not isinstance(sf_results, list):
                sf_results = [sf_results]
            updated_ids = [r.id for r in sf_results if hasattr(r, 'id')]

            print "Updated: %s" % updated_ids

            err_results = [r for r in sf_results if not r.success]
            msgs = [er.errors[0].message for er in err_results]
            if len(msgs) > 0:
                print "WARNING, SF UPDATE RETURNED ERRORS:"
                print msgs
        except:
            print sf_results

    def insert_salesforce(self, object_name, values_list):
        if isinstance(values_list, basestring):
            values_list = yaml.load(values_list)
        client = self.sf_client()

        inserts = []
        for values in values_list:
            record = client.generateObject(object_name)
            for field, val in values.iteritems():
                setattr(record, field, val)
            inserts.append(record)

        results = self.batch_client('create', inserts)
        self.show_results(results)

    def delete_salesforce(self, object_name, ids_or_count, where=None):
        client = self.sf_client()

        if isinstance(ids_or_count, (int,long)):
            ids_or_count = self.query_salesforce_id_set(object_name, ids_or_count, where=where)

        if isinstance(ids_or_count, list):
            results = self.batch_client('delete', ids_or_count)
            self.show_results(results)

        else:
            raise ValueError("Invalid arg ids_or_count")


    def copy_object(self, source, target):
        fields = subprocess.check_output(("force field list %s" % source).split())
        fields = fields.split("\n")
        bads = ['reference','email','date','id']
        good = []
        for f in fields:
            if len([t for t in bads if f.startswith(t) or f.endswith(t) or (t+" ") in f]) > 0:
                print "Skipping field: %s" % f
            else:
                good.append(f)
        fields = good
        fields = ["%s:%s" % (m.group(1), m.group(3)) if m else "" for m in (re.match(r"(\w+?)(__c)?:\s*(\w+)", f) for f in fields)]
        cmd = "force sobject create %s %s" % (target, fields[0])
        print cmd
        try:
            print subprocess.check_output(cmd, shell=True)
        except subprocess.CalledProcessError, e:
            print e

        for f in fields[1:]:
            cmd = "force field create %s__c %s" % (target, f)
            print cmd
            try:
                print subprocess.check_output(cmd, shell=True)
            except subprocess.CalledProcessError, e:
                print e
class SforcePartnerClientTest(test_base.SforceBaseClientTest):
  wsdlFormat = 'Partner'
  h = None

  def setUp(self):
    if self.h is None:
      self.h = SforcePartnerClient('../partner.wsdl.xml')
      self.h.login(test_config.USERNAME, test_config.PASSWORD, test_config.TOKEN)

  def testSearchOneResult(self):
    result = self.h.search('FIND {Single User} IN Name Fields RETURNING Lead(Name, Phone, Fax, Description, DoNotCall)')

    self.assertEqual(len(result.searchRecords), 1)
    self.assertEqual(result.searchRecords[0].record.Name, 'Single User')
    # it's not a string, it's a SAX Text object, but it can be cast to a string
    # just need to make sure it's not a bool
    self.assertTrue(result.searchRecords[0].record.DoNotCall in ('false', 'true'))
    # make sure we get None and not ''
    self.assertEqual(result.searchRecords[0].record.Description, None)


  def testSearchManyResults(self):
    result = self.h.search(u'FIND {Joë Möke} IN Name Fields RETURNING Lead(Name, Phone, DoNotCall, Company)')

    self.assertTrue(len(result.searchRecords) > 1)
    for searchRecord in result.searchRecords:
      self.assertEqual(searchRecord.record.Name, u'Joë Möke')
      self.assertEqual(searchRecord.record.Company, u'你好公司')
      self.assertTrue(searchRecord.record.DoNotCall in ('false', 'true'))

  def testUpdateOneFieldToNull(self):
    self.setHeaders('update')

    (result, lead) = self.createLead(True)

    lead.fieldsToNull = ('Email')
    lead.Email = None

    result = self.h.update(lead)
    self.assertTrue(result.success)
    self.assertEqual(result.id, lead.Id)

    result = self.h.retrieve('FirstName, LastName, Company, Email', 'Lead', (lead.Id))
    self.assertEqual(result.FirstName, u'Joë')
    self.assertEqual(result.LastName, u'Möke')
    self.assertEqual(result.Company, u'你好公司')
    self.assertEqual(result.Email, None)

  def testUpdateTwoFieldsToNull(self):
    self.setHeaders('update')

    (result, lead) = self.createLead(True)

    lead.fieldsToNull = ('FirstName', 'Email')
    lead.Email = None
    lead.FirstName = None

    result = self.h.update(lead)
    self.assertTrue(result.success)
    self.assertEqual(result.id, lead.Id)

    result = self.h.retrieve('FirstName, LastName, Company, Email', 'Lead', (lead.Id))

    self.assertEqual(result.FirstName, None)
    self.assertEqual(result.LastName, u'Möke')
    self.assertEqual(result.Email, None)
예제 #11
0
 def login(self, wsdl, username, password, token):
     self.client = SforcePartnerClient(wsdl)
     self.client.login(username, password, token)
예제 #12
0
 def connect2SForce(self):
   self.env.log.debug('--- Called connect2SForce: %s, %s, %s, %s' % \
     (self.username, self.password, self.sectoken, self.wsdlPath))
   self.sf = SforcePartnerClient(self.wsdlPath)
   self.sf.login(self.username, self.password, self.sectoken)
예제 #13
0
class Ticket2SForce(Component):
  implements(ITicketManipulator, ITicketChangeListener)
  
  # map Trac ticket field names to Salesforce custom object Ticket__c field names 
  fieldMap = \
    {'id': 'Trac_Ticket_Id__c',
     'status': 'Status__c',
     'summary': 'Summary__c',
     'reporter': 'Reporter__c',
     'cc': 'Cc__c',
     'changetime': 'Last_Update_Time__c',
     'time': 'Time__c',
     'description': 'Description__c',
     'component': 'Component__c',
     'priority': 'Priority__c',
     'owner': 'Owner_cc',
     'version': 'Version__c',
     'milestone': 'Milestone__c',
     'keywords': 'Keywords__c',
     'type': 'Type__c'}
      
  def connect2SForce(self):
    self.env.log.debug('--- Called connect2SForce: %s, %s, %s, %s' % \
      (self.username, self.password, self.sectoken, self.wsdlPath))
    self.sf = SforcePartnerClient(self.wsdlPath)
    self.sf.login(self.username, self.password, self.sectoken)
    #self.env.log.debug('**** SessionId: ' + self.sf._sessionHeader.sessionId)
    
  def __init__(self):
    self.env.log.debug('--------------- Ticket2SForce init')
    self.wsdlPath = 'file://' + self.env.config.getpath('ticket2sforce', 'wsdl')
    self.username = self.config.get('ticket2sforce', 'username', '')
    self.password = self.config.get('ticket2sforce', 'password', '')
    self.sectoken = self.config.get('ticket2sforce', 'sectoken', '')
    self.delete_closed_ticket = self.config.get('ticket2sforce', 'delete_closed_ticket', 'false')
    self.connect2SForce()

  def prepare_ticket(self, req, ticket, fields, actions):
    """Not currently called, but should be provided for future
    compatibility.
    """

  def validate_ticket(self, req, ticket):
    """Validate a ticket after it's been populated from user input.
    Must return a list of `(field, message)` tuples, one for each problem
    """
    self.env.log.debug("******** Called validate_ticket ***")
    caseNumber = ticket['case_number']
    if caseNumber == None or len(caseNumber) < 1:
      return [('case_number', 'case_number is required')]
    
    qstr = u"select Id, CaseNumber from Case where CaseNumber = '%s'" \
      % (caseNumber)
    result = self.sf.query(qstr)
    if result.size < 1:
      return [('case_number', 'case_number is not in the configured Org')]

    self.caseId = result.records[0].Id
    return []
  
  def createCaseTicketLink(self, caseId, ticketId):
    """
      Create M2M link Case <==> Ticket
    """
    link           = self.sf.generateObject('CaseTicketLink__c') 
    link.Case__c   = caseId
    link.Ticket__c = ticketId
    result         = self.sf.create(link)
    
    if result.success != True:
      msg = "Error: Can't create CaseTicketLink record for %s, result was %s" \
        % (str(link), result)      
      raise Exception(msg)
    return result
   
  def createComment(self, author, comment_text):
    """
    Create Comment_cc and link object, to be linked to Ticket__cc
    """
    comment             = self.sf.generateObject('Comment__c')
    comment.Author__c   = author
    comment.Comment__c  = comment_text
    result              = self.sf.create(comment)
    
    if result.success != True:
      msg = "Error: Can't create Comment record for %s, result was %s" \
        % (str(link), result)      
      raise Exception(msg)
    return result   
      
  def createTicketCommentLink(self, ticketId, commentId):
    """
      Create M2M link Ticket <==> Comment
    """
    link            = self.sf.generateObject('TicketCommentLink__c') 
    link.Ticket__c  = ticketId
    link.Comment__c = commentId
    result          = self.sf.create(link)
    
    if result.success != True:
      msg = "Error: Can't create TicketCommentLink record for %s, result was %s" \
        % (str(link), result)      
      raise Exception(msg)
    return result   
  
  def createTicket(self, record):
    """
      Create a Ticket__c record, associated with the ticket in Trac
    """
    ticket                      = self.sf.generateObject('Ticket__c')
    ticket.Trac_Ticket_Id__c    = record.id
    ticket.Name                 = record.id
    ticket.Status__c            = record['status']
    ticket.Summary__c           = record['summary']
    ticket.Reporter__c          = record['reporter']
    ticket.Cc__c                = record['cc']
    ticket.Last_Update_Time__c  = record['changetime'].isoformat()
    ticket.Time__c              = record['time'].isoformat()
    ticket.Description__c       = record['description']
    ticket.Component__c         = record['component']
    ticket.Priority__c          = record['priority']
    ticket.Owner__c             = record['owner']
    ticket.Version__c           = record['version']
    ticket.Milestone__c         = record['milestone']
    ticket.Keywords__c          = record['keywords']
    ticket.Type__c              = record['type']
    result                      = self.sf.create(ticket)

    if result.success != True:
      msg = "Error: Can't create Ticket record for %s, result was %s" \
        % (str(record), result)      
      raise Exception(msg)

    return result

  def updateTicket(self, ticketId, ticket, old_values):
    """
      Update existing Ticket - only fields that changed
    """
    
    fieldList = ','.join([Ticket2SForce.fieldMap[fld] for fld in old_values.iterkeys()]) 
    sfTicket = self.sf.retrieve(fieldList, 'Ticket__c', ticketId)
    for fld in old_values.iterkeys():
      sfTicket[Ticket2SForce.fieldMap[fld]] = ticket.values[fld]
    
    result = self.sf.update(sfTicket)

    if result.success != True:
      msg = "Error: Can't update Ticket record for %s, result was %s" \
        % (str(sfTicket), result)      
      raise Exception(msg)

    return result  

  def create_sfticket(self, ticket):
    self.env.log.debug('--------------- create_sfticket')
    self.env.log.debug(ticket['priority'])
    result = self.createTicket(ticket)
    ticketId = result.id
    result = self.createCaseTicketLink(self.caseId, ticketId)
    
  def change_sfticket(self, ticket, comment, author, old_values):
    self.env.log.debug('--------------- change_sfticket')
    qstr = u"select Id, Trac_Ticket_Id__c from Ticket__c where Trac_Ticket_Id__c = '%s'" \
      % (ticket.id)
    result = self.sf.query(qstr)
    if result.size < 1:    
      msg = "Error: Can't locate Ticket record for %s, result was %s" \
        % (str(ticket), result)      
      raise Exception(msg)
          
    ticketId = result.records[0].Id
    ticketNumber = result.records[0].Trac_Ticket_Id__c
    
    if len(comment) > 0:
      result = self.createComment(author, comment)   
      commentId = result.id
      result = self.createTicketCommentLink(ticketId, commentId)
    if len(old_values) > 0:
      self.updateTicket(ticketId, ticket, old_values)   
        
  def complete_sfticket(self, ticket):
    self.env.log.debug('--------------- complete_sfticket')
    #self.rtm_instance.complete_task(ticket)

  # ITicketChangeListener
  def ticket_created(self, ticket):
    #self.env.log.debug("*** ticket: %d: %s %s\n" % (ticket.id, type(ticket.values['changetime']), str(ticket.values)))
    #for key, value in ticket.values.iteritems():
    #   self.env.log.debug("    %s: %s\n" % (key, value))
    self.create_sfticket(ticket)

  def ticket_changed(self, ticket, comment, author, old_values):
    self.env.log.debug('################ ticket_changed')
    self.env.log.debug('>>>>>>>>>> ' + comment)
    self.env.log.debug(ticket['status'])
    self.env.log.debug(old_values)
    #for key, value in old_values.iteritems():
    #  self.env.log.debug("    %s: %s\n" % (key, value))
      
    for key, value in ticket.values.iteritems():
      self.env.log.debug("    %s: %s" % (key, value))
      
    if ticket['status'] == 'closed' and old_values['status'] != 'closed':
      self.complete_sfticket(ticket)
    else:
      self.change_sfticket(ticket, comment, author, old_values)

  def ticket_deleted(self, ticket):
    self.env.log.debug('################ ticket_deleted')
    self.complete_sfticket(ticket)
 def setUp(self):
     if self.h is None:
         self.h = SforcePartnerClient('../partner.wsdl.xml')
         self.h.login(test_config.USERNAME, test_config.PASSWORD,
                      test_config.TOKEN)
class SforcePartnerClientTest(test_base.SforceBaseClientTest):
    wsdlFormat = 'Partner'
    h = None

    def setUp(self):
        if self.h is None:
            self.h = SforcePartnerClient('../partner.wsdl.xml')
            self.h.login(test_config.USERNAME, test_config.PASSWORD,
                         test_config.TOKEN)

    def testSearchOneResult(self):
        result = self.h.search(
            'FIND {Single User} IN Name Fields RETURNING Lead(Name, Phone, Fax, Description, DoNotCall)'
        )

        self.assertEqual(len(result.searchRecords), 1)
        self.assertEqual(result.searchRecords[0].record.Name, 'Single User')
        # it's not a string, it's a SAX Text object, but it can be cast to a string
        # just need to make sure it's not a bool
        self.assertTrue(result.searchRecords[0].record.DoNotCall in ('false',
                                                                     'true'))
        # make sure we get None and not ''
        self.assertEqual(result.searchRecords[0].record.Description, None)

    def testSearchManyResults(self):
        result = self.h.search(
            u'FIND {Joë Möke} IN Name Fields RETURNING Lead(Name, Phone, DoNotCall, Company)'
        )

        self.assertTrue(len(result.searchRecords) > 1)
        for searchRecord in result.searchRecords:
            self.assertEqual(searchRecord.record.Name, u'Joë Möke')
            self.assertEqual(searchRecord.record.Company, u'你好公司')
            self.assertTrue(searchRecord.record.DoNotCall in ('false', 'true'))

    def testUpdateOneFieldToNull(self):
        self.setHeaders('update')

        (result, lead) = self.createLead(True)

        lead.fieldsToNull = ('Email')
        lead.Email = None

        result = self.h.update(lead)
        self.assertTrue(result.success)
        self.assertEqual(result.id, lead.Id)

        result = self.h.retrieve('FirstName, LastName, Company, Email', 'Lead',
                                 (lead.Id))
        self.assertEqual(result.FirstName, u'Joë')
        self.assertEqual(result.LastName, u'Möke')
        self.assertEqual(result.Company, u'你好公司')
        self.assertEqual(result.Email, None)

    def testUpdateTwoFieldsToNull(self):
        self.setHeaders('update')

        (result, lead) = self.createLead(True)

        lead.fieldsToNull = ('FirstName', 'Email')
        lead.Email = None
        lead.FirstName = None

        result = self.h.update(lead)
        self.assertTrue(result.success)
        self.assertEqual(result.id, lead.Id)

        result = self.h.retrieve('FirstName, LastName, Company, Email', 'Lead',
                                 (lead.Id))

        self.assertEqual(result.FirstName, None)
        self.assertEqual(result.LastName, u'Möke')
        self.assertEqual(result.Email, None)
class PushToSF:
	
	def __init__(self,configFile=None):
		self.configFile=configFile;
		self.config = ConfigParser.ConfigParser()
		self.config.read(self.configFile)
		self.log = Logger.Logger(self.config)
		self.partnerWSDL = self.config.get('wsdl','partnerWSDL')
	        self.partnersandboxWSDL = self.config.get('wsdl','partnersandboxWSDL')
		self.SUCCESS, self.FAILED = 1, 0
		self.log.info("in Constructor of PushToSF")

	def pushToSFUsingWS(self):
		self.log.info("In pushToSFUsingWS method")
		from sforce.partner import SforcePartnerClient	
	
		self.login = "******"
		self.password = "******"
		self.securityToken = "XXXXXXXXXXX"
		safety = self.config.get('security', 'safety').strip()
                self.log.info("Safety field : %s When safety = on use Decrypt to decode the credentials"%safety)
                if safety == "on":
                        self.login = self.config.get('credentials', 'login')
                        self.password = self.config.get('credentials', 'password')
                        self.securityToken = self.config.get('credentials', 'securityToken')
                        self.log.info("Encrypted -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))
                        self.dec = Decrypt(self.configFile)
                        self.login = self.dec.decode(self.login)
                        self.password = self.dec.decode(self.password)
                        self.securityToken = self.dec.decode(self.securityToken)
                        self.log.info("Decrypted -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))

                self.log.info("Actual Credentials -> login : %s, password: %s, securityToken: %s"%(self.login, self.password, self.securityToken))		
		self.client = SforcePartnerClient(self.partnerWSDL)
		loginResponse = self.logIn(self.login, self.password, self.securityToken)
		if loginResponse == self.FAILED:
			return self.FAILED
		response = self.createLeadUsingWS()
		if response == self.FAILED:
			return self.FAILED
		else:
			self.log.info("Operation on lead successful!. %s"%response)		
		leadId = response.id
		response = self.upsertLeadUsingWS(leadId)
		if response == self.FAILED:
			return self.FAILED
		else:
			self.log.info("Operation on lead successful!. %s"%response)		
		logoutResponse = self.logOut()
		if logoutResponse == self.FAILED:
			return self.FAILED

		
	def logIn(self, login, password, securityToken):
		self.log.info("Logging in with credentials, login : %s , password : %s , securityToken : %s"%(login, password, securityToken))
		try:
			loginResult = self.client.login(login, password, securityToken)
		except Exception, e:
			self.log.info("Login Failed! Exception : %s"%str(e))
			return self.FAILED
		self.log.info("Log in successful")
		return self.SUCCESS
예제 #17
0
class AnalyticsCloudUploader(object):
    MAX_FILE_SIZE = 10 * 1024 * 1024

    def __init__(self, metadata, data, client=None):
        # XXX serve via public github? ok to publish?
        self.metadata = metadata
        self.data = data

        self.client = client
        self.parts = None

    def login(self, wsdl, username, password, token):
        self.client = SforcePartnerClient(wsdl)
        self.client.login(username, password, token)

    def upload(self, edgemart):
        output = StringIO()
        writer = AnalyticsWriter(output, encoding='utf-8')

        self.start(edgemart, self.metadata)

        biggest_record = 0
        for record in self.data:
            before_write = output.tell()
            writer.writerow(record)
            after_write = output.tell()
            record_size = after_write - before_write
            biggest_record = max(biggest_record, record_size * 2)

            if after_write + biggest_record > self.MAX_FILE_SIZE:
                output.seek(0)
                self.add_data(output)
                output.truncate(0)

        if output.tell():
            output.seek(0)
            self.add_data(output)

        self.complete()

    def start(self, edgemart, metadata):
        log.info('starting upload %s', edgemart)
        self.parts = []
        obj = self.client.generateObject('InsightsExternalData')
        obj.EdgemartAlias = edgemart
        obj.EdgemartContainer = ''
        obj.MetadataJson = b64encode(json.dumps(metadata))
        obj.Format = 'CSV'
        obj.Operation = 'Overwrite'
        obj.Action = None

        result = self.client.create(obj)
        if not result.success:
            raise ConnectionError(result)
        self.data_id = result.id

    def add_data(self, data):
        log.info('uploading chunk')
        obj = self.client.generateObject('InsightsExternalDataPart')
        obj.PartNumber = len(self.parts) + 1
        obj.InsightsExternalDataId = self.data_id
        obj.DataFile = b64encode(data.read())
        result = self.client.create(obj)
        if not result.success:
            raise ConnectionError(result)
        self.parts.append(result)

    def complete(self):
        log.info('upload complete')
        obj = self.client.generateObject('InsightsExternalData')
        obj.Id = self.data_id
        obj.Action = 'Process'
        result = self.client.update(obj)
        if not result.success:
            raise ConnectionError(result)
def sfdc():
    h = SforcePartnerClient('partner.wsdl')
    h.login(app.config['SALESFORCE_USERNAME'], app.config['SALESFORCE_PASSWORD'], app.config['SALESFORCE_TOKEN'])
    return h
예제 #19
0
class AnalyticsCloudUploader(object):
    MAX_FILE_SIZE = 10 * 1024 * 1024

    def __init__(self, metadata, data, client=None):
        # XXX serve via public github? ok to publish?
        self.metadata = metadata
        self.data = data

        self.client = client
        self.parts = None

    def login(self, wsdl, username, password, token):
        self.client = SforcePartnerClient(wsdl)
        self.client.login(username, password, token)

    def upload(self, edgemart):
        output = StringIO()
        writer = AnalyticsWriter(output, encoding='utf-8')

        self.start(edgemart, self.metadata)

        biggest_record = 0
        for record in self.data:
            before_write = output.tell()
            writer.writerow(record)
            after_write = output.tell()
            record_size = after_write - before_write
            biggest_record = max(biggest_record, record_size * 2)

            if after_write + biggest_record > self.MAX_FILE_SIZE:
                output.seek(0)
                self.add_data(output)
                output.truncate(0)

        if output.tell():
            output.seek(0)
            self.add_data(output)

        self.complete()

    def start(self, edgemart, metadata):
        log.info('starting upload %s', edgemart)
        self.parts = []
        obj = self.client.generateObject('InsightsExternalData')
        obj.EdgemartAlias = edgemart
        obj.EdgemartContainer = ''
        obj.MetadataJson = b64encode(json.dumps(metadata))
        obj.Format = 'CSV'
        obj.Operation = 'Overwrite'
        obj.Action = None

        result = self.client.create(obj)
        if not result.success:
            raise ConnectionError(result)
        self.data_id = result.id

    def add_data(self, data):
        log.info('uploading chunk')
        obj = self.client.generateObject('InsightsExternalDataPart')
        obj.PartNumber = len(self.parts) + 1
        obj.InsightsExternalDataId = self.data_id
        obj.DataFile = b64encode(data.read())
        result = self.client.create(obj)
        if not result.success:
            raise ConnectionError(result)
        self.parts.append(result)

    def complete(self):
        log.info('upload complete')
        obj = self.client.generateObject('InsightsExternalData')
        obj.Id = self.data_id
        obj.Action = 'Process'
        result = self.client.update(obj)
        if not result.success:
            raise ConnectionError(result)
예제 #20
0
 def login(self, wsdl, username, password, token):
     self.client = SforcePartnerClient(wsdl)
     self.client.login(username, password, token)
 def setUp(self):
   if self.h is None:
     self.h = SforcePartnerClient('../partner.wsdl.xml')
     self.h.login(test_config.USERNAME, test_config.PASSWORD, test_config.TOKEN)
예제 #22
0
import os
import logging

from sforce.partner import SforcePartnerClient

import settings

from apicli import ClientCmdWrapper, run

logging.getLogger('suds').setLevel(logging.INFO)

SFPARTNER_WSDL = os.path.join(os.path.dirname(__file__), 'partnerwsdl.xml')
# XXX Slow?
SFPARTNER_CLIENT = SforcePartnerClient(SFPARTNER_WSDL)


class SalesforceSOAPClient(object):
    def __init__(self, username, password, token):
        self.username = username
        self.password = password
        self.token = token
        self.client = SFPARTNER_CLIENT

    def login(self):
        """ login to SFDC """
        self.client.login(self.username, self.password, self.token)

    def queryAll(self, object_name, fields=None, where=''):
        """ Query for object_name in SFDC """
        if fields is None:
            fields = []