<gh_stars>0
import os
import sys
import requests
import re
import pycurl
import base64
import string
import simplejson as json
import ssl
import time

from socket import *
from github import Github
from github import GithubException



from phabricator import Phabricator
from phabricator import APIError


phab = Phabricator()
phab.update_interfaces()
phab.timeout = 100.0

print("WHO AM I?")
print("=========")
me = phab.user.whoami()
print(me)

#phabToGit
usersToUsers = {
    "arend.danielek" : "ArendDanielek",
    "andrea.ellinger" : "AEllinger",
    "trevor.sundberg" : "TrevorSundberg",
    "joshua.davis" : "jodavis42",
    "joshua.claeys" : "JoshuaClaeys",
    "nathan.carlson" : "Nathan-Carlson",
    "joshua.shlemmer" : "Yellowrobe",
    "doug.zwick" : "douglasZwick",
    "dane.curbow" : "danecurbow",
    "Johannes" :  "JohannesMP",
    "ZeroBugBot" :  "",
    "ryan.edgemon" :  "redgemon",
    "victor.cecci" : "VictorCecci",
    "jason.clark" : "",
    "BugFixMilestoneTagBot" : ""
}


#usersToUsers = {
#    "arend.danielek" : "ArendDanielek",
#    "andrea.ellinger" : "AEllinger",
#    "trevor.sundberg" : "TrevorSundberg",
#    "joshua.davis" : "jodavis42",
#    "joshua.claeys" : "JoshuaClaeys",
#    "nathan.carlson" : "Nathan-Carlson",
#    "joshua.shlemmer" : "Yellowrobe",
#    "doug.zwick" : "douglasZwick",
#    "dane.curbow" : "danecurbow",
#    "Johannes" :  "JohannesMP",
#    "ZeroBugBot" :  "",
#    "ryan.edgemon" :  "redgemon",
#    "victor.cecci" : "VictorCecci"
#}

projectToLabels = {
    "zero_animation" : "Animation",
    "zero_archetypes" : "Archetypes",
    "zero_audio" : "Audio",
    "zero_bug_reporter" : "Bug Reporter",
    "zero_builds" : "Builds",
    "zero_content_system" : "Content System",
    "zero_crash_handler" : "Crash Handler",
    "zero_editor" : "Editor",
    "zero_graphics" : "Graphics",
    "zero_input" : "Input",
    "zero_launcher" : "Launcher",
    "zero_meta" : "Meta",
    "zero_networking" : "Networking",
    "zero_particles" : "Particles",
    "zero_physics" : "Physics",
    "zero_platform" : "Platform",
    "zero_ui" : "UI",
    "zilch" : "Zilch",
    "crash" : "Crash",
    "deprecated" : "Deprecated",
    "legacy" : "Legacy 1.0",
    "bug_report" : "Bug",
    "zilch_parser" : "Zilch Parser",
    "zilch_shaders" : "Zilch Shaders",
    "zilch_c_plugins" : "C++ Plugins"
}

tasksToIssues = {}
file_repo_url = "https://media.githubusercontent.com/media/zeroengineteam/ZeroFiles/master/task_files/"

fileExt_file = "fileIDToFileExt_resolved.json"
infileName = "./phab_tasks_resolved.json"
#infileName = "./phab_tasks_remainder_open_10-2.json"

userName = "zeroengineteam"
repoName = "ZeroCore"

#userName = "ArendDanielek"
#repoName = "Test"

# First create a Github instance:
# using username and password

tokenFile = open("token.txt", 'r')
access_token = tokenFile.read()
tokenFile.close()
print("Token: " + access_token)
# or using an access token
github = Github(login_or_token=access_token)#"ArendDanielek", password="<PASSWORD>")
print("Github connected:")
print("  rate_limiting: " + str(github.rate_limiting))
print("  rate_limiting_resettime: " + str(github.rate_limiting_resettime))
print("  get_rate_limit(): " + str(github.get_rate_limit()))
print("  oauth_scopes: " + str(github.oauth_scopes))
user = github.get_user()
print("  auth: " + str(user.login))
print("    user.name: " + str(user.name))

#returns github api repo object from user and repo string names
def GetRepo(userName, repoName):
    repo = None
    repo_id = userName + '/' + repoName
    try:
        repo = github.get_repo(repo_id)
    except GithubException as e:
        print("API error: " + str(e))
    else:
        print("Got Repo " + repo_id)
        return repo

