Skip to content

Instantly share code, notes, and snippets.

@glarrain
Last active February 20, 2024 08:27
Show Gist options
  • Save glarrain/5861055 to your computer and use it in GitHub Desktop.
Save glarrain/5861055 to your computer and use it in GitHub Desktop.
Exporting data from Pivotal Tracker is a pain in the ass. The following scripts let you download all the stories of a given project, and then (optionally) extract all the attachments linked to those, and download them
import getpass
import pickle
import urllib2
from xml.dom import minidom
project_id = raw_input("Project ID: ")
auth_token = getpass.getpass("Auth token: ")
url_template = "http://www.pivotaltracker.com/services/v3/projects/%s/stories"
url = url_template % project_id
req = urllib2.Request(url, None, {'X-TrackerToken': auth_token})
response = urllib2.urlopen(req)
dom = minidom.parseString(response.read())
dom_as_xml = dom.toxml(encoding='utf-8')
pickle_filename = "xml_stories_%s.p" % project_id
pickle.dump(dom_as_xml, open(pickle_filename, 'wb'))
import getpass
import os
import pickle
import xml.dom.minidom
def get_attachment_metadata(element_attachment):
def get_data_for_tag(tag_name):
elements_tag = element_attachment.getElementsByTagName(tag_name)
assert len(elements_tag) == 1
element_tag = elements_tag[0]
assert len(element_tag.childNodes) == 1
node_attachment_tag = element_tag.childNodes[0]
assert not node_attachment_tag.hasChildNodes()
return node_attachment_tag.data
return get_data_for_tag('id'), get_data_for_tag('filename'), get_data_for_tag('url')
def download_attachments(attachments_metadata, dir=None):
user = raw_input("Account user: ")
password = getpass.getpass("Account password: ")
exit_status = os.system("bash login-to-PT.sh %s %s" % (user, password))
for metadata in attachments_metadata:
file_id = metadata[0]
server_filename = metadata[1]
filename = "%s - %s" % (file_id, server_filename)
file_path = filename if dir is None else os.path.join(dir, filename)
print("downloading %s" % file_id)
exit_status = os.system('bash get-attachment.sh %s "%s"' % (file_id, filepath))
def main():
pickle_filename = raw_input("pickled file name: ")
pickle_file = open(pickle_file, 'rb') # "xml_stories_423507.p"
dom_as_xml = pickle.load(pickle_file)
dom = xml.dom.minidom.parseString(dom_as_xml)
elements_stories = dom.getElementsByTagName('stories')
assert len(dom.getElementsByTagName('stories')) == 1
element_stories = elements_stories[0]
elements_story = element_stories.getElementsByTagName('story')
print("number of stories: %s" % len(elements_story))
elements_attachments_dict = {}
attachments_metadata = []
for ix, story in enumerate(elements_story):
element_attachments = story.getElementsByTagName('attachments')
if element_attachments:
elements_attachments_dict[ix] = element_attachments
print("number of stories with attachment(s): %s" % len(elements_attachments_dict))
for key in elements_attachments_dict:
assert len(elements_attachments_dict[key]) == 1
element_attachments = elements_attachments_dict[key][0]
story_elements_attachment = element_attachments.getElementsByTagName('attachment')
assert len(story_elements_attachment) >= 1
for element_attachment in story_elements_attachment:
attachments_metadata.append(get_attachment_metadata(element_attachment))
print("number of attachments: %s" % len(attachments_metadata))
download_attachments(attachments_metadata, dir="attachments")
if __name__ == '__main__':
main()
@nfrontera
Copy link

Hi! Is this really works? Can you give me instructions to work this out? I'll appreciate it! I'm not a dev and I have to export from pivotal with attachments.
Thank you in advance!

@rpunzalan
Copy link

do you have means to extract story activity and review activities?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment