Last active
October 18, 2019 07:38
-
-
Save chillu/5965794 to your computer and use it in GitHub Desktop.
Python script to list all repos for gitorious projects. Since this feature is not available through the UI, we need to use the provided XML data as a start to aggregate these results. Requires Python 3. Example usage: python3.3 list_gitorious_repos.py -u [email protected] -p mypassword --repo cms http://gitorious.silverstripe.com
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import xml.etree.ElementTree as ET | |
import urllib.request | |
import base64 | |
import json | |
import os.path | |
import re | |
class GitoriousRepoLister: | |
""" | |
Lists all repos for gitorious projects. Since this feature is not | |
available through the UI, we need to use the provided XML data as | |
a start to aggregate these results. | |
""" | |
verbose = False | |
base_url = None | |
user = None | |
password = None | |
limit_project = None | |
limit_repo = None | |
def __init__(self, base_url): | |
self.base_url = base_url | |
def run(self): | |
page = 1 | |
while True: | |
xml = self.get_xml(self.base_url + '/projects.xml?page=' + str(page)) | |
if not xml: | |
break | |
projects = xml.iter('project') | |
for project in projects: | |
slug = project.find('slug').text | |
# Optionally filter by project slug | |
if self.limit_project and not re.match(self.limit_project, slug): | |
continue | |
project_data = self.get_project_data(project) | |
for repo in project_data.iter('repository'): | |
repo_slug = repo.find('name').text | |
if self.limit_repo and not re.match(self.limit_repo, repo_slug): | |
continue | |
print(repo.find('clone_url').text) | |
page = page + 1 | |
def get_xml(self, url): | |
"""Gets XML from URL, returns ElementTree""" | |
if isinstance(url, str): | |
if self.verbose: | |
print('Requesting XML from {0} ...'.format(url)) | |
request = urllib.request.Request(url) | |
if self.user or self.password: | |
base64raw = '{0}:{1}'.format(self.user, self.password) | |
base64string = base64.encodestring(base64raw.encode()).decode().replace('\n', '') | |
request.add_header("Authorization", "Basic %s" % base64string) | |
try: | |
handle = urllib.request.urlopen(request) | |
xml = ET.parse(handle) | |
except urllib.error.HTTPError: | |
xml = None | |
else: | |
# Assume a file-like object | |
xml = ET.parse(url) | |
return xml | |
def get_project_data(self, project): | |
"""Collect all relevant data, returns ElementTree""" | |
title = project.find('title').text | |
slug = project.find('slug').text | |
if self.verbose: | |
print('Collecting data from project \'{0}\' ...'.format(title)) | |
return self.get_xml(self.base_url + '/' + slug + '.xml') | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description=""" | |
Lists all repos for gitorious projects. Since this feature is not | |
available through the UI, we need to use the provided XML data as | |
a start to aggregate these results. | |
""") | |
parser.add_argument( | |
'url', | |
type=str, | |
help='Base URL to the gitorious installation, e.g. http://gitorious.mycompany.org/' | |
) | |
parser.add_argument( | |
'-u', | |
'--user', | |
type=str, | |
help='Basic Auth user for the Gitorious installation' | |
) | |
parser.add_argument( | |
'-p', | |
'--password', | |
type=str, | |
help='Basic Auth password for the Gitorious installation' | |
) | |
parser.add_argument( | |
'--project', type=str, | |
help='Limit to a single project slug (Caution: Not the project name)' | |
) | |
parser.add_argument( | |
'--repo', type=str, | |
help='Limit to a single repo slug, for example "cms"' | |
) | |
parser.add_argument( | |
'-v', | |
'--verbose', | |
action="store_true", | |
help='Verbose run with more feedback' | |
) | |
args = parser.parse_args() | |
inst = GitoriousRepoLister(args.url) | |
inst.verbose = args.verbose | |
inst.user = args.user | |
inst.password = args.password | |
if args.project: | |
inst.limit_project = args.project | |
if args.repo: | |
inst.limit_repo = args.repo | |
inst.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment