我们正在寻求为所有FogBugz数据创建快照,但是GUI似乎仅允许导出案例的顶层列表,而不是细节/附件.在我能找到的唯一解决方案中搜索与现在过时的应用程序有关.
We are seeking to create a snapshot of all our FogBugz data however the GUI only seems to allow to export the top level list of cases, not their detail/attachments. Searching around the only solutions I can find relate to apps that are now out of date.
推荐答案我发现很难找到任何帮助,但最终我想出了如何编写脚本来实现这一点,并希望与他人共享.请注意,我不是Python程序员,也不是HTML/CSS家伙,所以请不要发火!
I found this very hard to find any help on but eventually I figured out how to write a script to do this and wanted to share it. Please note I'm not a Python programmer nor a HTML/CSS guy so no flaming please!
它从他们的帮助站点开始,是一个示例脚本,我对其进行了修改,使其包含附件并独立存在.
It started as a sample script from their help site and I adapted it to include attachments and to be stand alone.
首先下载并安装Python3.然后pip安装fogbugz和jinja2.将这两个文件放在python目录中,填写变量(包括脚本中途的令牌),然后运行backit.
First download and install Python3. Then pip install fogbugz and jinja2. Place these two files in your python directory, fillin the variables (including the token half way down the script) and then run backit.
1- backit.py
1- backit.py
from fogbugz import FogBugz import sys from jinja2 import Template import os import urllib def main(): S_FOGBUGZ_URL = 'whatever.fogbugz/' S_EMAIL = 'email' S_PASSWORD = 'pass' MAX_BUGS = 9999 TEMPLATE_FILE = 'C:\\Users\\zzz\\AppData\\Local\\Programs\\Python\\Python36\\fbBackupTemplate.html' fb = FogBugz(S_FOGBUGZ_URL) fb.logon(S_EMAIL, S_PASSWORD) resp = fb.search(q='type:"Cases"', cols='ixBug', max=MAX_BUGS) tmpl = Template(open(TEMPLATE_FILE,'r').read()) for case in resp.cases.findAll('case'): ixBug = int(case['ixBug']) print(ixBug) respBug = fb.search(q='%s' % ixBug,cols ='sTitle,sPersonAssignedTo,sProject,sArea,sCategory,sPriority,events') xmlBug = respBug.cases.findAll('case')[0] bug = {} bug['ixBug'] = int(xmlBug['ixBug']) bug['sTitle'] = xmlBug.sTitle.string if xmlBug.sTitle.string else '' bug['sPersonAssignedTo'] = xmlBug.sPersonAssignedTo.string if xmlBug.sPersonAssignedTo.string else '' bug['sProject'] = xmlBug.sProject.string if xmlBug.sProject.string else '' bug['sArea'] = xmlBug.sArea.string if xmlBug.sArea.string else '' bug['sCategory'] = xmlBug.sCategory.string if xmlBug.sCategory.string else '' bug['sPriority'] = xmlBug.sPriority.string if xmlBug.sPriority.string else '' bug['events'] = [] BACKUP_DIR = 'C:\\Temp\\FBBack' BACKUP_DIR += '\\' + xmlBug.sProject.string if xmlBug.sProject.string else '' if not os.path.exists(BACKUP_DIR): os.makedirs(BACKUP_DIR) BACKUP_DIR += '\\' + str(xmlBug['ixBug']) if not os.path.exists(BACKUP_DIR): os.makedirs(BACKUP_DIR) for event in xmlBug.events.findAll('event'): bugEvent = {} bugEvent['ixBugEvent'] = int(event['ixBugEvent']) bugEvent['sVerb'] = event.sVerb.string if event.sVerb.string else '' bugEvent['dt'] = event.dt.string if event.dt.string else '' bugEvent['s'] = event.s.string if event.s.string else '' bugEvent['sChanges'] = event.sChanges.string if event.sChanges.string else '' bugEvent['evtDescription'] = event.evtDescription.string if event.evtDescription.string else '' bugEvent['sPerson'] = event.sPerson.string if event.sPerson.string else '' bugEvent['s'] = event.s.string.encode('ascii', 'ignore').decode('utf-8') if event.s.string else '' theAttachments = '' for att in event.rgAttachments: theAttachments += 'Attachment: ' +att.sFileName.string + '\n' print('Downloading attachment: ' + att.sFileName.string) str1 = att.sURL.string str2 = 'ixAttachment=' loc1 = str1.find(str2) + len(str2) loc2 = str1.find('&sFileName') str3 = ';sFileName=' loc3 = str1.find(str3) + len(str3) loc4 = str1.find('&sTicket') theURL = S_FOGBUGZ_URL #+ att.sURL.string theURL += 'default.asp?' theURL += 'ixAttachment=' + str1[loc1:loc2] theURL += '&pg=pgDownload&pgType=pgFile&sFilename=' + str1[loc3:loc4] theURL += '&token=123456sometoken' #fix the replace newFileName = att.sFileName.string.replace('\\','') newFileName = newFileName.replace(':','') newFileName = BACKUP_DIR+'\\'+newFileName #print(newFileName) urllib.request.urlretrieve(theURL, newFileName) bugEvent['attachment'] = theAttachments bug['events'].append(bugEvent) f = open('%s\\%s.html' % (BACKUP_DIR,bug['ixBug']),'w') f.write(tmpl.render(bug=bug)) f.close() fb.view(ixBug=ixBug) main()2- fbBackupTemplate.html
2- fbBackupTemplate.html
<!DOCTYPE html> <html lang="en"> <head> <title>{{bug.ixBug|e}} | {{bug.sTitle|e}}</title> <style type="text/css"> .bugHeader { outline-width: 2px; outline-style: solid; width: 90%; padding: 5px; background: #B8DDFF; font: 24px "Trebuchet MS", Arial, Helvetica, sans-serif; } .bugEvent { outline-width: 2px; outline-style: solid; outline-color: blue; width: 90%; padding: 5px; background: #D2E9FF; font: 12px Arial, Helvetica, sans-serif; } pre.s { white-space: pre-wrap; } </style> </head> <body> <div class="bugHeader"> <span class="ixBug">Bug ID: {{bug.ixBug|e}}</span><br> <span class="sTitle">Title: {{bug.sTitle|e}}</span><br> <span class="sPersonAssignedTo">Assigned To: {{bug.sPersonAssignedTo|e}}</span><br> <span class="sProject">Project: {{bug.sProject|e}}</span><br> <span class="sArea">Area: {{bug.sArea|e}}</span><br> <span class="sCategory">Category: {{bug.sCategory|e}}</span><br> <span class="sPriority">Title: {{bug.sPriority|e}}</span><br> </div> <div class="bugEvents"> {% for event in bug.events %} <div class="bugEvent"> <span class="ixBugEvent">BugEvent ID: {{event.ixBugEvent|e}}</span><br> <span class="dt">Date/Time: {{event.dt|e}}</span><br> <span class="sVerb">Verb: {{event.sVerb|e}}</span><br> <span class="evtDescription">Event Description: {{event.evtDescription|e}}</span><br> <span class="sChanges">Changes: {{event.sChanges|e}}</span><br> <span class="sPerson">Person: {{event.sPerson|e}}</span><br> <span class="Text">Text: </span><br> <pre class="s">{{event.s|e}}</pre><br> <pre class="s">{{event.attachment|e}}</pre><br> </div> {% endfor %} </div> </body> </html>备份脚本的原始URL: developers.fogbugz/?W211
Original URL for the backup script: developers.fogbugz/?W211
获取API调用的令牌: support. fogbugz/hc/zh-CN/articles/360011255754-Generating-a-FogBugz-XML-API-Token
Get a token for the API call: support.fogbugz/hc/en-us/articles/360011255754-Generating-a-FogBugz-XML-API-Token
更多推荐
从FogBugz导出案例详细信息
发布评论