shish/shimmie2

The danbooru_api plugin's tagging is broken (maybe?)

Closed this issue · 5 comments

Server Software

about:
title: "Shimmie"
theme: "default"
url: "http://localhost:8080/index.php?q="

versions:
shimmie: "2.12.0-alpha-20240707-8a8d78a"
schema: 21
php: "8.2.20"
db: "sqlite 3.40.1"
os: "Linux 2e2071790582 6.9.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 28 Jun 2024 04:32:50 +0000 x86_64"
server: "Unit/1.32.1"

extensions:
core: ["admin","alias_editor","bbcode","comment","download","et","ext_manager","four_oh_four","handle_pixel","help_pages","image","index","media","mime","post_lock","post_owner","post_source","post_tags","replace_file","setup","static_files","system","tag_list","upgrade","upload","user","user_config","view"]
extra: ["bulk_actions","bulk_import_export","danbooru_api","downtime"]
handled_mimes: ["image/jpeg","image/gif","image/png","image/webp","application/zip"]

stats:
images: 2
comments: 0
users: 2

media:
memory_limit: "8.0MB"
disk_use: "11GB"
disk_total: "31GB"

thumbnails:
engine: "convert"
quality: 75
width: 192
height: 192
scaling: 100
mime: "image/jpeg"

What steps trigger this bug

  1. Enable the danbooru_api plugin
  2. Write my own code to use the API submit a new post (I admit I could be doing this wrong, but I'm not convinced) with basic python requests

What did you expect to happen?

Data from the form-data value "tags" should be properly parsed and end up in the "Tags" field on the post.

What actually happened?

  1. The post shows up in the webui
  2. The tags on the new post are always "Array"
  3. Log: 2024/07/08 01:25:37 [notice] 132#132 [unit] #239: php message: PHP Warning: Array to string conversion in /app/ext/post_tags/main.php on line 135

Discussion

I admit maybe I am doing this wrong, but I really don't think so. Here's a code snippet:

def main():
    # Get the file data
    with open(filepath, 'rb') as hndl:
        filedata = hndl.read()
    
    # Get our data in order
    files = {
        'file': (filename, filedata)
    }
    data = {
        "tags": "tag1 tag2"
    }

    # Handle the request
    rqst = requests.Request("POST", "http://10.0.0.193:8080/api/danbooru/add_post", files=files, data=data, cookies=cookies)
    prep = rqst.prepare()
    prettyRequest(prep)
    s = requests.Session()
    resp = s.send(prep, proxies=proxy) # Proxy is only here to allow debugging via zaproxy

I've actually "fixed" this (assuming it's broken and I'm not just Doing It Wrong) by changing

$posttags = Tag::explode(isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']);

I changed it to: $posttags = isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']; since there's actually call to Tag::explode() at

$tags = Tag::explode("$common_tags $my_tags");
(the line which was generating the Warning). My understanding is that explode() always produces an array from a string, so passing the output of explode() to another explode() is always going to result in a cast to string here, but PHP isn't exactly my forte.

I considered submitting a PR, but I don't actually know if this is broken or if my script is broken, and I can't get the docker image to compile without modification locally (I get an error in Smoke Test about the get-page command not existing, which I think may have been updated to Get:page) so I can't do full testing; I modified the docker container live to test this.

Thank you, I have the same problem. And I fix it followed by your method.

Sorry for the delay - that fix does look correct, and I am very confused as to why the current code isn't throwing more explicit errors o_O

Specifically phpstan recognises that $posttags is an array, and it recognises that DataUploadEvent wants tags to be a string... and it doesn't think anything is wrong there 🙃

So it looks like if any part of the type signature is mixed, phpstan will ignore the whole thing - and because source is being set to $_REQUEST["source"] (which has unknown type, treated as mixed), the fact that tags is an array when it should be a string is ignored -_-

So this extension was designed to be compatible with danbooru 1.0 in 2008, and it's kind of inherently a mess - I'm not familiar with the latest clients of this API -- I wonder if either of you can recommend any that I can test with? In particular if these API clients support the latest danbooru API as described on https://danbooru.donmai.us/wiki_pages/help:api - that looks much more pleasant to support ^^;;

@shish
Apologies, but I don't have recommendations for the right clients to use-- I couldn't find docu on the API in question reliably, and I haven't used other boorus, so I admit I just reverse engineered this plugin and slapped some stuff together in python. Possibly that's why I ran into this bug...

Regardless, thank you for your response! Have a good one.