You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
12 KiB
Python

from urllib.parse import unquote
from fastapi import FastAPI, HTTPException
import uvicorn
from typing import List, Tuple
from database.database import Database
from database.database import DBPresence, DBArt2Presence
from database.models import Art, ArtnoID, Presence, ArtistNoId, TagnoID, TagCategory, TagCategorynoID
app = FastAPI()
db = Database()
@app.get("/artnet/metadata/art")
async def art(id: int = None, hash: str = None, tag_id: int = None):
hash = unquote(hash) if hash is not None else None
print(f"Received GET on /artnet/metadata/art (id={id}, hash={hash}, tag_id={tag_id})")
result = None
if id is not None:
result = db.get_art_by_id(id)
elif hash is not None:
result = db.get_art_by_hash(hash)
elif tag_id is not None:
result = db.get_tag_art(tag_id)
if id is None and hash is None and tag_id is None: # TODO fix against listing enormous amounts of art (because "all" could be large)
result = db.get_art_list()
if result is not None:
return result
raise HTTPException(status_code=404, detail="Art was not found!")
@app.post("/artnet/metadata/art")
async def art(art: ArtnoID, id: int = None):
print(f"Received POST on /artnet/metadata/art (id={id}) body: art=({art})")
if id is None: # create new art entry
if art.presences is None: # tried to create art without any presence
raise HTTPException(status_code=422, detail="No presences were listed")
try:
new_id = db.create_art_by_model(art).id
return {"id": new_id}
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e))
else: # update existing art entry
if db.get_art_by_id(id) is None:
raise HTTPException(status_code=404, detail="The specified art could not be found!")
updated_art = Art(id=id)
updated_art.hash = art.hash
updated_art.link = art.link
updated_art.title = art.title
updated_art.path = art.path
if art.presences is not None:
updated_art.presences = art.presences
db.update_art_by_model(updated_art)
return True
@app.delete("/artnet/metadata/art")
async def art(id: int, presence_name: str = None, presence_domain: str = None):
presence_name = unquote(presence_name) if presence_name is not None else None
presence_domain = unquote(presence_domain) if presence_domain is not None else None
print(f"Received DELETE on /artnet/metadata/art (id={id}, presence_name={presence_name}, "
f"presence_domain={presence_domain})")
print("All art available is", [a.id for a in db.get_art_list()])
if db.get_art_by_id(id) is None:
raise HTTPException(status_code=404, detail="Art has not been found!")
if id is not None and presence_name is None and presence_domain is None:
db.delete_art_by_id(id)
return
elif id is not None and presence_name is not None and presence_domain is not None:
try:
db.delete_art_presences_by_id(art_id=id, presence_name=presence_name, presence_domain=presence_domain)
except ValueError:
raise HTTPException(status_code=404, detail="The art-presence relation could not be found!")
return
raise HTTPException(status_code=422, detail="Unknown parameter combination!")
@app.get("/artnet/metadata/presence")
async def presence(name: str = None, domain: str = None, artist_id: int = None, art_id: int = None,
art_md5: str = None):
name = unquote(name) if name is not None else None
domain = unquote(domain) if domain is not None else None
art_md5 = unquote(art_md5) if art_md5 is not None else None
print(f"Received GET on /artnet/metadata/presence (name={name}, domain={domain}, artist_id={artist_id}"
f", art_id={art_id}, art_md5={art_md5})")
result = None
if artist_id is not None and name is None and domain is None:
result = db.get_artist_presences(artist_id)
elif art_id is not None and name is None and domain is None:
result = db.get_art_presences_by_id(art_id)
elif art_md5 is not None and name is None and domain is None:
result = db.get_art_presences_by_hash(art_md5)
elif name is not None and domain is not None:
result = db.get_presence(name, domain)
if name is None and domain is None and artist_id is None and art_id is None and art_md5 is None:
result = db.get_presence_list()
#raise HTTPException(status_code=406, detail="You must query with at least one parameter!")
if result is not None:
if isinstance(result, list):
for i in range(len(result)):
if isinstance(result[i], DBPresence):
result[i].name = result[i].name.strip()
result[i].domain = result[i].domain.strip()
elif isinstance(result[i], DBArt2Presence):
result[i].presence_name = result[i].presence_name.strip()
result[i].presence_domain = result[i].presence_domain.strip()
else:
result.name = result.name.strip()
result.domain = result.domain.strip()
return result
raise HTTPException(status_code=404, detail="Presence was not found!")
@app.post("/artnet/metadata/presence")
async def presence(presence: Presence):
print(f"Received POST on /artnet/metadata/presence body: presence={presence}")
curr_presence = db.get_presence(name=presence.name, domain=presence.domain)
r = db.get_artist(presence.artist_id)
if r is None:
raise HTTPException(status_code=406, detail="Invalid Artist ID! Could not find artist.")
if curr_presence is None: # must be new presence
db.create_presence(name=presence.name, domain=presence.domain, artist_id=presence.artist_id, link=presence.link)
else: # editing current presence
db.update_presence(name=curr_presence.name, domain=curr_presence.domain,
artist_id=presence.artist_id, link=presence.link)
@app.delete("/artnet/metadata/presence")
async def presence(name: str, domain: str):
print(f"Received DELETE on /artnet/metadata/presence (name={name}, domain={domain})")
if db.get_presence(name, domain) is None:
raise HTTPException(status_code=404, detail="Presence has not been found!")
db.delete_presence(name, domain)
@app.get("/artnet/metadata/artist")
async def artist(id: int = None, topic_id: int = None, name: str = None):
name = unquote(name) if name is not None else None
print(f"Received GET on /artnet/metadata/artist (id={id}, topic_id={topic_id}, name={name})")
result = None
if id is None and topic_id is None and name is None:
result = db.get_artist_list()
if id is not None:
result = db.get_artist(id)
elif topic_id is not None:
result = db.get_topic_artists(topic_id)
elif name is not None:
result = db.search_artist(name)
if result is not None:
return result
raise HTTPException(status_code=404, detail="Artist was not found!")
@app.post("/artnet/metadata/artist")
async def artist(artist: ArtistNoId, id: int = None):
print(f"Received POST on /artnet/metadata/artist (id={id}) body: artist={artist}")
if id is None: # create new artist
db_artist = db.create_artist(name=artist.name, topics=artist.topics)
return db_artist.id
else:
if db.get_artist(id) is not None:
db.update_artist(artist_id=id, name=artist.name, topics=artist.topics)
else:
raise HTTPException(status_code=404, detail="Tried to edit unknown artist. ID was not found!")
@app.delete("/artnet/metadata/artist")
async def artist(id: int):
print(f"Received DELETE on /artnet/metadata/artist (id={id})")
if db.get_artist(id) is None:
raise HTTPException(status_code=404, detail="Tried to delete unknown artist. ID was not found!")
db.delete_artist(id)
@app.get("/artnet/metadata/topic")
async def topic(name: str = None, id: int = None, artist_id: int = None):
name = unquote(name) if name is not None else None
print(f"Received GET on /artnet/metadata/topic (name={name}, id={id}, artist_id={artist_id})")
if name is None and id is None and artist_id is None:
raise HTTPException(status_code=406)
result = None
if name is not None or id is not None:
if id is not None:
result = db.get_topic_by_id(id)
elif name is not None:
result = db.get_topic_by_name(name)
elif artist_id is not None:
result = db.get_artist_topics(artist_id)
if result is not None:
if isinstance(result, list):
for i in range(len(result)):
result[i].name = result[i].name.strip()
else:
result.name = result.name.strip()
return result
raise HTTPException(status_code=404, detail="Topic was not found!")
@app.get("/artnet/metadata/tag")
async def tag(id: int = None, name: str = None, fuzzy: bool = False, category: int = None):
name = unquote(name) if name is not None else None
print(f"Received GET on /artnet/metadata/tag (name={name}, id={id}, name={category}, fuzzy={fuzzy})")
if id is None and name is None and category is None:
raise HTTPException(status_code=406)
result = None
if fuzzy:
if name is not None:
result = db.search_tag_by_name_fuzzy(name)
if result is not None:
return result
raise HTTPException(status_code=404, detail="No matching tag found!")
else:
if id is not None:
result = db.get_tag_by_id(id)
elif name is not None:
result = db.get_tag_by_name(name)
elif category is not None:
result = db.get_category_tags(category)
if result is not None:
if isinstance(result, list):
for i in range(len(result)):
result[i].name = result[i].name.strip()
else:
result.name = result.name.strip()
return result
raise HTTPException(status_code=404, detail="Tag was not found!")
@app.post("/artnet/metadata/tag")
async def tag(tag: TagnoID, id: int = None):
print(f"Received POST on /artnet/metadata/tag (id={id}) body: tag={tag}")
@app.get("/artnet/metadata/category")
async def category(name: str = None, id: int = None):
name = unquote(name) if name is not None else None
print(f"Received GET on /artnet/metadata/category (name={name}, id={id})")
if name is None and id is None:
result = db.get_category_list()
return result
result = None
if id is not None:
result = db.get_category_by_id(id)
elif name is not None:
result = db.get_category_by_name(name)
if result is not None:
result.name = result.name.strip()
return result
raise HTTPException(status_code=404, detail="Category not found!")
@app.post("/artnet/metadata/category")
async def category(category: TagCategorynoID, id: int = None):
print(f"Received GET on /artnet/metadata/category (id={id}, body: {category})")
if id is None: # create new name
try:
new_id = db.create_category_by_model(category).category_id
return {"id": new_id}
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e))
else:
updated_category = TagCategory(category_id=id, name=category.name)
db.update_category_by_model(updated_category)
return True
@app.delete("/artnet/metadata/category")
def category(id: int):
print(f"Received DELETE on /artnet/metadata/category (id={id})")
try:
db.delete_category_by_id(category_id=id)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)