Compare commits

...

10 Commits

Author SHA1 Message Date
fnux b44e8eb96a
Add initial rt2fs script 2024-04-18 15:53:32 +02:00
Michal Čihař 7d70eff100 Add disclaimer as a first step 2020-12-30 14:06:20 +01:00
Michal Čihař e19dd7da3b Utilize f-string 2020-12-30 13:44:03 +01:00
Michal Čihař d8a43642cb Apply black 2020-12-30 13:43:40 +01:00
Michal Čihař bbc600b0b1 Retain ticket ownership 2020-12-30 13:43:06 +01:00
Michal Čihař d32e9859f7 Simplify ticket subject 2020-12-30 13:42:48 +01:00
Michal Čihař b3383c542a Share code for creating tickets 2020-12-30 13:30:22 +01:00
Michal Čihař ab0f3f843a Fix creating owned tickets 2020-12-30 13:14:41 +01:00
Michal Čihař b06e01a774 Fix old ticket URL 2020-12-30 13:14:33 +01:00
Michal Čihař 33d2cbf533 Fix tag assignment 2020-12-30 11:58:40 +01:00
3 changed files with 128 additions and 30 deletions

View File

@ -23,6 +23,7 @@ myself. Pull requests are still welcome though.
## Usage
0. Review the script code, most likely it will not work out of box for you.
1. Prepare virtualenv and install dependencies: `virtualenv .venv --python python 3; . .venv/bin/activate ; pip install -r requirements.txt`
2. Start `rt2zammad.py`, it will display template for configuration file.
3. Fill in the template and save it as `rt2zammad.json`.

88
rt2fs Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env python
import base64
import json
import os
import pickle
import sys
from multiprocessing import Pool
from rt.rest1 import Rt
TEMPLATE = """{
"zammad_url": "",
"zammad_user": "",
"zammad_password": "",
"rt_url": "",
"rt_user": "",
"rt_pass": "",
"rt_start": 1,
"rt_end": 1000,
"usermap": {},
"userdata": {}
}
"""
### helpers ###
def maybe_dump_user(rt, username):
dumpfile = f"users/{username}"
if not os.path.exists(dumpfile):
user = rt.get_user(username)
with open(dumpfile, "wb") as handle:
pickle.dump(user, handle)
### 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)
rt = Rt(config["rt_url"], config["rt_user"], config["rt_pass"])
if not rt.login():
print("Failed to login to RT!")
sys.exit(2)
os.makedirs("users", exist_ok=True)
os.makedirs("tickets", exist_ok=True)
os.makedirs("attachments", exist_ok=True)
ticket_ids = range(config["rt_start"], config["rt_end"])
def dump(id):
print(f"Dumping RT#{id}")
ticket_dumpfile = f"tickets/{id}"
if not os.path.exists(ticket_dumpfile):
ticket = rt.get_ticket(id)
if ticket is None:
print("Got 'None' while fetching ticket")
os.exit(1)
ticket["original_id"] = str(id)
if ticket["Queue"] != 'spam':
maybe_dump_user(rt, ticket["Creator"])
maybe_dump_user(rt, ticket["Owner"])
if ticket["original_id"] != ticket["numerical_id"]:
# Merged ticket
history = []
else:
history = rt.get_history(id)
for item in history:
for a, title in item["Attachments"]:
attachment = rt.get_attachment(id, a)
os.makedirs(f"attachments/{id}", exist_ok=True)
with open(f"attachments/{id}/{a}", "wb") as handle:
pickle.dump(attachment, handle)
maybe_dump_user(rt, item["Creator"])
data = {"ticket": ticket, "history": history}
with open(ticket_dumpfile, "wb") as handle:
pickle.dump(data, handle)
worker_count = 4
with Pool(worker_count) as p:
p.map(dump, ticket_ids, chunksize=10)

View File

@ -23,7 +23,7 @@ class Tag(Resource):
self.url + "/add",
data={
"object": obj,
"id": id,
"o_id": id,
"item": item,
},
)
@ -48,7 +48,7 @@ TEMPLATE = """{
COMMENT_TEMPLATE = """
Ticket imported from Request Tracker
URL: https://support.weblate.org/Ticket/Display.html?id={numerical_id}
URL: https://oldsupport.weblate.org/Ticket/Display.html?id={numerical_id}
Created: {Created}
Resolved: {Resolved}
"""
@ -77,7 +77,7 @@ def get_zammad(user=None):
username=config["zammad_user"],
password=config["zammad_password"],
is_secure=config["zammad_secure"],
**kwargs
**kwargs,
)
return ZAMMADS[user]
@ -111,7 +111,7 @@ else:
users[username] = source.get_user(username)
for i in range(config["rt_start"], config["rt_end"]):
print("Loading ticket {}".format(i))
print(f"Loading ticket {i}")
ticket = source.get_ticket(i)
if ticket is None:
break
@ -194,36 +194,45 @@ def get_user(userdata, attr="login", default=None):
# Create tickets
for ticket in tickets:
label = "RT-{}".format(ticket["ticket"]["original_id"])
print("Importing {}".format(label))
creator = get_user(users[ticket["ticket"]["Creator"]])
print(f"Importing {label} ({creator})")
create_args = {
"title": ticket["ticket"]["Subject"],
"group": "Users",
"customer": creator,
"note": "RT-import:{}".format(ticket["ticket"]["original_id"]),
"article": {
"subject": ticket["ticket"]["Subject"],
},
}
merged = False
if ticket["ticket"]["original_id"] != ticket["ticket"]["numerical_id"]:
# Merged ticket
get_zammad(get_user(users[ticket["ticket"]["Creator"]])).ticket.create(
{
"title": "{} [{}]".format(ticket["ticket"]["Subject"], label),
"group": "Users",
"state_id": 4,
"note": "RT-import:{}".format(ticket["ticket"]["original_id"]),
"article": {
"subject": ticket["ticket"]["Subject"],
"body": "RT ticket merged into {}".format(
ticket["ticket"]["numerical_id"]
),
},
}
merged = True
create_args["state_id"] = 4
create_args["article"]["body"] = "RT ticket merged into {}".format(
ticket["ticket"]["numerical_id"]
)
new = get_zammad(creator).ticket.create(create_args)
else:
create_args["state_id"] = STATUSMAP[ticket["ticket"]["Status"]]
create_args["article"]["body"] = ticket["history"][0]["Content"]
new = get_zammad(creator).ticket.create(create_args)
print(f"Created ticket {new['id']}")
if ticket["ticket"]["Owner"] and ticket["ticket"]["Owner"] != "Nobody":
get_zammad().ticket.update(
new["id"], {"owner_id": get_user(users[ticket["ticket"]["Owner"]], "id")}
)
if merged:
# Do not add comments to merged ticket
continue
new = get_zammad(get_user(users[ticket["ticket"]["Creator"]])).ticket.create(
{
"title": "{} [{}]".format(ticket["ticket"]["Subject"], label),
"group": "Users",
"state_id": STATUSMAP[ticket["ticket"]["Status"]],
"note": "RT-import:{}".format(ticket["ticket"]["original_id"]),
"article": {
"subject": ticket["ticket"]["Subject"],
"body": ticket["history"][0]["Content"],
},
}
)
tag_obj.add("Ticket", new["id"], ticket["ticket"]["Queue"].lower().split()[0])
ticket_article.create(
{