diff --git a/shard.yml b/shard.yml index d7c1f00..3ea9557 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: ivr-crystal -version: 0.2.0 +version: 0.2.2 targets: ivr-api-crystal: diff --git a/src/config.cr b/src/config.cr index 0407826..f768f84 100644 --- a/src/config.cr +++ b/src/config.cr @@ -18,6 +18,6 @@ class Config config_file = "config/config.yml" config_yaml = File.read(config_file) config = Config.from_yaml(config_yaml) - return config + config end end diff --git a/src/datahandlers/twitch.cr b/src/datahandlers/twitch.cr index 77465d5..83b65b3 100644 --- a/src/datahandlers/twitch.cr +++ b/src/datahandlers/twitch.cr @@ -19,39 +19,26 @@ module TwAPI::Datahandlers::Twitch env.params.query["skipCache"]? end - def isBannedLogin(gql) - if gql["userResultByLogin"]["reason"]? - return true + def isBanned(gql, mode) + if gql["userResultBy#{mode}"]["reason"]? + true else - return false + false end end - def isBannedId(gql) - if gql["userResultByID"]["reason"]? - return true - else - return false - end - end + def user(env) + mode = env.params.query.has_key?("id") ? "ID" : "Login" - def banReason(gql) - if gql["userResultByLogin"] == nil - return false - end - return true - end - - def userLogin(env) if skipCache != "true" - if (json = Utils::Redis.retrieveFromCache("user-login_#{env.params.query["login"].try &.split(',').to_s}")) + if json = Utils::Redis.retrieveFromCache("user_#{env.params.query["#{mode.downcase}"].try &.split(',')}") json = JSON.parse(json) return json.to_json end end begin - gql = GqlAPI.getUserByLogin(env.params.query) + gql = TwitchAPI::GQL.getUser(env.params.query["#{mode.downcase}"], mode) rescue ex twitchError end @@ -61,98 +48,17 @@ module TwAPI::Datahandlers::Twitch gql.each do |gql| gql = gql["data"] - if (gql["user"] == nil) - # v3 could add some feedback error message instead of an empty array. - nil # Do not add anything to the array. Just like api.ivr.fi does. - else - panels = gql["user"]["panels"] - banned = isBannedLogin(gql) - - json.object do - json.field "banned", banned - if banned == true - json.field "banReason", gql["userResultByLogin"]["reason"] - end - json.field "displayName", gql["user"]["displayName"] - json.field "login", gql["user"]["login"] - json.field "id", gql["user"]["id"] - json.field "bio", gql["user"]["description"] - json.field "follows", nil - json.field "followers", gql["user"]["followers"]["totalCount"] - json.field "profileViewCount", nil # Always null - json.field "panelCount", panels.size - json.field "chatColor", gql["user"]["chatColor"] - json.field "logo", gql["user"]["profileImageURL"] - json.field "banner", gql["user"]["bannerImageURL"] - json.field "verifiedBot", nil # Deprecated by twitch - json.field "createdAt", gql["user"]["createdAt"] - json.field "updatedAt", gql["user"]["updatedAt"] - json.field "deletedAt", gql["user"]["deletedAt"] - json.field "emotePrefix", gql["user"]["emoticonPrefix"]["name"] - if gql["user"]["primaryTeam"] != nil - json.field "team", gql["user"]["primaryTeam"]["displayName"] - else - json.field "team", nil - end - if gql["user"]["primaryTeam"] != nil - json.field "contract", gql["user"]["programAgreement"]["type"] - else - json.field "contract", nil - end - json.field "roles", gql["user"]["roles"] - json.field "badges", gql["user"]["displayBadges"] - json.field "chatterCount", gql["user"]["channel"]["chatters"]["count"] - json.field "chatSettings", gql["user"]["chatSettings"] - json.field "stream", gql["user"]["stream"] - json.field "lastBroadcast", gql["user"]["lastBroadcast"] - json.field "panels", panels - end - end - end - end - end - - begin - Utils::Redis.saveJson("user-login_#{env.params.query["login"].try &.split(',')}", json_data) - rescue ex - puts ex.message - end - - return json_data - end - - def userId(env) - if skipCache != "true" - if (json = Utils::Redis.retrieveFromCache("user-id_#{env.params.query["id"].try &.split(',').to_s}")) - json = JSON.parse(json) - return json.to_json - end - end - - begin - gql = GqlAPI.getUserById(env.params.query) - rescue ex - twitchError - end - - json_data = JSON.build do |json| - json.array do - gql.each do |gql| - pp gql = gql["data"] - pp typeof(gql) - - if (gql["user"] == nil) + if gql["user"] == nil # v3 could add some feedback error message instead of an empty array. # Do not add anything to the array. Just like api.ivr.fi does. nil else - panels = gql["user"]["panels"] - banned = isBannedId(gql) + banned = isBanned(gql, mode) json.object do json.field "banned", banned if banned == true - json.field "banReason", gql["userResultByID"]["reason"] + json.field "banReason", gql["userResultBy#{mode}"]["reason"] end json.field "displayName", gql["user"]["displayName"] json.field "login", gql["user"]["login"] @@ -161,7 +67,7 @@ module TwAPI::Datahandlers::Twitch json.field "follows", nil json.field "followers", gql["user"]["followers"]["totalCount"] json.field "profileViewCount", nil # Always null - json.field "panelCount", panels.size + json.field "panelCount", gql["user"]["panels"].size json.field "chatColor", gql["user"]["chatColor"] json.field "logo", gql["user"]["profileImageURL"] json.field "banner", gql["user"]["bannerImageURL"] @@ -170,18 +76,12 @@ module TwAPI::Datahandlers::Twitch json.field "updatedAt", gql["user"]["updatedAt"] json.field "deletedAt", gql["user"]["deletedAt"] json.field "emotePrefix", gql["user"]["emoticonPrefix"]["name"] - - # failed attempts - # pp "1: #{gql["user"]["primaryTeam"]? || nil}" - # pp "2: #{gql["user"].try &.["primaryTeam"]?.try &.["displayName"]? || nil}" - # json.field "team", gql["user"]["primaryTeam"].try &.["displayName"]? - # if gql["user"]["primaryTeam"] != nil json.field "team", gql["user"]["primaryTeam"]["displayName"] else json.field "team", nil end - if gql["user"]["primaryTeam"] != nil + if gql["user"]["programAgreement"] != nil json.field "contract", gql["user"]["programAgreement"]["type"] else json.field "contract", nil @@ -192,7 +92,7 @@ module TwAPI::Datahandlers::Twitch json.field "chatSettings", gql["user"]["chatSettings"] json.field "stream", gql["user"]["stream"] json.field "lastBroadcast", gql["user"]["lastBroadcast"] - json.field "panels", panels + json.field "panels", gql["user"]["panels"] end end end @@ -200,12 +100,12 @@ module TwAPI::Datahandlers::Twitch end begin - Utils::Redis.saveJson("user-id_#{env.params.query["id"].try &.split(',')}", json_data) + Utils::Redis.saveJson("user_#{env.params.query["#{mode.downcase}"].try &.split(',')}", json_data) rescue ex puts ex.message end - return json_data + json_data end def modvip(env) @@ -219,13 +119,13 @@ module TwAPI::Datahandlers::Twitch end begin - gql = GqlAPI.getModsVips(channel) + gql = TwitchAPI::GQL.getModsVips(channel) gql = gql["data"]["user"] rescue ex twitchError end - if (gql == nil) + if gql == nil error("Specified channel does no exist") end @@ -281,7 +181,7 @@ module TwAPI::Datahandlers::Twitch end Utils::Redis.saveJson("modvip-#{channel}", json_data) - return json_data + json_data end # TODO: Add error message if query doesn't exist at all @@ -297,14 +197,14 @@ module TwAPI::Datahandlers::Twitch end begin - gql = GqlAPI.getFounders(login) + gql = TwitchAPI::GQL.getFounders(login) gql = gql["data"]["user"] rescue ex twitchError end # TODO: use begin rescue for this too! - if (gql == nil) + if gql == nil error("Specified channel does no exist") end @@ -341,7 +241,7 @@ module TwAPI::Datahandlers::Twitch end Utils::Redis.saveJson("founders-#{login}", json_data) - return json_data + json_data end def clip(env) @@ -355,14 +255,14 @@ module TwAPI::Datahandlers::Twitch end begin - gql = GqlAPI.getClips(slug) + gql = TwitchAPI::GQL.getClips(slug) gql = gql["data"]["clip"] rescue ex twitchError end # TODO: use begin rescue for this too! (again) - if (gql == nil) + if gql == nil error("Slug does not exist") end @@ -434,7 +334,7 @@ module TwAPI::Datahandlers::Twitch end Utils::Redis.saveJson("clip-#{slug}", json_data) - return json_data + json_data end def subage(env) @@ -449,10 +349,10 @@ module TwAPI::Datahandlers::Twitch end begin - gql = GqlAPI.getSubage(user, channel) + gql = TwitchAPI::GQL.getSubage(user, channel) gql = gql["data"] rescue ex - if (gql == nil) + if gql == nil error("Channel does not exist") end twitchError @@ -508,7 +408,7 @@ module TwAPI::Datahandlers::Twitch end end end - if (gql["info"]["relationship"]["meta"] == nil) + if gql["info"]["relationship"]["meta"] == nil json.field "meta", nil else json.field "meta" do @@ -525,7 +425,7 @@ module TwAPI::Datahandlers::Twitch end Utils::Redis.saveJson("subage-user_#{user}_channel_#{channel}", json_data) - return json_data + json_data end def emotes(env) @@ -539,7 +439,7 @@ module TwAPI::Datahandlers::Twitch end begin - gql = GqlAPI.getEmotes(emoteName) + gql = TwitchAPI::GQL.getEmotes(emoteName) gql = gql["data"]["emote"] if gql == nil raise "Emote does not exist" @@ -571,11 +471,11 @@ module TwAPI::Datahandlers::Twitch end Utils::Redis.saveJson("emotes-#{emoteName}", json_data) - return json_data + json_data end def channelEmotes(env) - gql = GqlAPI.getChannelEmotes(env.params.query["channel"]) # TODO: Add support for IDs an not just the channel name + gql = TwitchAPI::GQL.getChannelEmotes(env.params.query["channel"]) # TODO: Add support for IDs an not just the channel name json_data = JSON.build do |json| json.object do diff --git a/src/routes/kick.cr b/src/routes/kick.cr new file mode 100644 index 0000000..44ce84c --- /dev/null +++ b/src/routes/kick.cr @@ -0,0 +1,2 @@ +module TwAPI::Routes::Kick +end diff --git a/src/routes/routes.cr b/src/routes/routes.cr index f416f10..fff8faa 100644 --- a/src/routes/routes.cr +++ b/src/routes/routes.cr @@ -30,21 +30,10 @@ module TwAPI::Routes def register_all_twitch get "/v2/twitch/user", TwAPI::Routes::Twitch, :user - - get "/v2/twitch/modvip/", TwAPI::Routes::Twitch, :modvip get "/v2/twitch/modvip/:channel", TwAPI::Routes::Twitch, :modvip - - get "/v2/twitch/founders", TwAPI::Routes::Twitch, :founders get "/v2/twitch/founders/:login", TwAPI::Routes::Twitch, :founders - - get "/v2/twitch/clip", TwAPI::Routes::Twitch, :clip get "/v2/twitch/clip/:slug", TwAPI::Routes::Twitch, :clip - - get "/v2/twitch/subage", TwAPI::Routes::Twitch, :subage get "/v2/twitch/subage/:user/:channel", TwAPI::Routes::Twitch, :subage - - get "/v2/twitch/emotes", TwAPI::Routes::Twitch, :emotes get "/v2/twitch/emotes/:emote", TwAPI::Routes::Twitch, :emotes - # get "/v2/twitch/emotes/channel", TwAPI::Routes::Twitch, :channelEmotes end end diff --git a/src/routes/twitch.cr b/src/routes/twitch.cr index 9552be5..3d29ed8 100644 --- a/src/routes/twitch.cr +++ b/src/routes/twitch.cr @@ -12,19 +12,7 @@ module TwAPI::Routes::Twitch end def user(env) - if env.params.query.has_key?("login") - begin - handleData(userLogin) - rescue ex - puts ex.message - end - else - begin - handleData(userId) - rescue ex - puts ex.message - end - end + handleData(user) end def modvip(env) @@ -55,6 +43,6 @@ end # err = "[]" # return err.to_json # else -# gql = GqlAPI.getChannelEmotes(env.params.query) +# gql = TwitchAPI::GQL.getChannelEmotes(env.params.query) # json_data = JSON.build do |json| # end diff --git a/src/twitchapi/gqlapi.cr b/src/twitchapi/gqlapi.cr index 9fe699e..7f2b86b 100644 --- a/src/twitchapi/gqlapi.cr +++ b/src/twitchapi/gqlapi.cr @@ -1,46 +1,19 @@ -module TwAPI::GqlAPI +module TwAPI::TwitchAPI::GQL extend self - def userResultBy(params) - if params.has_key?("id") - return %(userResultByID(id: "#{params["id"]}")) - else - return %(userResultByLogin(login: "#{params["login"]}")) - end - end - - def targetUser(params) - if params.has_key?("id") - return %(targetUserID: "#{params["id"]}" ) - else - return %(targetUserLogin: "#{params["login"]}") - end - end - - def loginOrID(params) - if params.has_key?("id") - return %(id: "#{params["id"]}") - else - return %(login: "#{params["login"]}") - end - end - - def getUserByLogin(params) - logins = params["login"].try &.split(',') + def getUser(params, mode) + identifiers = params.try &.split(',') channel = Channel(JSON::Any).new responses = [] of JSON::Any queries = [] of String - logins.each do |login| + identifiers.each do |identifier| query = %( query { - userResultByLogin(login: "#{login}") { - ... on UserDoesNotExist { - key - reason - } - } - user(login: "#{login}" lookupType: ALL) { + userResultBy#{mode}(#{mode.downcase}: "#{identifier}") { + ... on UserDoesNotExist { key reason } + ... on UserError { key } } + user(#{mode.downcase}: "#{identifier}" lookupType: ALL) { id language login @@ -54,16 +27,9 @@ module TwAPI::GqlAPI updatedAt deletedAt chatColor - emoticonPrefix { - name - } - panels(hideExtensions: false) { - id - type - } - followers { - totalCount - } + emoticonPrefix { name } + panels(hideExtensions: false) { id type } + followers { totalCount } roles { isStaff isAffiliate @@ -112,12 +78,8 @@ module TwAPI::GqlAPI channel { chatters { count - moderators { - login - } - vips { - login - } + moderators { login } + vips { login } } } } @@ -137,122 +99,7 @@ module TwAPI::GqlAPI responses << channel.receive end - return responses - end - - def getUserById(params) - ids = params["id"].try &.split(',') - channel = Channel(JSON::Any).new - responses = [] of JSON::Any - queries = [] of String - - ids.each do |id| - query = %( - query { - userResultByID(id: "#{id}") { - ... on UserDoesNotExist { - key - reason - } - } - user(id: "#{id}" lookupType: ALL) { - id - language - login - displayName - programAgreement { type } - primaryTeam { displayName name } - description - bannerImageURL - profileImageURL(width: 600) - createdAt - updatedAt - deletedAt - chatColor - emoticonPrefix { - name - } - panels(hideExtensions: false) { - id - type - } - followers { - totalCount - } - roles { - isStaff - isAffiliate - isPartner - isExtensionsDeveloper - } - displayBadges { - setID - title - description - version - } - chatSettings { - autoModLevel - blockLinks - chatDelayMs - followersOnlyDurationMinutes - isBroadcasterLanguageModeEnabled - isEmoteOnlyModeEnabled - isFastSubsModeEnabled - isOptedOutOfGlobalBannedWordsList - isSubscribersOnlyModeEnabled - isUniqueChatModeEnabled - requireVerifiedAccount - rules - slowModeDurationSeconds - } - stream { - averageFPS - bitrate - codec - createdAt - width - height - id - viewersCount - type - game{displayName} - } - lastBroadcast { - game{displayName} - id - startedAt - title - } - channel { - chatters { - count - moderators { - login - } - vips { - login - } - } - } - } - } - ) - queries << query - end - - queries.each do |query| - spawn do - result = JSON.parse(req(query)) - channel.send(result) - end - end - - queries.each do - responses << channel.receive - end - - return responses + responses end def getModsVips(params) @@ -283,7 +130,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getFounders(params) @@ -308,7 +155,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getClips(params) @@ -348,11 +195,11 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getSubage(user, channel) - channelId = HelixAPI.getId(channel) + channelId = TwitchAPI::Helix.getId(channel) query = %( query { userData: userResultByLogin (login: "#{user}") { @@ -401,7 +248,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getEmotes(emote) @@ -432,7 +279,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getChannelEmotes(channel) @@ -466,7 +313,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getEmotes(emote) @@ -497,7 +344,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def getChannelBadges(channel) @@ -524,7 +371,7 @@ module TwAPI::GqlAPI } } ) - return JSON.parse(req(query)) + JSON.parse(req(query)) end def req(query) @@ -535,12 +382,12 @@ module TwAPI::GqlAPI "Client-Id" => "#{CONFIG.gqlClientID}", } data = {"query" => query} - response = HTTP::Client.post(CONFIG.gqlEndpoint.to_s, headers: headers, body: data.to_json) + response = HTTP::Client.post("#{CONFIG.gqlEndpoint}", headers: headers, body: data.to_json) if response.success? - return (response.body) + (response.body) else - raise "GQL Twitch API returned #{response.status_code}: #{response.body.to_s}" + raise "GQL Twitch API returned #{response.status_code}: #{response.body}" end end end diff --git a/src/twitchapi/helixapi.cr b/src/twitchapi/helixapi.cr index 1ebfcab..205a592 100644 --- a/src/twitchapi/helixapi.cr +++ b/src/twitchapi/helixapi.cr @@ -1,9 +1,9 @@ -module HelixAPI +module TwAPI::TwitchAPI::Helix extend self def getId(login) - request = "#{CONFIG.apiEndpoint.to_s}/users?login=#{login}" - return JSON.parse(req(request))["data"][0]["id"] + request = "#{CONFIG.apiEndpoint}/users?login=#{login}" + JSON.parse(req(request))["data"][0]["id"] end def req(request) @@ -15,9 +15,9 @@ module HelixAPI response = HTTP::Client.get(request, headers: headers) if response.success? - return (response.body) + (response.body) else - raise "Helix Twitch API returned #{response.status_code}: #{response.body.to_s}" + raise "Helix Twitch API returned #{response.status_code}: #{response.body}" end end end diff --git a/src/utils/redis.cr b/src/utils/redis.cr index 6f0c57b..4852555 100644 --- a/src/utils/redis.cr +++ b/src/utils/redis.cr @@ -2,7 +2,7 @@ module TwAPI::Utils::Redis extend self def getExpireTime(key) - return REDIS_DB.ttl(key) + REDIS_DB.ttl(key) end def retrieveFromCache(keyName)