Add webserver capabilities

This enables the script to be either used interactively or from outside
services (e.g. userscripts).
This commit is contained in:
sqozz 2023-02-27 15:57:58 +01:00
parent 6976f919c5
commit 55c15da039
3 changed files with 97 additions and 51 deletions

View File

@ -10,3 +10,6 @@ userstory_custom_field_name = Platform link
initial_task_status = New initial_task_status = New
[webserver]
host = localhost
port = 9080

View File

@ -1,10 +1,25 @@
import os import os
import sys
import uuid import uuid
import argparse
import tempfile import tempfile
import requests import requests
import configparser import configparser
import urllib.parse import urllib.parse
from taiga import TaigaAPI 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 parsing
CONFIG=configparser.ConfigParser() CONFIG=configparser.ConfigParser()
@ -203,66 +218,93 @@ def get_modelid_from_url(url):
model_id = model_slug.split("-")[0] model_id = model_slug.split("-")[0]
return model_id return model_id
link = input("Please paste link: ") @put('/import')
model_id = get_modelid_from_url(link) def http_import():
print_data = get_printables_print_data(model_id) data = request.body.read()
api = TaigaAPI(host=CONFIG["taiga"]["url"]) url = data.decode("utf-8")
api.auth( us_url = generate_taiga_userstory(url)
username=CONFIG["taiga"]["username"], response.set_header('Content-Location', us_url)
password=CONFIG["taiga"]["password"] response.status = 201
)
proj = api.projects.get_by_slug(CONFIG["taiga"]["project_slug"])
# Create userstory for printable def generate_from_cmdline():
story = proj.add_user_story( link = get_url_interactively()
print_data["name"], us_url = generate_taiga_userstory(link)
description = print_data["description"], return us_url
tags = list(map(lambda x: x.get("name"), print_data["tags"])))
# Set custom field for platform link if enabled and configured def get_url_interactively():
if bool(CONFIG["taiga"]["userstory_use_custom_field"]): url = input("Please paste link: ")
us_attributes = list(map(lambda x: {"id": x.id, "name": x.name}, api.user_story_attributes.list())) return url
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 def generate_taiga_userstory(link):
task_statuses = list(map(lambda x: {"id": x.id, "name": x.name}, api.task_statuses.list())) model_id = get_modelid_from_url(link)
task_status_id = list(filter(lambda x: CONFIG["taiga"]["initial_task_status"] == x["name"], task_statuses))[0]["id"] 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"] imagepath = print_data["images"][0]["filePath"]
imageurl = urllib.parse.urljoin("https://media.printables.com", imagepath) imageurl = urllib.parse.urljoin("https://media.printables.com", imagepath)
local_file = os.path.join(tmpdir.name, os.path.basename(imagepath)) local_file = os.path.join(tmpdir.name, os.path.basename(imagepath))
print("Downloading first image of printable to {}".format(local_file), end="") print("Downloading first image of printable to {}".format(local_file), end="")
with requests.get(imageurl, stream=True) as r: 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:
r.raise_for_status() r.raise_for_status()
with open(local_file, "wb") as f: with open(local_file, "wb") as f:
for chunk in r.iter_content(chunk_size=8192): for chunk in r.iter_content(chunk_size=8192):
f.write(chunk) f.write(chunk)
task.attach(local_file)
print(" done.") print(" done.")
newstory_url= urllib.parse.urljoin(CONFIG["taiga"]["url"], os.path.join("project", CONFIG["taiga"]["project_slug"], "us", str(story.ref))) story.attach(local_file)
print("New story created at: {}".format(newstory_url))
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))

View File

@ -1,2 +1,3 @@
python-taiga python-taiga
requests requests
bottle