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
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 __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
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
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)
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)
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)
def login(self, wsdl, username, password, token): self.client = SforcePartnerClient(wsdl) self.client.login(username, password, token)
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
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
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 = []