Nasicus / d2-holy-grail

https://d2-holy-grail.herokuapp.com
61 stars 28 forks source link

Creating API for d2-holy-grail #53

Closed oskros closed 4 years ago

oskros commented 4 years ago

I am writing an automatic run counter https://github.com/oskros/MF_counter_releases which has the ability to log found drops. I would like to be able to synchronize this app with your holy-grail user.

For this I would love an API with 2 features 1) Pass username, password, item name and boolean to check/uncheck whether a given item is found 2) Pass username to return all found items for the given user

oskros commented 4 years ago

With help of Nasicus I have connected to the appropriate APIs

squeek502 commented 4 years ago

For the sake of completeness / for future reference:

The format of the JSON will be something like (simplified, the actual JSON has way more elements obviously):

{
   "address":"squeek502",
   "data":{
      "uniques":{
         "armor":{
            "chest":{
               "normal":{
                  "Greyform":{
                     "wasFound":true,
                     "note":"Locations:\n_LOD_SharedStashSave.sss page 154"
                  },
                }
              }
            }
          }
        }
      },
      "sets":{
         "Angelic Raiment":{
            "Angelic Wings":{
               "wasFound":5,
               "note":"Locations:\n_LOD_SharedStashSave.sss page 213\n_LOD_SharedStashSave.sss page 213\n_LOD_SharedStashSave.sss page 213\n_LOD_SharedStashSave.sss page 213\n_LOD_SharedStashSave.sss page 213"
            },
          }
        }
      }
   },
   "runewordData":{
      "Ancient's Pledge":{
         "wasFound":3,
         "note":"Locations:\n_LOD_SharedStashSave.sss page 23\n_LOD_SharedStashSave.sss page 23\n_LOD_SharedStashSave.sss page 23"
      },
   },
   "settings":{
      "useItemCountMode":true
   },
   "token":"2020-08-17T21:32:28.478Z",
   "version":"1.1.0"
}
oskros commented 4 years ago

Thanks for that! What is this "Locations" part you have included in your example? Is that for something you are using the API for? Because I don't see any use for it on the UI

squeek502 commented 4 years ago

That's something I'm using the API for via https://github.com/squeek502/d2grailcheck (still unfinished). It uses the "note" field for each item to note which file/page an item is on. It's visible when you click on an item in the d2-holy-grail UI (example).

Other item fields that can be used but don't show up in the GET if they aren't set:

oskros commented 4 years ago

how do you handle the fact that GET returns no data if the profile is new? The structure of the GET command is only properly created after at least one item has been checked through the web UI

squeek502 commented 4 years ago

Currently, I actually embed the JSON instead of retrieving it from GET, since my tool will overwrite the status of every item anyway. But that's potentially brittle if the format of the JSON changes, and I am planning on using a GET request instead. Not sure what the best solution for an empty GET would be, though. Might be worth adding something to the API for that case (maybe a query parameter to the GET endpoint that forces returning empty keys?).

Nasicus commented 4 years ago

If I remember correctly in the API I do not even know about the structure / schema of the JSON (you could send whatever JSON yo uwant to the server). So it's not really possible to add an API for that, there would be need for more changes.

Honestly when I started doing this I never expected that anybody apart from me is even going to use the site and now some people (like you) even use my API ;D

So sorry for having such a "bad" API ;)

btw:

As you can see here: https://d2-holy-grail.herokuapp.com/stats

the site is still regulary used Grail Updates today basically means that a total of 166 different users did a "save" call somewhen in the last 24 hours.

oskros commented 4 years ago

Haha its just great that so many people have begun using the page, it's really great to see such a thriving grail community 👍

However, wouldn't you be able to impose the basic structure on the APIs without ruining backwards compatibility? It doesn't sound like a huge reformatting would be required.

Just as example I tried embedding the JSON in my own code to create a profile from scratch. However, I noticed that the ordering of the elements on the website is actually not retained if you do this.

See example: http://d2-holy-grail.herokuapp.com/testaddress2/holy/unique-armor Here, the order is completely different, since by default the json keys are alphabetically sorted when calling GET from Python

squeek502 commented 4 years ago

Does your JSON parser preserve order when decoding/encoding? That's something I had to make sure my JSON parser was doing for it to work right.

Nasicus commented 4 years ago

@oskros not saying it would be hard to have the "scheme" on the server, but if you or anyone else really needs it, it still would need to be implemented first ;) keeping the exact same json structure should be easy though.