110 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
import base64
 | 
						|
import json
 | 
						|
import os
 | 
						|
import pickle
 | 
						|
import sys
 | 
						|
import html2text
 | 
						|
import traceback
 | 
						|
import time
 | 
						|
 | 
						|
from zammad_py import ZammadAPI
 | 
						|
from zammad_py.api import Resource, TagList, TicketArticle
 | 
						|
 | 
						|
TEMPLATE = """{
 | 
						|
"zammad_url": "",
 | 
						|
"zammad_user": "",
 | 
						|
"zammad_password": "",
 | 
						|
"rt_url": "",
 | 
						|
"rt_user": "",
 | 
						|
"rt_pass": "",
 | 
						|
"rt_start": 1,
 | 
						|
"rt_end": 1000,
 | 
						|
}
 | 
						|
"""
 | 
						|
 | 
						|
COMMENT_TEMPLATE = """
 | 
						|
Ticket imported from Request Tracker (RT-#{numerical_id})
 | 
						|
 | 
						|
URL: https://support.ungleich.ch/Ticket/Display.html?id={numerical_id}
 | 
						|
Created: {Created}
 | 
						|
Resolved: {Resolved}
 | 
						|
"""
 | 
						|
 | 
						|
STATUSMAP = {"new": 1, "open": 2, "resolved": 4, "rejected": 4, "deleted": 4}
 | 
						|
USERMAP = {}
 | 
						|
 | 
						|
ZAMMAD_SESSIONS = {}
 | 
						|
 | 
						|
### helpers ###
 | 
						|
 | 
						|
def get_zammad_session(impersonated_user=None):
 | 
						|
    if impersonated_user in ZAMMAD_SESSIONS:
 | 
						|
        return ZAMMAD_SESSIONS[impersonated_user]
 | 
						|
    else:
 | 
						|
        kwargs = {}
 | 
						|
        if impersonated_user:
 | 
						|
            kwargs["on_behalf_of"] = impersonated_user
 | 
						|
        session = ZammadAPI(
 | 
						|
            url=config["zammad_host"],
 | 
						|
            username=config["zammad_user"],
 | 
						|
            password=config["zammad_password"],
 | 
						|
            **kwargs,
 | 
						|
        )
 | 
						|
        ZAMMAD_SESSIONS[impersonated_user or config["zammad_user"]] = session
 | 
						|
 | 
						|
        return session
 | 
						|
 | 
						|
def remove_duplicates_for(rt_id, zammad, retries=0):
 | 
						|
    try:
 | 
						|
        matching_zammad_tickets= zammad.ticket.search(f"title: \"\[RT-{rt_id}\]*\"")
 | 
						|
        matching_zammad_ids = []
 | 
						|
        if len(matching_zammad_tickets) >= 2:
 | 
						|
            print(f"Found duplicates:")
 | 
						|
            for zt in matching_zammad_tickets:
 | 
						|
                print(f"{zt["id"]} {zt["title"]}")
 | 
						|
                matching_zammad_ids.append(zt["id"])
 | 
						|
 | 
						|
        if len(matching_zammad_ids) >= 2:
 | 
						|
            matching_zammad_ids.sort()
 | 
						|
            matching_zammad_ids.pop()
 | 
						|
            for zt_id in matching_zammad_ids:
 | 
						|
                print(f"Deleting Zammad ticket {zt_id}")
 | 
						|
                zammad.ticket.destroy(zt_id)
 | 
						|
 | 
						|
    except:
 | 
						|
        print(f"Failed to process RT-{rt_id} .. ({retries} retries left)")
 | 
						|
        if retries > 0:
 | 
						|
            print("Sleeping 5 seconds to give Zammad some air...")
 | 
						|
            time.sleep(5)
 | 
						|
            remove_duplicates_for(id, retries - 1)
 | 
						|
        else:
 | 
						|
             traceback.print_exc()
 | 
						|
             raise RuntimeError
 | 
						|
 | 
						|
### main logic ###
 | 
						|
 | 
						|
if not os.path.exists("rt2zammad.json"):
 | 
						|
    print("Missing rt2zammad.json!")
 | 
						|
    print("Create one based on following template:")
 | 
						|
    print(TEMPLATE)
 | 
						|
    sys.exit(1)
 | 
						|
 | 
						|
with open("rt2zammad.json") as handle:
 | 
						|
    config = json.load(handle)
 | 
						|
 | 
						|
h2t = html2text.HTML2Text()
 | 
						|
zammad = get_zammad_session()
 | 
						|
 | 
						|
os.makedirs("tickets", exist_ok=True)
 | 
						|
 | 
						|
 | 
						|
ticket_ids = os.listdir("tickets/")
 | 
						|
print(f"Found {len(ticket_ids)} tickets on filesystem.")
 | 
						|
ticket_ids = list(map(int, ticket_ids))
 | 
						|
ticket_ids.sort()
 | 
						|
 | 
						|
for id in ticket_ids:
 | 
						|
    print(f"Processing RT-{id}...")
 | 
						|
    remove_duplicates_for(id, zammad)
 |