diff --git a/config.ini b/config.ini index 67b6d0b..383a994 100644 --- a/config.ini +++ b/config.ini @@ -10,3 +10,6 @@ userstory_custom_field_name = Platform link initial_task_status = New +[webserver] +host = localhost +port = 9080 diff --git a/importer.py b/importer.py index f73dc48..c3c8742 100644 --- a/importer.py +++ b/importer.py @@ -1,10 +1,25 @@ import os +import sys import uuid +import argparse import tempfile import requests import configparser import urllib.parse from taiga import TaigaAPI +from bottle import run, put, request, response + +try: + scriptname = os.path.basename(__file__) +except: + scriptname = "importer.py" +parser = argparse.ArgumentParser( + prog = scriptname, + description = "Import printables.com links into your taiga instance", + epilog = "The source of this program can be found at: https://git.geekify.de/sqozz/taiga-printable-importer") +parser.add_argument("-u", "--url", help="printables.com model url to import into taiga") +parser.add_argument("-w", "--enable-webserver", help="enable a webserver to receive URLs continuously", action=argparse.BooleanOptionalAction) +args = parser.parse_args() # Config parsing CONFIG=configparser.ConfigParser() @@ -203,66 +218,93 @@ def get_modelid_from_url(url): model_id = model_slug.split("-")[0] return model_id -link = input("Please paste link: ") -model_id = get_modelid_from_url(link) -print_data = get_printables_print_data(model_id) -api = TaigaAPI(host=CONFIG["taiga"]["url"]) -api.auth( - username=CONFIG["taiga"]["username"], - password=CONFIG["taiga"]["password"] -) -proj = api.projects.get_by_slug(CONFIG["taiga"]["project_slug"]) +@put('/import') +def http_import(): + data = request.body.read() + url = data.decode("utf-8") + us_url = generate_taiga_userstory(url) + response.set_header('Content-Location', us_url) + response.status = 201 -# Create userstory for printable -story = proj.add_user_story( - print_data["name"], - description = print_data["description"], - tags = list(map(lambda x: x.get("name"), print_data["tags"]))) +def generate_from_cmdline(): + link = get_url_interactively() + us_url = generate_taiga_userstory(link) + return us_url -# Set custom field for platform link if enabled and configured -if bool(CONFIG["taiga"]["userstory_use_custom_field"]): - us_attributes = list(map(lambda x: {"id": x.id, "name": x.name}, api.user_story_attributes.list())) - attribute_id = list(filter(lambda x: CONFIG["taiga"]["userstory_custom_field_name"] in x["name"], us_attributes))[0]["id"] - story.set_attribute(attribute_id, link) +def get_url_interactively(): + url = input("Please paste link: ") + return url -# Find id for desired status of newly tasks -task_statuses = list(map(lambda x: {"id": x.id, "name": x.name}, api.task_statuses.list())) -task_status_id = list(filter(lambda x: CONFIG["taiga"]["initial_task_status"] == x["name"], task_statuses))[0]["id"] +def generate_taiga_userstory(link): + model_id = get_modelid_from_url(link) + print_data = get_printables_print_data(model_id) + api = TaigaAPI(host=CONFIG["taiga"]["url"]) + api.auth( + username=CONFIG["taiga"]["username"], + password=CONFIG["taiga"]["password"] + ) + proj = api.projects.get_by_slug(CONFIG["taiga"]["project_slug"]) + + # Create userstory for printable + story = proj.add_user_story( + print_data["name"], + description = print_data["description"], + tags = list(map(lambda x: x.get("name"), print_data["tags"]))) + + # Set custom field for platform link if enabled and configured + if bool(CONFIG["taiga"]["userstory_use_custom_field"]): + us_attributes = list(map(lambda x: {"id": x.id, "name": x.name}, api.user_story_attributes.list())) + attribute_id = list(filter(lambda x: CONFIG["taiga"]["userstory_custom_field_name"] in x["name"], us_attributes))[0]["id"] + story.set_attribute(attribute_id, link) + + # Find id for desired status of newly tasks + task_statuses = list(map(lambda x: {"id": x.id, "name": x.name}, api.task_statuses.list())) + task_status_id = list(filter(lambda x: CONFIG["taiga"]["initial_task_status"] == x["name"], task_statuses))[0]["id"] -tmpdir = tempfile.TemporaryDirectory() #workdir for downloads + tmpdir = tempfile.TemporaryDirectory() #workdir for downloads -imagepath = print_data["images"][0]["filePath"] -imageurl = urllib.parse.urljoin("https://media.printables.com", imagepath) -local_file = os.path.join(tmpdir.name, os.path.basename(imagepath)) -print("Downloading first image of printable to {}…".format(local_file), end="") -with requests.get(imageurl, stream=True) as r: - r.raise_for_status() - with open(local_file, "wb") as f: - for chunk in r.iter_content(chunk_size=8192): - f.write(chunk) -print(" done.") - -story.attach(local_file) - -stls = list(filter(lambda x: x["filePath"].endswith(".stl"), print_data["stls"])) -stl_files = list(map(lambda x: {"name": x["name"], "filePath": x["filePath"]},stls)) -for stl_file in stl_files: - stlpath = stl_file["filePath"] - filename = os.path.basename(stlpath) - print("Creating task for file {}…".format(filename), end="") - - task = story.add_task(filename, task_status_id) - - stlurl = urllib.parse.urljoin("https://files.printables.com", stlpath) - local_file = os.path.join(tmpdir.name, filename) - with requests.get(stlurl, stream=True) as r: + imagepath = print_data["images"][0]["filePath"] + imageurl = urllib.parse.urljoin("https://media.printables.com", imagepath) + local_file = os.path.join(tmpdir.name, os.path.basename(imagepath)) + print("Downloading first image of printable to {}…".format(local_file), end="") + with requests.get(imageurl, stream=True) as r: r.raise_for_status() with open(local_file, "wb") as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) - task.attach(local_file) print(" done.") -newstory_url= urllib.parse.urljoin(CONFIG["taiga"]["url"], os.path.join("project", CONFIG["taiga"]["project_slug"], "us", str(story.ref))) -print("New story created at: {}".format(newstory_url)) + story.attach(local_file) + + stls = list(filter(lambda x: x["filePath"].endswith(".stl"), print_data["stls"])) + stl_files = list(map(lambda x: {"name": x["name"], "filePath": x["filePath"]},stls)) + for stl_file in stl_files: + stlpath = stl_file["filePath"] + filename = os.path.basename(stlpath) + print("Creating task for file {}…".format(filename), end="") + + task = story.add_task(filename, task_status_id) + + stlurl = urllib.parse.urljoin("https://files.printables.com", stlpath) + local_file = os.path.join(tmpdir.name, filename) + with requests.get(stlurl, stream=True) as r: + r.raise_for_status() + with open(local_file, "wb") as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + task.attach(local_file) + print(" done.") + + newstory_url= urllib.parse.urljoin(CONFIG["taiga"]["url"], os.path.join("project", CONFIG["taiga"]["project_slug"], "us", str(story.ref))) + return newstory_url + +if __name__ == "__main__": + if bool(args.enable_webserver) == True: + run(host=CONFIG["webserver"]["host"], port=CONFIG["webserver"]["port"]) + sys.exit(0) + elif args.url != None: + us_url = generate_taiga_userstory(args.url) + else: + us_url = generate_from_cmdline() + print("New story created at: {}".format(us_url)) diff --git a/requirements.txt b/requirements.txt index a9c7fbb..8871b1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ python-taiga requests +bottle