ShaderToy API : access the biggest library of amazing shaders on the planet

I am working on implimenting the ShaderToy.com API, if you aren’t familiar with ShaderToy.com, go there now, you are in for a treat.

So, the first thing you need to do is get an account there, and in your account you make an API key.
You do this in your profile page, I will gather more info if needed. There is info on the API if you hit the link at the very bottom of the page labeled “API”

Once you have your key, you can add it in the code I am working on, and I hope to polish this up and add full parsing along with my ShaderALL / GLSL library I have been working on and get a proper installer going on my git as soon as I can.

for now here is my class that will download a list of shaders, and parse the JSON of a shader:
main tab for testing:

function setup()
    ShaderToy:init()
    ShaderToy.key = '' -- INSERT YOUR API KEY
    ShaderToy:getList()
    ShaderToy:getShader('MdX3Rr') 
end

ShaderToy tab for class:

ShaderToy = class()

function ShaderToy:init()
    self.decoded = {}
    self.list = {}
    self.key = ''
end

function ShaderToy:getList(search, key)
    http.request('https://www.shadertoy.com/api/v1/shaders?key='..self.key,
    function(data, status, headers)
        ShaderToy:gotList(data, status, headers)
    end )
end

function ShaderToy:gotList(data, status, headers)
    if data ~= nil then
        print(data)
        saveText("Documents:ShaderToyListFull",data)
        local list = json.decode(data)
        tablePrint(list)
    end
end

function ShaderToy:getShader(sss, key)
    http.request( "https://www.shadertoy.com/api/v1/shaders/"..sss.."?key="..self.key,
    function(data, status, headers) 
        ShaderToy:decoder(data, status, headers) 
    end )
end

function ShaderToy:decoder(data, status, headers)
    if data ~= nil then 
        local decoded = json.decode(data) 
        tablePrint(decoded)
        
    elseif data == nil then
        return false
    end
end

function tablePrint(t)
    if t ~= nil then
        for k,v in pairs(t) do
            if type(v) == 'table' then
                tablePrint(v)
            else
                print(k..':'..v)
            end
        end
    end
end

Worth noting, tablePrint(list) takes a long time, you may want to comment it out.

actually it may be the json.decode(list) as well.

@AxiomCrux You don’t need tablePrint calling itself. Try this routine to print the names. The json.decode routine isn’t slowing thing down, it’s the print(k…‘:’…v) that’s doing it. You’re trying to print 5838 names one line at a time. The output window wasn’t meant to print a lot of lines at a time.

function tablePrint(t)
    local tab={}
    if t ~= nil then
        for k,v in pairs(t) do
            if type(v) == 'table' then
                for a,b in pairs(v) do
                    table.insert(tab,b)
                end
            end
        end
    end    
    print(table.concat(tab,",")) 
end

@dave1707 it appears that the text editor in the document browser also gets absurdly slow when I try to select parts of the text.

Would you be willing to explain a little of why this way of printing the table is better? It seems like you are creating another table out of something that’s already a table? I know you’ve been doing this a lot longer than I have so I want to learn and improve my skill and understanding, and I am not currently clear just by looking at the code.

It makes a single (very long) string and prints it as a single (very large) line rather than printing hundreds or thousands of smaller lines.

@AxiomCrux I don’t think any editor used by Codea is meant to work with large amounts of text. That’s why large projects have a lot of tabs, that’s to keep the amount of text in the editor small. I don’t know the exact workings of the output window for printing, but I think it might work the same way strings work. Each time you do a print, the text is added to the text that’s already there. It has to create another print area, copy the existing text and add the new text to it. When you were doing your print, you’re printing 5838 names. That means the print routine has to create a new print area, copy the existing text to it, and then copy the new text to the end 5838 times. Each time the amount of text gets larger and larger. By creating another table with just the information that I want to print, the print(table.concat) routine just creates 1 large string that get sent to the print area once instead of 5838 times. As for your print routine calling itself, that would work great when you have a lot of tables within tables. In this case, it’s only 1 table within a table. Just in case you didn’t notice, I hid your ShaderToy key that you posted in the other discussion. I didn’t think you wanted everyone using your key.

Oh @dave1707, you maybe didn’t see the shader json that the tablePrint is meant to parse. There are several nested structures. The list is not what I designed it for, the shader is.

Where did I post my key??!! I did not mean to do that and I thought I had removed it??!!

@dave1707 I am super confused, what is the thread you are mentioning, I can’t seem to find it and I really thought I had removed it entirely beforehand. I also don’t remember posting that code anywhere else, so maybe some kind of accident that I want to look into what I might have done.

RE: the list / print, it seems like everything works just fine and fast if I print one by one to the screen rather than the console. Now its on to parsing the shaders for display! :smiley:

Also, to reitterate, the printTable function I did was meant to print nested tables parsed from the json.decode of the actual shader, but your version is better for printing the list. I am wondering if there is a good way to merge the two, to make the best optimized merger for proposing in my other thread of adding a built in metamethod for printing tables.

https://codea.io/talk/discussion/8588/print-table-example-add-to-api-metamethods#latest

Is there a way to delete or edit my own forum reply posts?

@AxiomCrux If you want to delete or re-edit your own posts, tap the gear icon at the upper right of your post. It gives you some options.

@dave1707 that only seems to let me edit the original top level post, and not my replies. The replys are what I am wondering about.

I signed in as a non MOD and posted a reply. There was a gear icon at the top right of my post. When I tapped on it, there was an EDIT option. Apparently you can only edit your posts and not delete them. That means you can completely backspace over your post and leave it blank, or change something you don’t like. I guess a MOD can only delete posts.

Is it possible that that doesn’t show up on the browser I am using ? Or that it is only available to moderators? I’ve got the one on the main post but nothing on any of my replies

I’m using the current Safari on iOS with an iPad Pro

I’m not sure what’s up with the iPad Pro, but it doesn’t act like a normal iPad. To get the gear to show, tap on your name on the post you want the gear to show on.

hahahaha good one! what is it with apple and making life hard for devs. :P`