diff --git a/ticket_transfer.py b/ticket_transfer.py
index ba7b352..743c8bc 100644
--- a/ticket_transfer.py
+++ b/ticket_transfer.py
@@ -13,6 +13,8 @@ import base64
import urllib.parse
from datetime import datetime
from dateutil.relativedelta import relativedelta
+import itertools
+import threading
###################################
# Function Definitions
@@ -59,6 +61,22 @@ def makeCall (target, verb, key, payload= None, files= None):
except Exception as error:
print(f'{RED}Error:{RESET}\n{error}')
raise
+ if verb.lower() == 'put':
+ try:
+ response = requests.put(target, auth=(key, 'X'), json= payload)
+ if response.status_code != 429:
+ response.raise_for_status()
+ responseData = response.json()
+ if (checkRate(response)):
+ return makeCall(target, verb, key, payload)
+ return responseData
+ except requests.exceptions.HTTPError as http_error:
+ print(f'{RED}HTTP Error:{RESET}\n{http_error}')
+ print(f'Reponse Content: {response.content}')
+ raise
+ except Exception as error:
+ print(f'{RED}Error:{RESET}\n{error}')
+ raise
# Clears out the specified number of console lines
def clear(number):
@@ -111,6 +129,26 @@ def buildTicketArray(domain, groupId, key):
currentDate -= relativedelta(months=1)
return retArray
+def spinner():
+ anim = itertools.cycle(['◑', '◒', '◐', '◓'])
+ while not stopSpin.is_set():
+ sys.stdout.write(f'\r{message}{next(anim)}\n')
+ sys.stdout.flush()
+ time.sleep(0.1)
+ clear(1)
+
+def start_spinner(msg):
+ global stopSpin, message
+ stopSpin.clear()
+ message = msg
+ spinner_thread = threading.Thread(target=spinner)
+ spinner_thread.start()
+ return spinner_thread
+
+def stop_spinner(spinner_thread):
+ stopSpin.set()
+ spinner_thread.join()
+
###################################
# Globals Variables
###################################
@@ -126,6 +164,8 @@ RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
RESET = '\033[0m'
+stopSpin = threading.Event()
+spinnerThread = threading.Thread(target=spinner)
###################################
# Main Loop
@@ -187,37 +227,27 @@ else:
## Building Definition Arrays
-print(f'Obtaining account information...◐')
+spinner_thread = start_spinner('Obtaining account information...')
groupIdDefs_source = makeCall(sourceDom + '/api/v2/groups', 'get', sourceKey)
-clear(1)
-print(f'Obtaining account information...◓')
groupIdDefs_dest = makeCall(destDom + '/api/v2/groups', 'get', destKey)
-clear(1)
-print(f'Obtaining account information...◑')
-for i, group in enumerate(groupIdDefs_source):
- anim = ['◒','◐', '◓', '◑']
+for group in groupIdDefs_source:
if group["name"] == targetGroup:
targetGroupId = group["id"]
break
- clear(1)
- print(f'Obtaining account information...{anim[i % len(anim)]}')
-clear(1)
+stop_spinner(spinner_thread)
print(f'Obtaining account information...{GREEN}COMPLETE{RESET}')
## Building Ticket Array from Source
-print(f'Gathering list of tickets from source...')
-#ticketArray = makeCall(sourceDom + '/api/v2/search/tickets?query=' + urllib.parse.urlencode(f'"group_id:\'{targetGroupId}\'"'), 'get', sourceKey)
-#ticketArray = makeCall(f'{sourceDom}/api/v2/search/tickets?query="group_id:{targetGroupId}"', 'get', sourceKey)
+spinner_thread = start_spinner('Gathering list of tickets from source...')
ticketArray = buildTicketArray(sourceDom, targetGroupId, sourceKey)
-clear(1)
+stop_spinner(spinner_thread)
print(f'Gathering list of tickets from source...{GREEN}COMPLETE{RESET}')
## Transferring tickets to Destination
print(f'{YELLOW}*This may take a while*{RESET}')
-print(f'Transferring tickets to destination account...◐')
-for i, ticket in enumerate(ticketArray):
+spinner_thread = start_spinner(f'Transferring tickets to destination account...')
+for ticket in ticketArray:
attachments = {}
- anim = ['◓', '◑', '◒', '◐']
ticketData = makeCall(sourceDom + f'/api/v2/tickets/{ticket["id"]}?include=conversations,requester', 'get', sourceKey)
if 'attachments' in ticketData:
for attachment in ticketData['attachments']:
@@ -238,7 +268,7 @@ for i, ticket in enumerate(ticketArray):
'source': ticketData["source"],
}
newTicket = makeCall(destDom + '/api/v2/tickets', 'post', destKey, payload, attachments if attachments else None)
-
+ ticket['new_ticket'] = newTicket['id']
## Gaterhing conversation history from ticketData, and then updating the ticket to include them in a private note
if len(ticketData['conversations']) > 0:
convos = '''
@@ -260,12 +290,19 @@ for i, ticket in enumerate(ticketArray):
elif convo['private'] == False and convo['incoming'] == False:
convos += f'Outgoing Reply from {username}:
{convo["body"]}
---------------------------
'
makeCall(destDom + f'/api/v2/tickets/{newTicket["id"]}/notes', 'post', destKey,{'body': convos})
-
- clear(1)
- print(f'Transferring tickets to destination account...{anim[i % len(anim)]}')
- i += 1
-clear(2)
+stop_spinner(spinner_thread)
+clear(1)
print(f'Transferring tickets to destination account...{GREEN}COMPLETE{RESET}')
+spinner_thread = start_spinner('Closing transferred tickets on source account...')
+for ticket in ticketArray:
+ noteBody = f'''
+ Ticket has been transferred to {destDom}/a/tickets/{ticket['new_ticket']}
+ Ticket ID: {ticket['new_ticket']}
+ '''
+ makeCall(sourceDom + f'/api/v2/tickets/{ticket["id"]}/notes', 'post', sourceKey, {'body': noteBody})
+ makeCall(sourceDom + f'/api/v2/tickets/{ticket["id"]}', 'put', sourceKey, {'status': 5})
+stop_spinner(spinner_thread)
+print(f'Closing transferred tickets on source account...{GREEN}COMPLETE{RESET}')
print(f'{GREEN}*TICKET TRANSFER COMPLETED SUCCESSFULLY*{RESET}')
for i in range(5, 0, -1):
print(f'Exiting in {i} seconds...')