Added mod a vips handling

This commit is contained in:
Fijxu 2024-05-21 23:47:49 -04:00
parent ec3df79f6e
commit 6d82b13e09
Signed by: Fijxu
GPG key ID: 32C1DDF333EDA6A4
5 changed files with 280 additions and 265 deletions

View file

@ -1,156 +0,0 @@
require "json"
require "../twitchapi/*"
# def fetchGQL(id : String) : JSON::Any
# GqlAPI.query(id)
# end
# def fetchGQLchannel(id : String) : JSON::Any
# GqlAPI.channel(id)
# end
# def fetchGQLbanned(id : String) : JSON::Any
# GqlAPI.isBanned(id)
# end
module Users
def self.checkBanned(gql)
# puts "checkBanned: #{gql}"
# puts (typeof(gql))
# if gql["userResultByLogin"]
# return false
# if gql["userResultByLogin"]["result"]?
# return true
# else
# return false
# end
# elsif gql["userResultByID"]?
# return false
# if gql["userResultByID"]["reason"]?
# return true
# else
# return false
# end
# else
# return true
# end
# if gql["userResultByLogin"]["reason"]?
# return true
# elsif gql["userResultByID"]["reason"]?
# return true
# else
# return false
# end
# return false
if GqlAPI.urb.includes? "login"
if gql["userResultByLogin"]["reason"]?
return gql["userResultByLogin"]["reason"]
else
return nil
end
elsif GqlAPI.urb.includes? "id"
if gql["userResultByID"]["reason"]?
return gql["userResultByID"]["reason"]
else
return nil
end
end
end
def self.parseData(params)
# helixUsers = JSON.parse(HelixAPI.users(params))
# begin
# login = helixUsers["data"][0]["login"]
# id = helixUsers["data"][0]["id"]
# rescue
# login = nil
# id = nil
# end
# if login.nil? && params.has_key?("login")
# login = params["login"]
# elsif id.nil? && params.has_key?("id")
# id = params["id"]
# end
# gqlUser = GqlAPI.user(id.to_s)
# gqlChannel = GqlAPI.channel(id.to_s)
# a = Channel(JSON::Any).new
# spawn do
# a.send fetchGQL(id.to_s)
# end
login = params["login"]?
id = params["id"]?
if login && (json = REDIS_DB.get(login))
puts (JSON.parse(json))
return json
elsif id && (json = REDIS_DB.get(id))
return json
end
# puts REDIS_DB.get(params["login"]?)
# puts REDIS_DB.get(params["id"]?)
# if (json = (REDIS_DB.get(params["login"]?.to_s))) || (json = (REDIS_DB.get(params["id"]?.to_s)))
# if ((json = REDIS_DB.get(id))
# puts json
# return json
# end
gql = GqlAPI.query(params)
panels = gql["user"]["panels"]
banned = checkBanned(gql)
# puts(banned)
json_data = [
{
"cache" => {
"isCached" => false,
"expireTime" => nil : Int32,
},
"banned" => false,
"reason" => banned,
"displayName" => gql["user"]["displayName"],
"login" => gql["user"]["login"],
"id" => gql["user"]["id"],
"bio" => gql["user"]["description"],
"follows" => nil,
"followers" => gql["user"]["followers"]["totalCount"],
"profileViewCount" => nil, # Always null
"panelCount" => panels.size,
"chatColor" => gql["user"]["chatColor"],
"logo" => gql["user"]["profileImageURL"],
"banner" => gql["user"]["bannerImageURL"],
"verifiedBot" => nil, # Deprecated by twitch
"createdAt" => gql["user"]["createdAt"],
"updatedAt" => gql["user"]["updatedAt"],
"deletedAt" => gql["user"]["deletedAt"],
"emotePrefix" => gql["user"]["emoticonPrefix"]["name"],
"roles" => {
"isAffiliate" => gql["user"]["roles"]["isAffiliate"],
"isPartner" => gql["user"]["roles"]["isPartner"],
"isStaff" => gql["user"]["roles"]["isStaff"],
},
"badges" => gql["user"]["displayBadges"],
"chatterCount" => gql["user"]["channel"]["chatters"]["count"],
"chatSettings" => gql["user"]["chatSettings"],
"stream" => gql["user"]["stream"],
"lastBroadcast" => gql["user"]["lastBroadcast"],
"panels" => panels,
},
]
if banned != nil
json_data[0]["banned"] = true
end
if id
REDIS_DB.set(id, json_data.to_json, ex: 5)
else
REDIS_DB.set(login.to_s, json_data.to_json, ex: 5)
end
return json_data.to_json
end
end