# Loads serialized map of file IDs to file extensions generated by PullPhabTasks.py
def LoadFileExts():
    extFile = open(fileExt_file, "r")
    extMap = json.loads(extFile.read())
    extFile.close()
    return extMap

# Load file extension map from file
fileExtMap = LoadFileExts()

# Loads serialized tasks generated by PullPhabTasks.py
def LoadTasks():
    inFile = open(infileName, 'r')
    inFileContent = inFile.read()
    #print(inFileContent)
    tasks = json.loads(inFileContent)['data']
    inFile.close()
    return tasks

# Read in task objects from file
tasks = LoadTasks()
repo = GetRepo(userName, repoName)

#Queries conduit API with user phid and return the string name of the user
def GetUserNameFromPHID(phid):
    if(phid == None):
        return None
    #print("Get Username from PHID: " + phid)
    queryKey = "all"
    constraints = {}
    phids = []
    phids.append(phid)
    constraints['phids'] = phids
    response = None

    try:
        response = phab.user.search(queryKey=queryKey, constraints=constraints)
    except APIError:
        print(APIError.message)
    else:
        #print("Phabricator reponse: " + str(response))
        data = response.data[0]
        fields = data["fields"]
        name = fields["username"]
        return name;

#Queries conduit API with project phid and return the string name of the project
def GetProjectNameFromPHID(phid):
    if(phid == None):
        return None
    #print("Get project name from PHID: " + phid)
    queryKey = "all"
    constraints = {}
    phids = [phid]
    constraints['phids'] = phids
    response = None

    try:
        response = phab.project.search(constraints=constraints)
    except APIError:
        print(APIError.message)
    else:
        #print("Phabricator reponse: " + str(response))
        data = response.data[0]
        fields = data["fields"]
        name = fields["name"]
        return name

#Returns corresponding github markdown formatted URL when passed a re module MatchObj for a remarkup formatted link
#This function is passed to re.replace in CreateIssue as the callback function for 
#  generating the replacement string on pattern match
def GenerateFileURL(matchObj):
    fileID = matchObj.group(3)
    fileExt = fileExtMap[fileID]

    url = "![" + fileID + "](" + file_repo_url + fileID + fileExt + ")"
    print("Gen File URL for FileID: " + str(fileID) + " URL: " + url)
    return url

#Extracts task details from the description and generates the equivalent markdown
def ReformatBody(body):
    #Extract and write the description
    descriptionRegex = "([\s\S]+?(?=\nUser Data))"
    descriptionMatch = re.search(descriptionRegex, body)
    result = "# Description\n"
    if(descriptionMatch == None):
        result += "Description was not present\n"
    else:
        description = descriptionMatch.groups(0)[0]
        result += description + "\n"

    #Extract and write the user name
    usernameRegex = "(\- \*\*User[N|n]ame\*\*\: \@)(\S*)"
    usernameMatch = re.search(usernameRegex, body)
    result += "# User Data\n"
    result += "- **UserName**: "
    if(usernameMatch == None):
        result += "Username was not present\n"
    else:
        username = usernameMatch.groups(2)[1]
        gitusername = ""

        if username in usersToUsers.keys():
            gitusername = usersToUsers[username]
        result += gitusername + "\n"

    #Extract and write the revision ID
    revisionRegex = "(\- \*\*Revision\*\*\: )(\S*)"
    revisionMatch = re.search(revisionRegex, body)
    result += "\n# Zero Engine Data\n"
    result += "- **Revision**: "
    if(revisionMatch == None):
        result += "Revision was not present\n"
    else:
        revision = revisionMatch.groups(2)[1]
        result += revision + "\n"
    
    #Extract and write the changeset ID
    changeSetRegex = "(\- \*\*ChangeSet\*\*\: )(\S*)"
    changeSetMatch = re.search(changeSetRegex, body)
    result += "- **ChangeSet**: "
    if(changeSetMatch == None):
        result += "changeSet was not present\n"
    else:
        changeSetSHA = changeSetMatch.groups(2)[1]
        result += "zeroengineteam/zerocore@" + changeSetSHA + "\n"

    #Extract and write the platform ID
    platformRegex = "(\- \*\*Platform\*\*\: )(\S*)"
    platformMatch = re.search(platformRegex, body)
    result += "- **Platform**: "
    if(platformMatch == None):
        result += "Platform was not present\n"
    else:
        platform = platformMatch.groups(2)[1]
        result += platform + "\n"
    
    #Extract and write the build version details
    buildVersionRegex = "(\- \*\*Build Version Name\*\*\: )(\S*) (\S*) (\S*) (\S*) (\S*)"
    buildVersionMatch = re.search(buildVersionRegex, body)
    result += "- **Build Version Name**: "
    if(buildVersionMatch == None):
        result += "BuildVersion was not present\n"
    else:
        match = buildVersionMatch.groups(0)
        buildNumber = match[1]
        versionChangeSet = match[2]
        buildDate = match[3]
        buildType = match[4]
        platform = match[5]

        result += buildNumber + " zeroengineteam/zerocore@" + versionChangeSet + " " + buildDate + " " + buildType + " " + platform

    return result

