|
|
|
@ -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"]) |
|
|
|
|
|
|
|
|
|
# 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"]))) |
|
|
|
|
@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 |
|
|
|
|
|
|
|
|
|
# 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 generate_from_cmdline(): |
|
|
|
|
link = get_url_interactively() |
|
|
|
|
us_url = generate_taiga_userstory(link) |
|
|
|
|
return us_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 get_url_interactively(): |
|
|
|
|
url = input("Please paste link: ") |
|
|
|
|
return url |
|
|
|
|
|
|
|
|
|
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"]) |
|
|
|
|
|
|
|
|
|
tmpdir = tempfile.TemporaryDirectory() #workdir for downloads |
|
|
|
|
# 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"]))) |
|
|
|
|
|
|
|
|
|
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.") |
|
|
|
|
# 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) |
|
|
|
|
|
|
|
|
|
story.attach(local_file) |
|
|
|
|
# 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"] |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
tmpdir = tempfile.TemporaryDirectory() #workdir for downloads |
|
|
|
|
|
|
|
|
|
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)) |
|
|
|
|