View file

@ -2,11 +2,17 @@ require "http/server"
require "kemal"
require "json"
require "uri"
require "./config"
require "./api/*"
require "./twitchapi/*"
require "redis"
require "./config"
require "./routes/**"
require "./twitchapi/*"
module TwAPI
end
alias TA = TwAPI
CONFIG = Config.load
Kemal.config.port = CONFIG.port
REDIS_DB = Redis::PooledClient.new(unixsocket: CONFIG.redis_socket || nil, url: CONFIG.redis_url || nil)
@ -14,41 +20,43 @@ if REDIS_DB.ping
puts "Connected to redis"
end
before_all "/twitch/*" do |env|
before_all "/v2/*" do |env|
env.response.content_type = "application/json"
end
get "/twitch/user" do |env|
query = env.request.query
if query
params = URI::Params.parse(query)
if params.has_key?("login")
begin
Users.parseData(params)
rescue ex
env.response.status_code = 401
err = {"error" => "#{ex.message}"}
err.to_json
end
elsif params.has_key?("id")
begin
Users.parseData(params)
rescue ex
env.response.status_code = 401
err = {"error" => "#{ex.message}"}
err.to_json
end
else
env.response.status_code = 401
err = {"error" => "Parameter 'login' or 'id' is missing"}
err.to_json
end
else
env.response.status_code = 401
err = {"error" => "No query parameters found"}
err.to_json
end
end
TwAPI::Routing.register_all()
# get "/v2/twitch/user" do |env|
# query = env.request.query
# if query
# params = URI::Params.parse(query)
# if params.has_key?("login")
# begin
# Users.parseData(params)
# rescue ex
# env.response.status_code = 401
# err = {"error" => "#{ex.message}"}
# err.to_json
# end
# elsif params.has_key?("id")
# begin
# Users.parseData(params)
# rescue ex
# env.response.status_code = 401
# err = {"error" => "#{ex.message}"}
# err.to_json
# end
# else
# env.response.status_code = 401
# err = {"error" => "Parameter 'login' or 'id' is missing"}
# err.to_json
# end
# else
# env.response.status_code = 401
# err = {"error" => "No query parameters found"}
# err.to_json
# end
# end
{% if flag?(:release) || flag?(:production) %}
Kemal.config.env = "production" if !ENV.has_key?("KEMAL_ENV")

175
src/routes/api/users.cr Normal file
View file

