Skip to content
This repository was archived by the owner on Oct 30, 2018. It is now read-only.
Open
40 changes: 38 additions & 2 deletions import.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

import argparse
import sys
from importer import validate_json, print_labels
from importer import validate_json, print_labels, create_issue, get_as_json, format_post_body, format_issue, fake_message
from termcolor import cprint

if __name__ == '__main__':
parser = argparse.ArgumentParser()
Expand All @@ -18,8 +19,43 @@
help='Print all labels used by issues.')
parser.add_argument('-f', '--force', action='store_true',
help='Don\'t validate labels against the issues repo.')
parser.add_argument('-o', '--origin',
choices=['moz', 'ms', 'blink', 'apple'],
help='Adjust the import to the JSON issue format')
publishgroup = parser.add_mutually_exclusive_group()
publishgroup.add_argument('-t', '--test', action='store_true',
help='NO publishing on Github, just testing')
publishgroup.add_argument('-g', '--github', action='store_true',
help='Publishing on Github. Irreversible.')
args = parser.parse_args()
# Printing the list of existing labels on Github
if args.labels:
print_labels()
sys.exit(0)
validate_json(args.issue_file, args.force)
elif args.origin:
# Let's get the data
json_data = get_as_json(args.issue_file)
# create the data with the right format
webcompat_issue = format_issue(json_data, args.origin)
else:
cprint('Missing --labels or --origin', 'white', 'on_red')
parser.print_help()
sys.exit(0)
# Validation
if validate_json(webcompat_issue, args.force):
if args.github:
# Mode with consequences
create_issue(webcompat_issue)
cprint('Creating the issue on Github', 'green')
elif args.test:
# Mode without consequences
cprint('Test Mode Run. Nothing is sent to github', 'yellow')
print fake_message(webcompat_issue)
else:
cprint('Missing --test or --github', 'white', 'on_red')
parser.print_help()
sys.exit(0)
else:
cprint('Invalid JSON data for the issue', 'red')
sys.exit(0)

41 changes: 34 additions & 7 deletions importer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from schema import schema
from termcolor import cprint
from textwrap import fill
import adapters


LABEL_VALIDATION_ERROR = '''
You attempted to create an issue with an unknown label. GitHub ignores unknown
Expand All @@ -26,7 +28,7 @@
'''

REPO_URI = 'https://api.github.com/repos/{0}'.format(REPO_PATH)

USER_AGENT = 'Webcompat-Issue-Importer'

def get_issue_body(json_data):
'''Return the issue body in the proper format.'''
Expand All @@ -42,6 +44,18 @@ def get_issue_body(json_data):
json_data['body'])


def format_issue(json_data, json_format):
'''Transform the issue data into something usable by importer'''
if json_format == 'moz':
cprint('Converting Mozilla bugs', 'yellow')
webcompat_json = adapters.mozilla_adapter.convert_issue_data(json_data)
else:
webcompat_json = None
cprint('Time for you to code an adapter', 'white', 'on_red')
print 'We need an adapter for the format %s' % (json_format)
print 'See http://github.com/webcompat/issue-importer'
return webcompat_json

def format_post_body(json_data):
'''Create the POST "body" object.'''
body = {'body': get_issue_body(json_data),
Expand All @@ -55,10 +69,21 @@ def api_post(uri, body):
what gets created (currently either an issue or a comment).'''
headers = {
'Authorization': 'token {0}'.format(OAUTH_TOKEN),
'User-Agent': 'Webcompat-Issue-Importer'
'User-Agent': USER_AGENT
}
return requests.post(uri, data=json.dumps(body), headers=headers)

def fake_message(webcompat_issue):
'''Generate a fake message for the dry run'''
message = u'''
POST /repos/{0} HTTP/1.1
Host: api.github.com
Authorization: ***OBFUSCATED****
User-Agent: {1}

{2}
'''
return message.format(REPO_PATH, USER_AGENT, format_post_body(webcompat_issue))

def create_issue(json_data):
'''Create a new GitHub issue by POSTing data to the issues API endpoint.
Expand Down Expand Up @@ -103,14 +128,15 @@ def get_as_json(issue_file):
return r


def validate_json(issue_file, skip_labels=False):
'''Validate the structure of `file_name` against our JSON schema.'''
json_data = get_as_json(issue_file)
def validate_json(json_data, skip_labels=False):
'''Validate the structure of `json_data` against our JSON schema.'''
if not skip_labels:
schema['properties']['labels']['items'].update(enum=get_labels())
labels = get_labels()
labels.extend(['serversniff', 'clientsniff', 'imported'])
schema['properties']['labels']['items'].update(enum=labels)
try:
jsonschema.validate(json_data, schema)
create_issue(json_data)
return True
except jsonschema.exceptions.ValidationError as e:
cprint('JSON Schema validation failed:', 'white', 'on_red')
print('\n')
Expand All @@ -119,6 +145,7 @@ def validate_json(issue_file, skip_labels=False):
print(e.message)
else:
print(e)
return False


def get_labels():
Expand Down
7 changes: 7 additions & 0 deletions importer/adapters/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from . import mozilla_adapter
38 changes: 38 additions & 0 deletions importer/adapters/mozilla_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import re
VALID_LABELS = ['serversniff', 'clientsniff']

def convert_issue_data(json_data):
'''Take the json data from the bug repo and convert it
into json data suitable for webcompat.

Documentation of HTTP Mozilla Bugzilla API:
http://bugzilla.org/docs/tip/html/api/Bugzilla/WebService/Server/REST.html
http://bugzilla.org/docs/tip/html/api/Bugzilla/WebService/Bug.html
'''
webcompat_json = None
# json_data is a list of bugs we only want the first one
bug_data = json_data['bugs'][0]
source = 'https://bugzilla.mozilla.org/show_bug.cgi?id=%s' % (bug_data['id'])
os = bug_data['op_sys'].lower()
# Let's gather some labels
regex = re.compile(ur'\[(.*?)\]')
whiteboard_labels = re.findall(regex, bug_data['whiteboard'])
# We probably want to filter out labels that are only mozilla.
moz_labels = [label for label in whiteboard_labels if label in VALID_LABELS]
moz_labels.extend([u'firefox', os, u'imported'])
webcompat_json = {
'url': bug_data['url'],
'title': bug_data['summary'],
'os': os,
'browser': u'Firefox',
'source_human': source,
'labels': moz_labels,
'body': 'body is missing. Need to code it'
}
return webcompat_json