LifePex/src/systems/pex.rb

314 lines
10 KiB
Ruby

require "date"
require_relative "./auth.rb"
require_relative "./csrf.rb"
class LifePex::Systems::PexSystem < LifePex::Systems::AuthSystem
include JSON::API
include LifePex::Systems::CrlfHelper
def my_user_pexs(cookies, date = nil)
params = {
user_id: user_id_decoded(cookies),
}
params[:created_at] = date unless date.nil?
LifePex::UserPex.where(params).all()
end
def get_user_date
date = cookies["date"]
if date && Date.respond_to?(date)
Date.send date
elsif date == "yesterday"
Date.today - 1
else
Date.today
end
end
get "/today", auth: [] do
cookies.set "date", { value: "today", httponly: false }
redirect "/"
end
get "/yesterday", auth: [] do
cookies.set "date", { value: "yesterday", httponly: false }
redirect "/"
end
def pex_by_models(params, filter_hidden: true)
user_pexs = my_user_pexs(cookies, get_user_date)
user_pexs_amounts = user_pexs.group_by { |user_pex| user_pex[:pex_id] }
pexs = LifePex::Pex.where(user_id: current_user_id)
pexs = pexs.where(hidden: false) if filter_hidden
pexs = pexs.all
pex_by_models = pexs.map do |pex|
{
pex: pex,
user_pexs: {
at_date: (user_pexs_amounts[pex[:id]] || []).length
},
}
end
pex_by_models
end
get "/", auth: [], provides: 'html' do
pex_by_models = pex_by_models(params, filter_hidden: params['filter_hidden'] != 'false')
slim :index, locals: { pex_by_models: pex_by_models }
end
post "/", auth: [] do
user_id = user_id_decoded(cookies)
pex_id = params["id"]
if params["type"] == "+"
LifePex::UserPex.new(user_id: user_id, pex_id: pex_id, created_at: get_user_date).save
elsif params["type"] == "-"
user_pex = LifePex::UserPex.where(user_id: user_id, pex_id: pex_id, created_at: get_user_date).select(:id).first
halt 400, "No user pex can be found" if user_pex.nil?
LifePex::UserPex.where(id: user_pex[:id]).delete
end
redirect "/"
end
get "/pexs", auth: [] do
slim :pex_form
end
get "/pexs/update", auth: [] do
pex = LifePex::Pex.where(id: params["id"]).first
slim :pex_form, locals: { pex: pex, submit_name: "update" }
end
post "/pexs", auth: [] do
pex_id = if params["id"]
LifePex::Pex.where(id: params["id"]).update(name: params['name'], category: params['category'].to_s.downcase, amount: params['amount'])
else
LifePex::Pex.new(name: params['name'], category: params['category'], amount: params['amount'], user_id: current_user.id).save
end
if pex_id
redirect "/"
else
slim :register, locals: { flash: { danger: "Failed to add #{params['name']}" } }
end
end
post "/pexs/delete", auth: [] do
removed = LifePex::Pex.where(id: params['id']).delete
links_removed = LifePex::UserPex.where(pex_id: params['id']).delete
slim :pex_removed, locals: { flash: { success: "#{removed} model and #{links_removed} marks removed" } }
end
post "/pexs/hide", auth: [] do
pex = LifePex::Pex.find(id: params['id'])
pex.set(hidden: !pex.hidden).save
redirect '/'
end
post "/pexs/bookmark", auth: [] do
pex = LifePex::Pex.find(id: params['id'])
set_flag = pex.bookmarked? ? "" : "bookmarked"
pex.set(flag: set_flag).save
redirect '/'
end
def compute_highchart_cumul(pex_data)
total = 0
pex_data.map do |v|
total += v
end
end
def get_recap_infos(cookies)
user_pexs = my_user_pexs(cookies)
pexs = LifePex::Pex.setup_user_pexs(user_id: current_user_id, user_pexs: user_pexs)
total_xp = pexs.values.sum { |up| up[:total_by_date].values.sum }
level = LifePex::Level.new total_xp
all_dates = user_pexs.map(&:created_at).uniq
all_category = pexs.values.map(&:category).uniq
pex_table_by_date = all_dates.map { |date| [date, 0] }.to_h
pexs.values.each do |pex|
pex[:total_by_date].each do |date, total|
# pex_table_by_date[date] ||= 0
pex_table_by_date[date] += total
end
end
pex_table_by_category_and_date = all_category.map do |category|
[
category,
all_dates.map { |date| [date, 0] }.to_h,
]
end.to_h
pexs.values.each do |pex|
pex[:total_by_date].each do |date, total|
category = pex[:category]
# pex_table_by_category_and_date[category] ||= {}
# pex_table_by_category_and_date[category][date] ||= 0
pex_table_by_category_and_date[category][date] += total
end
end
highchart_total = {
name: 'total',
data: compute_highchart_cumul(pex_table_by_date.values),
}
highchart_tables = pex_table_by_category_and_date.map do |category, total_by_date|
{
name: category,
data: compute_highchart_cumul(total_by_date.values),
}
end.unshift(highchart_total)
all_setup = LifePex::Achievement.where(user_id: current_user_id).map(&:to_dsl_setup)
medals = all_setup.filter do |success|
success.call(user_pexs, pexs.values)
end
{
pex_tables: highchart_tables,
level: level,
medals: medals,
}
end
get "/recap", auth: [], provides: 'html' do
recap_infos = get_recap_infos(cookies)
slim :recap, locals: recap_infos
end
extend DocMyRoutes::Annotatable
register Sinatra::Namespace
namespace '/api/pex/v1' do
summary 'Get a dataset by category of the total point by time'
produces 'application/json'
status_codes [200]
get "/recap", auth: [], provides: 'json' do
recap_infos = get_recap_infos(cookies)
{
pex_tables: recap_infos[:pex_tables],
level: recap_infos[:level].to_h,
}.to_json
end
summary 'The the list of the pex and user pex for eahc model'
produces 'application/json'
status_codes [200]
get "/pex_by_models", auth: [], provides: 'json' do
pex_by_models = pex_by_models(json_params)
pex_by_models.to_json
end
namespace "/pex" do
summary 'Get a list of all pex'
produces 'application/json'
status_codes [200]
get "/", auth: [], provides: 'json' do
current_user.pexs.to_json
end
summary 'Create a new pex'
produces 'application/json'
status_codes [200]
parameter :name, required: true, type: 'string', in: 'body'
parameter :category, required: true, type: 'string', in: 'body'
parameter :amount, required: true, type: 'number', in: 'body'
parameter :auth, required: true, type: 'string', in: 'cookies'
post "/", auth: [], provides: 'json' do
pex_id = LifePex::Pex.new(
name: json_params['name'],
category: json_params['category'],
amount: json_params['amount'],
user_id: current_user.id,
).save
{
message: "entity created",
pex: LifePex::Pex.find(id: pex_id),
}.to_json
end
summary 'Show the state of a pex'
notes "Sloppy implementation"
produces 'application/json'
status_codes [200]
parameter :id, required: true, type: 'string', in: 'path'
get "/by_id/:id", auth: [], provides: 'json' do
{
pex: LifePex::Pex.find(
id: params["id"],
user_id: current_user.id,
),
}.to_json
end
summary 'Modify an existing pex'
produces 'application/json'
status_codes [200]
parameter :id, required: true, type: 'integer', in: 'path'
parameter :name, required: false, type: 'string', in: 'body'
parameter :category, required: false, type: 'string', in: 'body'
parameter :amount, required: false, type: 'number', in: 'body'
parameter :auth, required: true, type: 'string', in: 'cookies'
post "/by_id/:id", auth: [], provides: 'json' do
LifePex::Pex.where(id: params["id"]).update(
name: json_params['name'],
category: json_params['category'].to_s.downcase,
amount: json_params['amount'],
)
{
message: "entity updated",
pex: LifePex::Pex.find(id: params["id"]),
}.to_json
end
summary 'Remove a pex and its dependencies'
notes "Sloppy implementation"
produces 'application/json'
status_codes [200]
parameter :id, required: true, type: 'integer', in: 'path'
parameter :auth, required: true, type: 'string', in: 'cookies'
delete "/by_id/:id", auth: [], provides: 'json' do
amount1 = LifePex::Pex.where(id: params["id"], user_id: current_user.id).delete
amount2 = LifePex::UserPex.where(pex_id: params["id"], user_id: current_user.id).delete
{
message: "deleted #{amount1 + amount2} entities",
amount1: amount1,
amount2: amount2,
}.to_json
end
summary 'Increase the amount occurence of this pex for a day (default today)'
notes "Sloppy implementation"
produces 'application/json'
status_codes [200]
parameter :id, required: true, type: 'integer', in: 'path'
parameter :date, required: false, type: '"now"|"yesterday"', in: 'cookies'
parameter :auth, required: true, type: 'string', in: 'cookies'
post "/by_id/:id/mark", auth: [], provides: 'json' do
user_id = user_id_decoded
pex_id = params["id"]
LifePex::UserPex.new(user_id: user_id, pex_id: pex_id, created_at: get_user_date).save
{ message: "ok" }.to_json
end
summary 'Decrease the amount occurence of this pex for a day (default today)'
notes "Sloppy implementation"
produces 'application/json'
status_codes [200]
parameter :id, required: true, type: 'integer', in: 'path'
parameter :date, required: false, type: '"now"|"yesterday"', in: 'cookies'
parameter :auth, required: true, type: 'string', in: 'cookies'
post "/by_id/:id/undo_mark", auth: [], provides: 'json' do
user_id = user_id_decoded
pex_id = params["id"]
id = LifePex::UserPex.where(user_id: user_id, pex_id: pex_id, created_at: get_user_date).select(:id).first[:id]
LifePex::UserPex.where(id: id).delete
{ message: "ok" }.to_json
end
end
end
include LifePex::Systems::ApiList
end