@ -0,0 +1,175 @@
module TwAPI::Routes::Twitch
extend self
def checkBanned(gql)
if GqlAPI.urb.includes? "login"
if gql["userResultByLogin"]["reason"]?
return gql["userResultByLogin"]["reason"]
else
return nil
end
elsif GqlAPI.urb.includes? "id"
if gql["userResultByID"]["reason"]?
return gql["userResultByID"]["reason"]
else
return nil
end
end
end
def parseData(params)
login = params["login"]?
id = params["id"]?
if login && (json = REDIS_DB.get(login))
puts(JSON.parse(json))
return json
elsif id && (json = REDIS_DB.get(id))
return json
end
# puts REDIS_DB.get(params["login"]?)
# puts REDIS_DB.get(params["id"]?)
# if (json = (REDIS_DB.get(params["login"]?.to_s))) || (json = (REDIS_DB.get(params["id"]?.to_s)))
# if ((json = REDIS_DB.get(id))
# puts json
# return json
# end
gql = GqlAPI.queryUser(params)
puts gql
panels = gql["user"]["panels"]
banned = checkBanned(gql)
# puts(banned)
# Using JSON::Builder will be better I guess
json_data = [
{
"cache" => {
"isCached" => false,
"expireTime" => nil : Int32,
},
"banned" => false,
"reason" => banned,
"displayName" => gql["user"]["displayName"],
"login" => gql["user"]["login"],
"id" => gql["user"]["id"],
"bio" => gql["user"]["description"],
"follows" => nil,
"followers" => gql["user"]["followers"]["totalCount"],
"profileViewCount" => nil, # Always null
"panelCount" => panels.size,
"chatColor" => gql["user"]["chatColor"],
"logo" => gql["user"]["profileImageURL"],
"banner" => gql["user"]["bannerImageURL"],
"verifiedBot" => nil, # Deprecated by twitch
"createdAt" => gql["user"]["createdAt"],
"updatedAt" => gql["user"]["updatedAt"],
"deletedAt" => gql["user"]["deletedAt"],
"emotePrefix" => gql["user"]["emoticonPrefix"]["name"],
"roles" => {
"isAffiliate" => gql["user"]["roles"]["isAffiliate"],
"isPartner" => gql["user"]["roles"]["isPartner"],
"isStaff" => gql["user"]["roles"]["isStaff"],
},
"badges" => gql["user"]["displayBadges"],
"chatterCount" => gql["user"]["channel"]["chatters"]["count"],
"chatSettings" => gql["user"]["chatSettings"],
"stream" => gql["user"]["stream"],
"lastBroadcast" => gql["user"]["lastBroadcast"],
"panels" => panels,
},
]
if banned != nil
json_data[0]["banned"] = true
end
if id
REDIS_DB.set(id, json_data.to_json, ex: 5)
else
REDIS_DB.set(login.to_s, json_data.to_json, ex: 5)
end
return json_data.to_json
end
def user(env)
# TODO: Clean this mess shit of else if else if else if
if env.params.query
params = env.params.query
if params.has_key?("login") || params.has_key?("id")
begin
parseData(params)
rescue ex
env.response.status_code = 401
err = {"error" => "#{ex.message}"}
err.to_json
end
elsif params.has_key?("id")
begin
parseData(params)
rescue ex
env.response.status_code = 401
err = {"error" => "#{ex.message}"}
err.to_json
end
else
env.response.status_code = 401
err = {"error" => "Parameter 'login' or 'id' is missing"}
err.to_json
end
else
env.response.status_code = 401
err = {"error" => "No query parameters found"}
err.to_json
end
end
def modvip(env)
if !env.params.query.has_key?("login") && !env.params.query.has_key?("id")
err = {"error" => "No query parameters found"}
return err.to_json
else
gql = GqlAPI.queryModsVips(env.params.query)["user"]
# puts (gql["user"]["mods"]["edges"].size.times)
i, j = 0, 0
json_data = JSON.build do |json|
json.object do
json.field "modCount", gql["mods"]["edges"].size.to_i
json.field "vipCount", gql["vips"]["edges"].size.to_i
json.field "mods" do
json.array do
while i < gql["mods"]["edges"].size # There is a better way to do this?
json.object do
json.field "id", gql["mods"]["edges"][i]["node"]["id"]?
json.field "login", gql["mods"]["edges"][i]["node"]["login"]?
json.field "displayName", gql["mods"]["edges"][i]["node"]["displayName"]?
json.field "grantedAt", gql["mods"]["edges"][i]["grantedAt"]?
i += 1
end
end
end
json.field "vips" do
json.array do
while j < gql["vips"]["edges"].size
json.object do
# puts gql["vips"]["edges"][j]["node"]["id"]
json.field "id", gql["vips"]["edges"][j].try &.["node"]?.try &.["id"]
json.field "login", gql["vips"]["edges"][j].try &.["node"]["login"] || ""
json.field "displayName", gql["vips"]["edges"][j].try &.["node"]["displayName"] || ""
json.field "grantedAt", gql["vips"]["edges"][j]["grantedAt"]?
j += 1
end
end
end
end
end
end
end
return json_data
end
# TODO: Add error message if query doesn't exist at all
end
end

24
src/routes/routes.cr Normal file
View file

@ -0,0 +1,24 @@
module TwAPI::Routing
extend self # To prevent writing self. at the start of every function
# Thanks Invidious devs
{% for http_method in {"get", "post", "delete", "options", "patch", "put"} %}
macro {{http_method.id}}(path, controller, method = :handle)
unless Kemal::Utils.path_starts_with_slash?(\{{path}})
raise Kemal::Exceptions::InvalidPathStartException.new({{http_method}}, \{{path}})
end
Kemal::RouteHandler::INSTANCE.add_route({{http_method.upcase}}, \{{path}}) do |env|
\{{ controller }}.\{{ method.id }}(env)
end
end
{% end %}
def register_all
# get "/"
get "/v2/twitch/user", TwAPI::Routes::Twitch, :user
get "/v2/twitch/modvip", TwAPI::Routes::Twitch, :modvip
end
end

View file