#Returns github usernames for zero engine team members based of the usersToUsers table above
#This function is passed to re.replace in ReplaceUsernames as the callback function for 
#  generating the replacement string on pattern match
def GetGitUserName(matchObjs):
    username = matchObj.group(1)

    if not username in usersToUsers.keys():
        return ""
    return usersToUsers[username]

#Replaces phabricator usernames with github usernames in the task body
def ReplaceUsernames(body):
    userNameRegex = "\@(.*?\..*?)[\.|\s|\s]"
    result = re.sub(userNameRegex, GetGitUserName, body)
    print(result)
    return result

def CloseIssue(issue):
    time.sleep(sleep_interval)
    try:
        result = issue.edit(state="closed")
    except GithubException as e:
        print("exception on closing of task: " + str(e))
        errors = e.data["errors"]
        error = errors[0]
        print(error)
    else:
        print(str(result))
        return result


#Creates and issue on github in the given repo for the given phabricator task
def CreateIssue(repo, task):
    time.sleep(sleep_interval)
    print("Create Issue: ")
    fields = task['fields']
    attachments = task['attachments']
    ownerPHID = fields['ownerPHID']
    print("  OnwerPHID: " + str(ownerPHID))
    ownerPhabUserName = GetUserNameFromPHID(ownerPHID)
    
    title = fields['name']
    body = fields['description']['raw']
    status = fields['status']['value']
    print("  Issue Title: " + title)
    print("    Status: " + status)

    #Set phabricator task owner as the assignee of the github issue
    githubassignees = []
    if not(ownerPhabUserName == None):
        ownerGithubUserName = usersToUsers[ownerPhabUserName]
        print("  Issue Owner:")
        print("    Phabricator Username: " + ownerPhabUserName)
        print("    GitHub Username: " + ownerGithubUserName)
        githubassignees.append(ownerGithubUserName)

    #Set the labels for the github issue to the corresponding phabricator projects
    projects = attachments['projects']
    projectPHIDs = projects['projectPHIDs']
    labels = []

    for phid in projectPHIDs:
        projectName = GetProjectNameFromPHID(phid)
        if(projectName in projectToLabels):
            labels.append(projectToLabels[projectName])

    labelStr = "  Issue Labels: "
    for label in labels:
        labelStr += str(label) + " "

    #find and replace file references with URLs to the zeroengineteam/ZeroFiles repository
    fileIDRegEx = "(\{)(\s*?)F(\d.*?)(\s*?)(,\s*?size=full\s*?|\s*?size=full\s*?|)(\})"
    newBody = re.sub(fileIDRegEx, GenerateFileURL, body)
    newBody = ReformatBody(newBody)

    #attempt issue creation
    issue = None
    try:
        issue = repo.create_issue(title, body=newBody, assignees=githubassignees, labels=labels)
    #If it fails, check to see if it is because assignee is invalid
    except GithubException as e:
        print("exception on creation of task: " + str(e))
        errors = e.data["errors"]
        error = errors[0]
        #If the exception is due to the assignee upload it without the assignee
        if(error["field"] == "assignees"):
            try:
                issue = repo.create_issue(title, body=newBody, labels=labels)
            except GithubException as e:
                print("Attempted to upload issue without assignee and still does not work, moving on.")
            else:
                CloseIssue(issue)
                return issue
    else:
        CloseIssue(issue)
        return issue

sleep_interval = 3

def ProcessTask(tasks):
    if(len(tasks) == 0):
        return;

    task = tasks.pop(0)
    issue = CreateIssue(repo, task)
    print("ProcessTask")
    limit = github.rate_limiting
    print("Limit remaining: " + str(limit))
    if(limit[0] <= 0):
        print("GITHUB RATE LIMIT REACHED")
        print("Last Issue Uploaded: " + str(issue))
        return
    else:
        ProcessTask(tasks)

