require 'debci/auth_app'
require 'debci/user'
require 'debci/package'
require 'debci/job'
require 'debci/html_helpers'
module Debci
class Admin < Debci::AuthApp
include Debci::HTMLHelpers
set :views, "#{File.dirname(__FILE__)}/html/templates"
Model = Struct.new(:name, :icon, :ar_class, :order, :fields, :select_fields, :search_fields, :read_only_fields, :edit_fields, :new)
set :models, {}
def self.model(name, **opts)
model = Model.new(name)
opts.each do |k, v|
model.send("#{k}=", v)
end
settings.models[name] = model
end
model :users,
icon: :user,
ar_class: Debci::User,
order: :username,
new: true,
fields: [:username, :uid, :admin],
search_fields: [:username],
read_only_fields: [:username]
model :packages,
icon: :gears,
ar_class: Debci::Package,
order: :name,
new: false,
fields: [:name, :removed, :backend],
select_fields: {
backend: Debci.config.backend_list,
},
search_fields: [:name, :backend],
read_only_fields: [:name]
before do
authenticate!
forbidden unless @user.admin
end
get '/' do
erb :admin_index, locals: { models: settings.models, current_model: nil }
end
get '/:model/' do
halt 404 unless current_model
rel = current_model.all.order(order)
if params[:q]
q = "%#{current_model.sanitize_sql_like(params[:q])}%"
cond = search_fields.map { |f| "#{f} LIKE ?" }.join(" OR ")
values = search_fields.map { |_f| q }
rel = rel.where(cond, *values)
end
results = get_page_params(rel, params[:page], 20) erb :admin_index, locals: {
models: settings.models,
current_model: current_model,
results: results,
fields: fields,
}
end
get '/:model/new/' do
forbidden unless current_model_info.new
object = current_model.new
erb :admin_edit, locals: { object: object, fields: fields, select_fields: select_fields, read_only_fields: [] }
end
get '/:model/:id/' do
halt 404 unless current_model
erb :admin_edit, locals: { object: current_object, fields: fields, select_fields: select_fields, read_only_fields: read_only_fields }
end
post '/:model/new/' do
forbidden unless current_model_info.new
save_object(current_model.new, params, [])
redirect "/admin/#{current_model_name}/"
end
post '/:model/:id/' do
save_object(current_object, params, read_only_fields)
redirect "/admin/#{current_model_name}/"
end
def save_object(object, params, read_only_fields)
data = params.reject do |key, _value|
[:model, :id].include?(key.to_sym) || read_only_fields.include?(key.to_sym)
end
data.each_key do |f|
column = current_model.columns_hash[f]
data[f] = nil if column.null && data[f].blank?
end
object.update!(data) end
def current_model_name
@current_model_name ||= params[:model]
end
def current_model_info
@current_model_info ||= settings.models[params[:model].to_sym]
end
def current_model
@current_model ||= current_model_info.ar_class
end
def order
current_model_info.order || :id
end
def current_object
@current_object ||= current_model.find(params[:id])
rescue ActiveRecord::RecordNotFound
halt 404
end
def fields
@fields ||= current_model_info.fields
end
def select_fields
@select_fields ||= current_model_info.select_fields || []
end
def read_only_fields
@read_only_fields ||=
if current_model_info.read_only_fields
current_model_info.read_only_fields
elsif current_model_info.edit_fields
current_model_info.fields - current_model_info.edit_fields
else
[]
end
end
def search_fields
@search_fields ||= current_model_info.search_fields
end
end
end