Add webserver capabilities
This enables the script to be either used interactively or from outside services (e.g. userscripts).
This commit is contained in:
parent
6976f919c5
commit
55c15da039
|
@ -10,3 +10,6 @@ userstory_custom_field_name = Platform link
|
|||
|
||||
initial_task_status = New
|
||||
|
||||
[webserver]
|
||||
host = localhost
|
||||
port = 9080
|
||||
|
|
144
importer.py
144
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))
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
python-taiga
|
||||
requests
|
||||
bottle
|
||||
|
|
Loading…
Reference in a new issue