ProcessTask(tasks)
#task = tasks[0]
#response = CreateIssue(repo,task)


#for task in tasks:
#    issue = CreateIssue(repo, task)
#    print("sleeping")
#    time.sleep(sleep_interval)
#    print("done sleeping")
#    #print(str(issue))
#    limit = github.rate_limiting
#    print("Limit remaining: " + str(limit))
#    if(limit[0] <= 0):
#        print("GITHUB RATE LIMIT REACHED")
#        print("Last Issue Uploaded: " + str(issue))
#        break

import os
import sys
import requests
import re
import pycurl
import base64
import string
import simplejson as json
import ssl
import time

from socket import *
from github import Github
from github import GithubException



from phabricator import Phabricator
from phabricator import APIError


phab = Phabricator()
phab.update_interfaces()
phab.timeout = 100.0

print("WHO AM I?")
print("=========")
me = phab.user.whoami()
print(me)

#phabToGit
usersToUsers = {
    "arend.danielek" : "ArendDanielek",
    "andrea.ellinger" : "AEllinger",
    "trevor.sundberg" : "TrevorSundberg",
    "joshua.davis" : "jodavis42",
    "joshua.claeys" : "JoshuaClaeys",
    "nathan.carlson" : "Nathan-Carlson",
    "joshua.shlemmer" : "Yellowrobe",
    "doug.zwick" : "douglasZwick",
    "dane.curbow" : "danecurbow",
    "Johannes" :  "JohannesMP",
    "ZeroBugBot" :  "",
    "ryan.edgemon" :  "redgemon",
    "victor.cecci" : "VictorCecci",
    "jason.clark" : "",
    "BugFixMilestoneTagBot" : ""
}


#usersToUsers = {
#    "arend.danielek" : "ArendDanielek",
#    "andrea.ellinger" : "AEllinger",
#    "trevor.sundberg" : "TrevorSundberg",
#    "joshua.davis" : "jodavis42",
#    "joshua.claeys" : "JoshuaClaeys",
#    "nathan.carlson" : "Nathan-Carlson",
#    "joshua.shlemmer" : "Yellowrobe",
#    "doug.zwick" : "douglasZwick",
#    "dane.curbow" : "danecurbow",
#    "Johannes" :  "JohannesMP",
#    "ZeroBugBot" :  "",
#    "ryan.edgemon" :  "redgemon",
#    "victor.cecci" : "VictorCecci"
#}

projectToLabels = {
    "zero_animation" : "Animation",
    "zero_archetypes" : "Archetypes",
    "zero_audio" : "Audio",
    "zero_bug_reporter" : "Bug Reporter",
    "zero_builds" : "Builds",
    "zero_content_system" : "Content System",
    "zero_crash_handler" : "Crash Handler",
    "zero_editor" : "Editor",
    "zero_graphics" : "Graphics",
    "zero_input" : "Input",
    "zero_launcher" : "Launcher",
    "zero_meta" : "Meta",
    "zero_networking" : "Networking",
    "zero_particles" : "Particles",
    "zero_physics" : "Physics",
    "zero_platform" : "Platform",
    "zero_ui" : "UI",
    "zilch" : "Zilch",
    "crash" : "Crash",
    "deprecated" : "Deprecated",
    "legacy" : "Legacy 1.0",
    "bug_report" : "Bug",
    "zilch_parser" : "Zilch Parser",
    "zilch_shaders" : "Zilch Shaders",
    "zilch_c_plugins" : "C++ Plugins"
}

tasksToIssues = {}
file_repo_url = "https://media.githubusercontent.com/media/zeroengineteam/ZeroFiles/master/task_files/"

fileExt_file = "fileIDToFileExt_resolved.json"
infileName = "./phab_tasks_resolved.json"
#infileName = "./phab_tasks_remainder_open_10-2.json"

userName = "zeroengineteam"
repoName = "ZeroCore"

#userName = "ArendDanielek"
#repoName = "Test"

# First create a Github instance:
# using username and password

