[fs2zammad] retry import due to unpredictable 503
This commit is contained in:
parent
900f8d6a44
commit
807ed89c08
1 changed files with 118 additions and 111 deletions
229
fs2zammad
229
fs2zammad
|
@ -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}")
|
||||||
|
|
Loading…
Reference in a new issue