@ -1,7 +1,6 @@
require "json"
require "uri"
module GqlAPI
extend self
@@headers = HTTP::Headers{
"Content-Type" => "application/json",
# "Client-Id" => "kimne78kx3ncx6brgo4mv6wki5h1ko", # Can cause problems due to Client-Integrity
@ -10,11 +9,11 @@ module GqlAPI
}
@@urb : String = "fuck"
def self.urb
def urb
return @@urb
end
def self.userResultBy(params)
def userResultBy(params)
if params.has_key?("id")
return %(userResultByID(id: "#{params["id"]}"))
else
@ -22,7 +21,7 @@ module GqlAPI
end
end
def self.loginOrID(params)
def loginOrID(params)
if params.has_key?("id")
return %(userResultByID(id: "#{params["id"]}")), %(user(id: "#{params["id"]}" lookupType: ALL))
else
@ -30,15 +29,7 @@ module GqlAPI
end
end
# def self.channel (params)
# if params.has_key?("id")
# return %(channel(id: "#{params["id"]}"))
# else
# return %(channel(name: "#{params["login"]}"))
# end
# end
def self.user(params)
def user(params)
if params.has_key?("id")
return %(user(id: "#{params["id"]}" lookupType: ALL))
else
@ -46,27 +37,7 @@ module GqlAPI
end
end
def self.query(params)
# puts params
# id = params["id"]
# data = { "query" => "{user(id:#{id}){
# bannerImageURL,
# profileImageURL(width: 600),
# createdAt,
# updatedAt,
# deletedAt,
# chatColor,
# emoticonPrefix{name},
# panels(hideExtensions: false){id,type},
# follows(first: 1, after: buh, filter: ALL order: ASC){totalCount},
# followers(first: 1, after: buh, order: ASC){totalCount},
# roles{isStaff,isAffiliate,isPartner,isExtensionsDeveloper},
# displayBadges(){setID, title, description,version},
# chatSettings{blockLinks,chatDelayMs,slowModeDurationSeconds,followersOnlyDurationMinutes,isBroadcasterLanguageModeEnabled,isEmoteOnlyModeEnabled,isFastSubsModeEnabled,isSubscribersOnlyModeEnabled,isUniqueChatModeEnabled,requireVerifiedAccount,rules},
# stream{averageFPS,bitrate,codec,createdAt,width,height,id,viewersCount,type,game{displayName}},
# lastBroadcast{game{displayName},id,startedAt,title}
# }}" }
def queryUser(params)
@@urb = userResultBy(params)
query = %(
query {
@ -157,36 +128,42 @@ module GqlAPI
}
}
)
# puts JSON.parse(gqlReqq)["data"]
# puts ("gqlReq JSON.parse typeof: #{typeof (gqlReqq)}")
# puts ("gqlReq JSON.parse typeof: #{typeof(JSON.parse(gqlReq(params, query))["data"])}")
# puts ("gqlReq JSON.parse.to-H typeof: #{typeof (gqlReqq.to_h)}")
# puts ((JSON.parse(gqlReq(params, query)))["data"])["userResultByID"]["reason"]?
return (JSON.parse(gqlReq(params, query)))["data"]
end
# def self.isBanned(id : String)
# data = {"query" => "{userResultByID(id:#{id}){... on UserDoesNotExist{reason}}}"}
# return JSON.parse(gqlReq(id, data.to_json))["data"]["userResultByID"]
# end
def queryModsVips(params)
query = %(
query {
#{user(params)} {
mods(first: 100) {
edges {
grantedAt
isActive
node {
displayName
id
login
}
}
}
vips(first: 100) {
edges {
grantedAt
node {
displayName
id
login
}
}
}
}
}
)
return (JSON.parse(gqlReq(params, query)))["data"]
end
# def self.channel(id : String)
# data = {"query" => "{channel(id:#{id}){
# chatters{count,moderators{login},vips{login}}
# }}"}
# return JSON.parse(gqlReq(id, data.to_json))["data"]["channel"]
# end
# def self.query(id : String)
# data = { "query" => "{query(id:#{id}){
# chatters{count,moderators{login},vips{login}}
# }}" }
# return JSON.parse(gqlReq(id, data.to_json))["data"]["channel"]
# end
def self.gqlReq(params, query)
def gqlReq(params, query)
data = {"query" => query}
# puts (typeof(data))
response = HTTP::Client.post(CONFIG.gqlEndpoint.to_s, headers: @@headers, body: data.to_json)
if response.success?
@ -196,17 +173,4 @@ module GqlAPI
raise "GQL Twitch API returned #{response.status_code}: #{response.body.to_s}"
end
end
# def self.gqlReq(operation : String, login : String)
# gqlRequest = gqlOperation2()
# puts gqlRequest
# response = HTTP::Client.post(CONFIG.gqlEndpoint.to_s, headers: @@headers, body: gqlRequest)
# if response.success?
# return (response.body)
# else
# raise "GQL Twitch API returned #{response.status_code}: #{response.body.to_s}"
# end
# end
end