tokenFile = open("token.txt", 'r')
access_token = tokenFile.read()
tokenFile.close()
print("Token: " + access_token)
# or using an access token
github = Github(login_or_token=access_token)#"ArendDanielek", password="<PASSWORD>")
print("Github connected:")
print("  rate_limiting: " + str(github.rate_limiting))
print("  rate_limiting_resettime: " + str(github.rate_limiting_resettime))
print("  get_rate_limit(): " + str(github.get_rate_limit()))
print("  oauth_scopes: " + str(github.oauth_scopes))
user = github.get_user()
print("  auth: " + str(user.login))
print("    user.name: " + str(user.name))

#returns github api repo object from user and repo string names
def GetRepo(userName, repoName):
    repo = None
    repo_id = userName + '/' + repoName
    try:
        repo = github.get_repo(repo_id)
    except GithubException as e:
        print("API error: " + str(e))
    else:
        print("Got Repo " + repo_id)
        return repo

# Loads serialized map of file IDs to file extensions generated by PullPhabTasks.py
def LoadFileExts():
    extFile = open(fileExt_file, "r")
    extMap = json.loads(extFile.read())
    extFile.close()
    return extMap

# Load file extension map from file
fileExtMap = LoadFileExts()

# Loads serialized tasks generated by PullPhabTasks.py
def LoadTasks():
    inFile = open(infileName, 'r')
    inFileContent = inFile.read()
    #print(inFileContent)
    tasks = json.loads(inFileContent)['data']
    inFile.close()
    return tasks

# Read in task objects from file
tasks = LoadTasks()
repo = GetRepo(userName, repoName)

#Queries conduit API with user phid and return the string name of the user
def GetUserNameFromPHID(phid):
    if(phid == None):
        return None
    #print("Get Username from PHID: " + phid)
    queryKey = "all"
    constraints = {}
    phids = []
    phids.append(phid)
    constraints['phids'] = phids
    response = None

    try:
        response = phab.user.search(queryKey=queryKey, constraints=constraints)
    except APIError:
        print(APIError.message)
    else:
        #print("Phabricator reponse: " + str(response))
        data = response.data[0]
        fields = data["fields"]
        name = fields["username"]
        return name;

#Queries conduit API with project phid and return the string name of the project
def GetProjectNameFromPHID(phid):
    if(phid == None):
        return None
    #print("Get project name from PHID: " + phid)
    queryKey = "all"
    constraints = {}
    phids = [phid]
    constraints['phids'] = phids
    response = None

    try:
        response = phab.project.search(constraints=constraints)
    except APIError:
        print(APIError.message)
    else:
        #print("Phabricator reponse: " + str(response))
        data = response.data[0]
        fields = data["fields"]
        name = fields["name"]
        return name

#Returns corresponding github markdown formatted URL when passed a re module MatchObj for a remarkup formatted link
#This function is passed to re.replace in CreateIssue as the callback function for 
#  generating the replacement string on pattern match
def GenerateFileURL(matchObj):
    fileID = matchObj.group(3)
    fileExt = fileExtMap[fileID]

    url = "![" + fileID + "](" + file_repo_url + fileID + fileExt + ")"
    print("Gen File URL for FileID: " + str(fileID) + " URL: " + url)
    return url

