sapo-videos/main.rb

125 lines
2.8 KiB
Ruby
Raw Normal View History

2023-07-28 02:01:40 +00:00
# SPDX-License-Identifier: AGPL-3.0-only
# SPDX-FileCopyrightText: 2023 Hugo Peixoto <hugo.peixoto@gmail.com>
require 'sinatra'
require './database.rb'
require './models.rb'
2023-07-28 11:00:41 +00:00
def h(bytes)
if bytes < 2**10
"#{bytes} bytes"
elsif bytes < 2**20
"%.2f KiB" % (1.0 * bytes / 2**10)
elsif bytes < 2**30
"%.2f MiB" % (1.0 * bytes / 2**20)
elsif bytes < 2**40
"%.2f GiB" % (1.0 * bytes / 2**30)
else
"%.2f TiB" % (1.0 * bytes / 2**40)
end
end
def attempt(attempts, &block)
begin
block.call
rescue
if attempts > 1
attempts -= 1
retry
else
raise
end
end
end
2023-07-28 11:00:41 +00:00
set :public_folder, __dir__ + '/public'
2023-07-28 02:01:40 +00:00
get '/' do
downloads = ActiveRecord::Base.connection.execute("
SELECT
COUNT(1) AS total,
SUM(size) AS bytes
2023-08-01 18:58:31 +00:00
FROM (select MAX(size) AS size from downloads group by video_id) as x;
2023-07-28 02:01:40 +00:00
")[0]
2023-07-28 19:50:22 +00:00
videos = ActiveRecord::Base.connection.execute("select count(1) AS total from videos;")[0]
2023-07-28 19:31:14 +00:00
users = ActiveRecord::Base.connection.execute("select count(distinct email) AS total from downloads;")[0]
2023-07-30 16:45:26 +00:00
downloads_per_user = ActiveRecord::Base.connection.execute("select SUM(size) AS size, COUNT(1) AS total FROM (select email, video_id, MAX(size) as size from downloads group by email, video_id) x GROUP BY email ORDER BY 1 DESC;")
2023-07-28 19:31:14 +00:00
2023-07-28 19:50:22 +00:00
stats = {
videos_known: videos["total"].to_i,
videos_downloaded: downloads["total"].to_i,
bytes_downloaded: downloads["bytes"].to_i,
2023-07-30 16:45:26 +00:00
downloads_per_user: downloads_per_user,
2023-07-28 19:50:22 +00:00
users: users["total"],
}
2023-07-28 02:01:40 +00:00
ERB
.new(File.read("index.html.erb"), trim_mode: "<>-")
2023-07-28 19:50:22 +00:00
.result_with_hash(stats)
2023-07-28 02:01:40 +00:00
end
get '/videos.json' do
content_type 'application/json'
amount = params['amount'].to_i
if amount > 100_000
{ error: "greedy" }.to_json
else
videos = Video
.left_outer_joins(:downloads)
.group("randname")
2023-08-01 00:14:16 +00:00
.order("COUNT(downloads.video_id) ASC, RANDOM()")
.limit(amount)
.pluck(:randname)
{ videos: videos }.to_json
2023-07-28 02:01:40 +00:00
end
end
post '/video' do
content_type 'application/json'
data = JSON.parse(request.body.read)
attempt(10) do
Download.create!(
video: Video.find_by!(randname: data["video_id"]),
size: data["size"],
sha256: data["sha256"],
email: data["email"],
)
end
2023-07-28 02:01:40 +00:00
{ status: 'ok' }.to_json
end
post '/check' do
content_type 'application/json'
ids = JSON.parse(request.body.read)
videos = Video
.left_outer_joins(:downloads)
.where(randname: ids)
.pluck(:randname, :sha256, :size)
.map { |v| %w[randname sha256 size].zip(v).to_h }
{ videos: videos }.to_json
end
2023-07-28 02:01:40 +00:00
get '/config.json' do
content_type 'application/json'
{
videos_url: "https://sapo.pxto.pt/videos.json",
upload_url: "https://sapo.pxto.pt/video",
check_url: "https://sapo.pxto.pt/check",
2023-07-28 02:01:40 +00:00
max_amount: 100_000,
}.to_json
end