def updateFogbugzCases(site, username, password, ordered_changes, changemap, casemap, releasenotesmap): logging.info('Logging on to site ' + site + ' as user ' + username) fb = FogBugz('https://' + site + '.fogbugz.com/') fb.logon(username, password) logging.info('Updating fogbugz cases') for change in ordered_changes: logging.info(' Commit: ' + change) changetext = changemap[change] cases = casemap[change] # releasenotes = releasenotesmap[change] logging.info(' Cases: ' + str(cases)) logging.info(' Text: ' + changetext) # logging.info(' Release notes: ' + releasenotes) if cases: for case in cases: if hasChange(fb, case, change) == False: logging.info(' Updating case ' + str(case)) fb.edit(ixBug=case, sEvent=changetext) # fb.edit(ixBug=case, sReleaseNotes=releasenotes) else: logging.info(' Skipping case ' + str(case))
def editFBCase(site, username, password, case, change, changetext): fb = FogBugz('https://' + site + '.fogbugz.com/') fb.logon(username, password) logging.info('Updating fogbugz cases') fb.edit(ixBug=case, sEvent=changetext) fb.logoff()
def update_tickets(args): cols = [ "ixBug", "sStatus", "sTitle", 'sTags', "ixPersonOpenedBy", "dtOpened", "sProject", 'plugin_customfields', "latestEvent" ] fb = FogBugz('https://daily.manuscript.com/') fb.logon(args.email, args.password) query = {"status": "Active", "AssignedTo": "Unassigned"} querystring = " ".join(["{}:{}".format(k, v) for k, v in query.items()]) resp = fb.search(q=querystring, cols=",".join(cols)) for casexml in resp.cases.childGenerator(): #logger.info("case:##{}".format(casexml)) logger.debug(casexml['ixBug']) id = casexml['ixBug'] question = casexml.sTitle.getText() latest_event = casexml.events event_id = latest_event.ixBugEvent.getText() message_body = latest_event.s.getText() answers_string = "" pdb.set_trace() if message_body == "": answers = googler(question) for ele in answers: answers_string += "\n".join( [ele['title'], ele['url'], ele['abstract']]) answers_string += '\n\n' fb.edit(ixBug=id, sEvent=answers_string, ixPersonAssignedTo=casexml.ixPersonOpenedBy.getText()) else: for line in [i for i in message_body.split('\n') if i != '']: answers_string = "" if line.startswith("##"): answers_string += '**' + line[3:].encode('utf-8') answers_string += '\n' answers = googler(line[3:]) for ele in answers: answers_string += "\n".join( [ele['title'], ele['url'], ele['abstract']]) answers_string += '\n\n' fb.edit( ixBug=id, ixPersonAssignedTo=casexml.ixPersonOpenedBy.getText(), sEvent=answers_string) #fb.edit(ixBug=id,ixBugEvent=event_id,sEvent=answers_string,ixPersonAssignedT=casexml.ixPersonOpenedBy.getText()) else: break
# Change the specified case's milestone ("Fixfor" in fogbugz API parlance) # This will change a case's milestone even if the case is closed # This is a fast way to change case milestones, especially for # closed cases that the UI forces you to reopen before editing from fogbugz import FogBugz from datetime import datetime, timedelta import fbSettings # user input sCase = raw_input('Case #: ') sMilestone = raw_input('New milestone: ') # open session with FogBugz using our API token fb = FogBugz(fbSettings.URL, fbSettings.TOKEN) # update the case try: resp = fb.edit(ixBug=sCase, sFixFor=sMilestone) except: print "Update not performed - Error from FogBugz" print "Done"
print '*** Cannot login to [{0}] ***'.format(URL_TO) print 'copy terminated' sys.exit() # when q='' it takes the user's (from) current selected filter in fogbugz.com (and copies only those cases) resp_from = fbz_from.search(q='', cols='ixBug,ixBugParent,ixStatus,sTitle,sProject,sFixFor,' 'sCategory,sPersonAssignedTo,sPriority,dtDue,events') for case in resp_from.cases.childGenerator(): title = case.stitle.string.encode('UTF-8') # to eliminate the garbage from <![CDATA[title here]]> resp_to = fbz_to.search(q='title:"{0}"'.format(title), cols='ixBug') if resp_to.cases.case: print case.ixbug.string, 'ALREADY EXISTS as', resp_to.cases.case.ixbug.string else: resp_new_case = fbz_to.new(ixBug=case.ixbug.string, ixBugParent=case.ixbugparent.string, sTitle=case.stitle.string, sProject=case.sproject.string, sFixFor=case.sfixfor.string, sCategory=case.scategory.string, sPersonAssignedTo=case.spersonassignedto.string, spriority=case.spriority.string, dtdue=case.dtdue.string, cols='ixBug') new_id = int(resp_new_case.ixbug.string) # changes the status of the newly created case fbz_to.edit(ixBug=new_id, ixStatus=int(case.ixstatus.string)) # add all the events for event in case.events.childGenerator(): fbz_to.edit(ixBug=new_id, sEvent=event.s.string) print case.ixbug.string, 'ADDED as', new_id
fb = FogBugz("https://sailthru.fogbugz.com/") # To run this needs a d.txt file that contains the json of: {"login":"******","pass":"******"} with open('../d.txt') as json_data: data = json.load(json_data) login = data["login"] passw = data["pass"] fb.logon(login,passw) milestones = fb.listFixFors() #this is not being used now ... it gets the most current milestone... i could probably trash it.. milestone_dates, sep, tail = milestones.sfixfor.renderContents().partition('T') miled = milestones.findAll('dt',limit=2)[1] work = miled.renderContents().partition('T') milestone = work[0] milestone = milestone.replace("-","/") print milestone search = 'milestone'+':'+args.o_variable+' '+'status:open -status:Merged -milestone:Undecided Project:Sailthru' print search response = fb.search(q=search) for case in response.cases.childGenerator(): print case['ixbug'] fb.edit(ixBug=case['ixbug'],sFixFor=args.n_variable)
if branchPos is not -1: formattedText = formattedText[ 0: branchPos] + '<a href="' + gitweburl + '/gitweb/?p=' + reponame + ';a=shortlog;h=' + branchname + '">' + branchname + '</a>' + formattedText[ branchPos + len(branchname):] return formattedText def testFormatDescription(): test1 = formatDescription( 'quasar.git', 'https://gitweb.aphelion.se', 'commit 3b22351959e1e0e7a5ef6d1c067ab3ca4b6d6c94\nAuthor: Patrik Hoglund <*****@*****.**>\nDate: Mon Oct 1 13:06:34 2012 +0200\n\n case 4669: Added cvs export to Fx Report view\n\nBranch: refs/heads/develop', '3b22351959e1e0e7a5ef6d1c067ab3ca4b6d6c94', 'refs/heads/develop') return test1 def editFBCase(site, username, password, case, change, changetext): fb = FogBugz('https://' + site + '.fogbugz.com/') fb.logon(username, password) logging.info('Updating fogbugz cases') fb.edit(ixBug=case, sEvent=changetext) fb.logoff() desciption = testFormatDescription() editFBCase('apehlion', '*****@*****.**', '#01APhelion', '4675', '3b22351959e1e0e7a5ef6d1c067ab3ca4b6d6c94', desciption)
'sCategory,sPersonAssignedTo,sPriority,dtDue,events') for case in resp_from.cases.childGenerator(): title = case.stitle.string.encode( 'UTF-8') # to eliminate the garbage from <![CDATA[title here]]> resp_to = fbz_to.search(q='title:"{0}"'.format(title), cols='ixBug') if resp_to.cases.case: print case.ixbug.string, 'ALREADY EXISTS as', resp_to.cases.case.ixbug.string else: resp_new_case = fbz_to.new( ixBug=case.ixbug.string, ixBugParent=case.ixbugparent.string, sTitle=case.stitle.string, sProject=case.sproject.string, sFixFor=case.sfixfor.string, sCategory=case.scategory.string, sPersonAssignedTo=case.spersonassignedto.string, spriority=case.spriority.string, dtdue=case.dtdue.string, cols='ixBug') new_id = int(resp_new_case.ixbug.string) # changes the status of the newly created case fbz_to.edit(ixBug=new_id, ixStatus=int(case.ixstatus.string)) # add all the events for event in case.events.childGenerator(): fbz_to.edit(ixBug=new_id, sEvent=event.s.string) print case.ixbug.string, 'ADDED as', new_id
class Bugz(object): def __init__(self): self.config = yaml.load(file('bugzbot.conf', 'r')) self.fb = FogBugz(self.config['FOGBUGZ_URL'], self.config['FOGBUGZ_TOKEN']) def returnUser(self, _semail): self.user = self.fb.viewPerson(semail=_semail) try: self.fb_user = self.user.people.person.sfullname.string return self.fb_user except AttributeError: return "User not found" def assignTicket(self, ticket_num, user, orig_user): self.touser = self.returnUser(user) print user print self.touser if self.touser != "User not found": self.event = "This ticket was assigned to you by slack user " + \ orig_user[1] + " courtesy of bugzbot!" self.fb.edit(ixBug=ticket_num, sPersonAssignedTo=self.touser, sEvent=self.event) self.checker = self.fb.search(q=ticket_num, cols="ixPersonAssignedTo") print self.checker if self.checker.cases.case.ixpersonassignedto.string != "93": return "success" else: return "One of us screwed up. I got stuck with the ticket somehow." \ "Please follow up and manually assign the ticket so it does not get lost in the shuffle!" else: return "Fogbugz user was not found. Please try again." def returnTicket(self, option, ticket_num): if option: self.retrieve_ticket = self.fb.search(q=ticket_num, cols='ixBug,sTitle,sProject') if self.retrieve_ticket.cases['count'] == str(1): self.ticket_title = self.retrieve_ticket.cases.case.stitle.string self.ticket_project = self.retrieve_ticket.cases.case.sproject.string self.ticket_URL = "https://tenthwave.fogbugz.com/f/cases/" + ticket_num self.ticket = "Ticket: " + ticket_num + " | " + self.ticket_title + \ "\n\n" + self.ticket_URL print self.ticket return self.ticket else: msg = "Something went wrong! Either Fogbugz is down, you're a magician calling a number " \ "that does not exist yet, or it somehow returned more than one ticket." print msg return msg else: self.retrieve_ticket = self.fb.search( q=ticket_num, cols="ixBug,sTitle,sLatestTextSummary,sArea,sProject") if self.retrieve_ticket.cases['count'] == str(1): self.ticket_title = self.retrieve_ticket.cases.case.stitle.string self.ticket_area = self.retrieve_ticket.cases.case.sarea.string self.ticket_project = self.retrieve_ticket.cases.case.sproject.string self.ticket_URL = "https://tenthwave.fogbugz.com/f/cases/" + ticket_num self.ticket_last_update = self.retrieve_ticket.cases.case.slatesttextsummary.string self.ticket = self.ticket_URL + "\n\nTicket: " + ticket_num + "\n" + self.ticket_project + \ " : " + self.ticket_area + "\n*" + self.ticket_title + "*\n\n" + self.ticket_last_update print self.ticket return self.ticket else: msg = "Something went wrong! Either Fogbugz is down, you're a magician calling a number " \ "that does not exist yet, or it somehow returned more than one ticket." print msg return msg
fogbugz_response=fb.search(q='tag:"' + cur_card['id'] + '"',cols='ixBug') if len(fogbugz_response.cases) == 0 : fb.new(sTitle=cur_card['name'], sTags=cur_card['id'], ixProject=os.environ['FOGBUGZ_DEFAULT_PROJECT']) # Get ixBug value fogbugz_response=fb.search(q='tag:"' + cur_card['id'] + '"',cols='ixBug') fogbugz_id=fogbugz_response.ixbug.string # Load fogbugz updates into dictionary. fogbugz_updates=[] messages_response=fb.search(q=fogbugz_id,cols='sTitle,events') for case in messages_response.cases.childGenerator() : for event in case.events.childGenerator(): current_string=str(event.shtml.string) # Fogbugz stores all shtml data in CDATA container, we need to strip this out. There must be a way to parse this # with BeautifulSoup... if current_string != 'None' and current_string !='<![CDATA[None]]>' : fogbugz_updates.append(current_string.replace('<br />\n',"\n").replace('<![CDATA[','').replace(']]>','')) trello_updates=[] # Iterate through Trello card actions and update FogBugz. for cur_action in trello.cards.get_action(cur_card['id']) : if cur_action['type'] == 'commentCard' : trello_updates.append(cur_action['data']['text']) if not cur_action['data']['text'] in fogbugz_updates : fb.edit(ixbug=fogbugz_id, sEvent=cur_action['data']['text']) # Iterate through fogbugz_updates and update trello. for cur_fogbugz_update in fogbugz_updates: if not cur_fogbugz_update in trello_updates: trello.cards.new_action_comment(cur_card['id'], cur_fogbugz_update)