#Extracts task details from the description and generates the equivalent markdown
def ReformatBody(body):
    #Extract and write the description
    descriptionRegex = "([\s\S]+?(?=\nUser Data))"
    descriptionMatch = re.search(descriptionRegex, body)
    result = "# Description\n"
    if(descriptionMatch == None):
        result += "Description was not present\n"
    else:
        description = descriptionMatch.groups(0)[0]
        result += description + "\n"

    #Extract and write the user name
    usernameRegex = "(\- \*\*User[N|n]ame\*\*\: \@)(\S*)"
    usernameMatch = re.search(usernameRegex, body)
    result += "# User Data\n"
    result += "- **UserName**: "
    if(usernameMatch == None):
        result += "Username was not present\n"
    else:
        username = usernameMatch.groups(2)[1]
        gitusername = ""

        if username in usersToUsers.keys():
            gitusername = usersToUsers[username]
        result += gitusername + "\n"

    #Extract and write the revision ID
    revisionRegex = "(\- \*\*Revision\*\*\: )(\S*)"
    revisionMatch = re.search(revisionRegex, body)
    result += "\n# Zero Engine Data\n"
    result += "- **Revision**: "
    if(revisionMatch == None):
        result += "Revision was not present\n"
    else:
        revision = revisionMatch.groups(2)[1]
        result += revision + "\n"
    
    #Extract and write the changeset ID
    changeSetRegex = "(\- \*\*ChangeSet\*\*\: )(\S*)"
    changeSetMatch = re.search(changeSetRegex, body)
    result += "- **ChangeSet**: "
    if(changeSetMatch == None):
        result += "changeSet was not present\n"
    else:
        changeSetSHA = changeSetMatch.groups(2)[1]
        result += "zeroengineteam/zerocore@" + changeSetSHA + "\n"

    #Extract and write the platform ID
    platformRegex = "(\- \*\*Platform\*\*\: )(\S*)"
    platformMatch = re.search(platformRegex, body)
    result += "- **Platform**: "
    if(platformMatch == None):
        result += "Platform was not present\n"
    else:
        platform = platformMatch.groups(2)[1]
        result += platform + "\n"
    
    #Extract and write the build version details
    buildVersionRegex = "(\- \*\*Build Version Name\*\*\: )(\S*) (\S*) (\S*) (\S*) (\S*)"
    buildVersionMatch = re.search(buildVersionRegex, body)
    result += "- **Build Version Name**: "
    if(buildVersionMatch == None):
        result += "BuildVersion was not present\n"
    else:
        match = buildVersionMatch.groups(0)
        buildNumber = match[1]
        versionChangeSet = match[2]
        buildDate = match[3]
        buildType = match[4]
        platform = match[5]

        result += buildNumber + " zeroengineteam/zerocore@" + versionChangeSet + " " + buildDate + " " + buildType + " " + platform

    return result

#Returns github usernames for zero engine team members based of the usersToUsers table above
#This function is passed to re.replace in ReplaceUsernames as the callback function for 
#  generating the replacement string on pattern match
def GetGitUserName(matchObjs):
    username = matchObj.group(1)

    if not username in usersToUsers.keys():
        return ""
    return usersToUsers[username]

#Replaces phabricator usernames with github usernames in the task body
def ReplaceUsernames(body):
    userNameRegex = "\@(.*?\..*?)[\.|\s|\s]"
    result = re.sub(userNameRegex, GetGitUserName, body)
    print(result)
    return result

def CloseIssue(issue):
    time.sleep(sleep_interval)
    try:
        result = issue.edit(state="closed")
    except GithubException as e:
        print("exception on closing of task: " + str(e))
        errors = e.data["errors"]
        error = errors[0]
        print(error)
    else:
        print(str(result))
        return result


#Creates and issue on github in the given repo for the given phabricator task
def CreateIssue(repo, task):
    time.sleep(sleep_interval)
    print("Create Issue: ")
    fields = task['fields']
    attachments = task['attachments']
    ownerPHID = fields['ownerPHID']
    print("  OnwerPHID: " + str(ownerPHID))
    ownerPhabUserName = GetUserNameFromPHID(ownerPHID)
    
    title = fields['name']
    body = fields['description']['raw']
    status = fields['status']['value']
    print("  Issue Title: " + title)
    print("    Status: " + status)

    #Set phabricator task owner as the assignee of the github issue
    githubassignees = []
    if not(ownerPhabUserName == None):
        ownerGithubUserName = usersToUsers[ownerPhabUserName]
        print("  Issue Owner:")
        print("    Phabricator Username: " + ownerPhabUserName)
        print("    GitHub Username: " + ownerGithubUserName)
        githubassignees.append(ownerGithubUserName)

    #Set the labels for the github issue to the corresponding phabricator projects
    projects = attachments['projects']
    projectPHIDs = projects['projectPHIDs']
    labels = []

    for phid in projectPHIDs:
        projectName = GetProjectNameFromPHID(phid)
        if(projectName in projectToLabels):
            labels.append(projectToLabels[projectName])

    labelStr = "  Issue Labels: "
    for label in labels:
        labelStr += str(label) + " "

    #find and replace file references with URLs to the zeroengineteam/ZeroFiles repository
    fileIDRegEx = "(\{)(\s*?)F(\d.*?)(\s*?)(,\s*?size=full\s*?|\s*?size=full\s*?|)(\})"
    newBody = re.sub(fileIDRegEx, GenerateFileURL, body)
    newBody = ReformatBody(newBody)

    #attempt issue creation
    issue = None
    try:
        issue = repo.create_issue(title, body=newBody, assignees=githubassignees, labels=labels)
    #If it fails, check to see if it is because assignee is invalid
    except GithubException as e:
        print("exception on creation of task: " + str(e))
        errors = e.data["errors"]
        error = errors[0]
        #If the exception is due to the assignee upload it without the assignee
        if(error["field"] == "assignees"):
            try:
                issue = repo.create_issue(title, body=newBody, labels=labels)
            except GithubException as e:
                print("Attempted to upload issue without assignee and still does not work, moving on.")
            else:
                CloseIssue(issue)
                return issue
    else:
        CloseIssue(issue)
        return issue

