[fs2zammad] retry import due to unpredictable 503

This commit is contained in:
fnux 2024-05-02 16:27:50 +02:00
parent 900f8d6a44
commit 807ed89c08
No known key found for this signature in database
GPG key ID: 4502C902C00A1E12

229
fs2zammad
View file

@ -110,133 +110,141 @@ def maybe_create_zammad_user(userdata, zammad_session, attr="login", default=Non
# id, {"roles": roles.append("Agent")} # id, {"roles": roles.append("Agent")}
# ) # )
def create_zammad_ticket(id, zammad, h2t): def create_zammad_ticket(id, zammad, h2t, retries=3):
with open(f"tickets/{id}", "rb") as handle: try:
rt_ticket = pickle.load(handle) with open(f"tickets/{id}", "rb") as handle:
rt_ticket = pickle.load(handle)
label = "RT-{}".format(rt_ticket["ticket"]["original_id"]) label = "RT-{}".format(rt_ticket["ticket"]["original_id"])
creator = rt_ticket["ticket"]["Creator"] creator = rt_ticket["ticket"]["Creator"]
with open(f"users/{creator}", "rb") as handle: with open(f"users/{creator}", "rb") as handle:
rt_creator = pickle.load(handle) rt_creator = pickle.load(handle)
# The RT user object doesn't always contain everything (e.g. disabled users). # The RT user object doesn't always contain everything (e.g. disabled users).
if "EmailAddress" in rt_creator: if "EmailAddress" in rt_creator:
creator = rt_creator["EmailAddress"] creator = rt_creator["EmailAddress"]
print(f"Importing {label} ({creator})") print(f"Importing {label} ({creator})")
zammad_creator = maybe_create_zammad_user(rt_creator, zammad) zammad_creator = maybe_create_zammad_user(rt_creator, zammad)
# Make sure that we use what we created in Zammad, independently of what we # Make sure that we use what we created in Zammad, independently of what we
# had in RT. # had in RT.
creator = zammad_creator creator = zammad_creator
zammad_ticket_template = { zammad_ticket_template = {
"title": rt_ticket["ticket"]["Subject"], "title": rt_ticket["ticket"]["Subject"],
"group": "Users", "group": "Users",
"customer": creator, "customer": creator,
"note": "RT-import:{}".format(rt_ticket["ticket"]["original_id"]), "note": "RT-import:{}".format(rt_ticket["ticket"]["original_id"]),
"article": { "article": {
"subject": rt_ticket["ticket"]["Subject"], "subject": rt_ticket["ticket"]["Subject"],
}, },
} }
# Ticket creation. # Ticket creation.
merged = False merged = False
if rt_ticket["ticket"]["original_id"] != rt_ticket["ticket"]["numerical_id"]: if rt_ticket["ticket"]["original_id"] != rt_ticket["ticket"]["numerical_id"]:
merged = True merged = True
zammad_ticket_template["state_id"] = STATUSMAP["resolved"] zammad_ticket_template["state_id"] = STATUSMAP["resolved"]
zammad_ticket_template["article"]["body"] = "RT ticket merged into {}".format( zammad_ticket_template["article"]["body"] = "RT ticket merged into {}".format(
rt_ticket["ticket"]["numerical_id"] rt_ticket["ticket"]["numerical_id"]
) )
zammad_ticket = get_zammad_session(creator).ticket.create(zammad_ticket_template) zammad_ticket = get_zammad_session(creator).ticket.create(zammad_ticket_template)
else: else:
zammad_ticket_template["state_id"] = STATUSMAP[rt_ticket["ticket"]["Status"]] zammad_ticket_template["state_id"] = STATUSMAP[rt_ticket["ticket"]["Status"]]
body = rt_ticket["history"][0]["Content"] or 'RT Import: empty comment.' body = rt_ticket["history"][0]["Content"] or 'RT Import: empty comment.'
zammad_ticket_template["article"]["body"] = body zammad_ticket_template["article"]["body"] = body
zammad_ticket = get_zammad_session(creator).ticket.create(zammad_ticket_template) zammad_ticket = get_zammad_session(creator).ticket.create(zammad_ticket_template)
print(f"Created Zammad ticket {zammad_ticket['id']} for {label}") print(f"Created Zammad ticket {zammad_ticket['id']} for {label}")
if rt_ticket["ticket"]["Owner"] and rt_ticket["ticket"]["Owner"] != "Nobody": if rt_ticket["ticket"]["Owner"] and rt_ticket["ticket"]["Owner"] != "Nobody":
zammad_owner_id = maybe_create_zammad_user(rt_ticket["ticket"]["Owner"], zammad, "id") zammad_owner_id = maybe_create_zammad_user(rt_ticket["ticket"]["Owner"], zammad, "id")
zammad.ticket.update( zammad.ticket.update(
zammad_ticket["id"], {"owner_id": zammad_owner_id} zammad_ticket["id"], {"owner_id": zammad_owner_id}
)
# Ignore comments for merged tickets.
if merged:
return
# Internal note regarding the RT-Zammad import.
TicketArticle(zammad).create(
{
"ticket_id": zammad_ticket["id"],
"body": COMMENT_TEMPLATE.format(**rt_ticket["ticket"]),
"internal": True,
}
) )
# Ignore comments for merged tickets. # Comments/notes within the ticket.
if merged: for entry in rt_ticket["history"]:
return if entry["Type"] not in ("Correspond", "Comment"):
# Internal note regarding the RT-Zammad import.
TicketArticle(zammad).create(
{
"ticket_id": zammad_ticket["id"],
"body": COMMENT_TEMPLATE.format(**rt_ticket["ticket"]),
"internal": True,
}
)
# Comments/notes within the ticket.
for entry in rt_ticket["history"]:
if entry["Type"] not in ("Correspond", "Comment"):
continue
# Attachments.
files = []
may_contain_entry_content = None
for a, title in entry["Attachments"]:
with open(f"attachments/{id}/{a}", "rb") as handle:
data = pickle.load(handle)
if data["Filename"] == "signature.asc":
continue continue
file_template = { # Attachments.
"filename": data["Filename"], files = []
"data": base64.b64encode(data["Content"]).decode("utf-8"), may_contain_entry_content = None
"mime-type": data["ContentType"], for a, title in entry["Attachments"]:
} with open(f"attachments/{id}/{a}", "rb") as handle:
data = pickle.load(handle)
if data["Filename"] == '': if data["Filename"] == "signature.asc":
if may_contain_entry_content is None: continue
may_contain_entry_content = file_template
else: file_template = {
files.append(file_template) "filename": data["Filename"],
"data": base64.b64encode(data["Content"]).decode("utf-8"),
"mime-type": data["ContentType"],
}
if data["Filename"] == '':
if may_contain_entry_content is None:
may_contain_entry_content = file_template
else:
files.append(file_template)
# Comment/note. # Comment/note.
entry_creator = entry["Creator"] entry_creator = entry["Creator"]
with open(f"users/{entry_creator}", "rb") as handle: with open(f"users/{entry_creator}", "rb") as handle:
rt_entry_creator = pickle.load(handle) rt_entry_creator = pickle.load(handle)
zammad_entry_creator = maybe_create_zammad_user(rt_entry_creator, zammad) zammad_entry_creator = maybe_create_zammad_user(rt_entry_creator, zammad)
entry_content = entry["Content"] entry_content = entry["Content"]
if entry_content == '' and may_contain_entry_content: if entry_content == '' and may_contain_entry_content:
file = may_contain_entry_content file = may_contain_entry_content
entry_content = base64.b64decode(file["data"]).decode("utf-8") entry_content = base64.b64decode(file["data"]).decode("utf-8")
if file["mime-type"]: if file["mime-type"]:
entry_content = h2t.handle(entry_content) entry_content = h2t.handle(entry_content)
zammad_entry_template = { zammad_entry_template = {
"ticket_id": zammad_ticket["id"], "ticket_id": zammad_ticket["id"],
"body": entry_content, "body": entry_content,
"internal": entry["Type"] == "Comment", "internal": entry["Type"] == "Comment",
"attachments": files, "attachments": files,
} }
entry_creator_id = maybe_create_zammad_user(zammad_entry_creator, zammad, "id") entry_creator_id = maybe_create_zammad_user(zammad_entry_creator, zammad, "id")
# We temporarly change the ticket's creator to create a new entry # We temporarly change the ticket's creator to create a new entry
# without giving its author 'Agent' privileges. # without giving its author 'Agent' privileges.
restore_creator_to = None restore_creator_to = None
if entry_creator_id != zammad_ticket["customer_id"]: if entry_creator_id != zammad_ticket["customer_id"]:
zammad.ticket.update(zammad_ticket["id"], {"customer_id": entry_creator_id}) zammad.ticket.update(zammad_ticket["id"], {"customer_id": entry_creator_id})
restore_creator_to = zammad_ticket["customer_id"] restore_creator_to = zammad_ticket["customer_id"]
zammad_ticket_id = zammad_ticket["id"] zammad_ticket_id = zammad_ticket["id"]
print(f"-> Adding a new entry/comment to ticket {zammad_ticket_id} ({zammad_entry_creator})...") print(f"-> Adding a new entry/comment to ticket {zammad_ticket_id} ({zammad_entry_creator})...")
TicketArticle(get_zammad_session(zammad_entry_creator)).create(zammad_entry_template) TicketArticle(get_zammad_session(zammad_entry_creator)).create(zammad_entry_template)
if restore_creator_to != None: if restore_creator_to != None:
zammad.ticket.update(zammad_ticket["id"], {"customer_id": restore_creator_to}) zammad.ticket.update(zammad_ticket["id"], {"customer_id": restore_creator_to})
except KeyboardInterrupt:
print("Received keyboard interrupt. Exiting.")
sys.exit()
except:
print(f"Failed to import RT-#{id} .. ({retries} retries left)")
if retries > 0:
create_zammad_ticket(id, zammad, h2t, retries - 1)
### main logic ### ### main logic ###
@ -262,9 +270,8 @@ print(f"Found {len(ticket_ids)} tickets on filesystem.")
for id in ticket_ids: for id in ticket_ids:
try: try:
create_zammad_ticket(id, zammad, h2t) create_zammad_ticket(id, zammad, h2t, 3)
except KeyboardInterrupt: except SystemExit:
print("Received keyboard interrupt. Exiting.")
sys.exit() sys.exit()
except: except:
print(f"Failed to import RT#{id}") print(f"Failed to import RT#{id}")