sleep_interval = 3

def ProcessTask(tasks):
    if(len(tasks) == 0):
        return;

    task = tasks.pop(0)
    issue = CreateIssue(repo, task)
    print("ProcessTask")
    limit = github.rate_limiting
    print("Limit remaining: " + str(limit))
    if(limit[0] <= 0):
        print("GITHUB RATE LIMIT REACHED")
        print("Last Issue Uploaded: " + str(issue))
        return
    else:
        ProcessTask(tasks)

ProcessTask(tasks)
#task = tasks[0]
#response = CreateIssue(repo,task)


#for task in tasks:
#    issue = CreateIssue(repo, task)
#    print("sleeping")
#    time.sleep(sleep_interval)
#    print("done sleeping")
#    #print(str(issue))
#    limit = github.rate_limiting
#    print("Limit remaining: " + str(limit))
#    if(limit[0] <= 0):
#        print("GITHUB RATE LIMIT REACHED")
#        print("Last Issue Uploaded: " + str(issue))
#        break
#phabToGit #usersToUsers = { #    "arend.danielek" : "ArendDanielek", #    "andrea.ellinger" : "AEllinger", #    "trevor.sundberg" : "TrevorSundberg", #    "joshua.davis" : "jodavis42", #    "joshua.claeys" : "JoshuaClaeys", #    "nathan.carlson" : "Nathan-Carlson", #    "joshua.shlemmer" : "Yellowrobe", #    "doug.zwick" : "douglasZwick", #    "dane.curbow" : "danecurbow", #    "Johannes" :  "JohannesMP", #    "ZeroBugBot" :  "", #    "ryan.edgemon" :  "redgemon", #    "victor.cecci" : "VictorCecci" #} #infileName = "./phab_tasks_remainder_open_10-2.json" #userName = "ArendDanielek" #repoName = "Test" # First create a Github instance: # using username and password # or using an access token #"ArendDanielek", password="<PASSWORD>") #returns github api repo object from user and repo string names # Loads serialized map of file IDs to file extensions generated by PullPhabTasks.py # Load file extension map from file # Loads serialized tasks generated by PullPhabTasks.py #print(inFileContent) # Read in task objects from file #Queries conduit API with user phid and return the string name of the user #print("Get Username from PHID: " + phid) #print("Phabricator reponse: " + str(response)) #Queries conduit API with project phid and return the string name of the project #print("Get project name from PHID: " + phid) #print("Phabricator reponse: " + str(response)) #Returns corresponding github markdown formatted URL when passed a re module MatchObj for a remarkup formatted link #This function is passed to re.replace in CreateIssue as the callback function for #  generating the replacement string on pattern match #Extracts task details from the description and generates the equivalent markdown #Extract and write the description #Extract and write the user name #Extract and write the revision ID # Zero Engine Data\n" #Extract and write the changeset ID #Extract and write the platform ID #Extract and write the build version details #Returns github usernames for zero engine team members based of the usersToUsers table above #This function is passed to re.replace in ReplaceUsernames as the callback function for #  generating the replacement string on pattern match #Replaces phabricator usernames with github usernames in the task body #Creates and issue on github in the given repo for the given phabricator task #Set phabricator task owner as the assignee of the github issue #Set the labels for the github issue to the corresponding phabricator projects #find and replace file references with URLs to the zeroengineteam/ZeroFiles repository #attempt issue creation #If it fails, check to see if it is because assignee is invalid #If the exception is due to the assignee upload it without the assignee #task = tasks[0] #response = CreateIssue(repo,task) #for task in tasks: #    issue = CreateIssue(repo, task) #    print("sleeping") #    time.sleep(sleep_interval) #    print("done sleeping") #    #print(str(issue)) #    limit = github.rate_limiting #    print("Limit remaining: " + str(limit)) #    if(limit[0] <= 0): #        print("GITHUB RATE LIMIT REACHED") #        print("Last Issue Uploaded: " + str(issue)) #        break