refact round
This commit is contained in:
@@ -13,7 +13,7 @@ class Api::DownloadsController < ApiController
|
||||
path = params[:path]
|
||||
return render(json: { error: "Path is required" }, status: :bad_request) if path.blank?
|
||||
|
||||
full_path = DownloadService.new.call(
|
||||
full_path = DownloadService.new.create(
|
||||
path: path,
|
||||
ip: request.remote_ip,
|
||||
user_agent: request.user_agent,
|
||||
|
||||
@@ -27,7 +27,7 @@ class Api::WikiController < ApiController
|
||||
end
|
||||
# GET /api/wiki/pages?tag=blog|howto[&limit=30][&body=1]
|
||||
def index
|
||||
render json: WikiService.new.pages(
|
||||
render json: WikiService.new.index(
|
||||
tag: params[:tag],
|
||||
limit: params[:limit],
|
||||
body: params[:body]
|
||||
|
||||
@@ -4,6 +4,15 @@ class UpdateController < ApiController
|
||||
formats [ "text" ]
|
||||
end
|
||||
|
||||
rescue_from ArgumentError do |e|
|
||||
render plain: e.message, status: :bad_request
|
||||
end
|
||||
|
||||
rescue_from StandardError do |e|
|
||||
Rails.logger.error("[UpdateController] #{e.class}: #{e.message}\n#{e.backtrace.first(5).join("\n")}")
|
||||
render plain: "Internal server error", status: :internal_server_error
|
||||
end
|
||||
|
||||
api :GET, "/update", "Update software version in database"
|
||||
param :secret, String, required: true, desc: "Authorization secret"
|
||||
param :platform, String, required: false, desc: "Platform (tic80, love, ebitengine, c64, godot, bevy, phaser)"
|
||||
@@ -25,11 +34,6 @@ class UpdateController < ApiController
|
||||
|
||||
UpdateService.new.update(input)
|
||||
render plain: "Updated"
|
||||
rescue ArgumentError => e
|
||||
render plain: e.message, status: :bad_request
|
||||
rescue => e
|
||||
Rails.logger.error("[UpdateController] #{e.class}: #{e.message}\n#{e.backtrace.first(5).join("\n")}")
|
||||
render plain: "Internal server error", status: :internal_server_error
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -4,8 +4,10 @@ class AdminUser < ApplicationRecord
|
||||
|
||||
belongs_to :member, optional: true
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[created_at email id member_id updated_at]
|
||||
%w[created_at deleted_at email id member_id updated_at]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
|
||||
@@ -3,8 +3,10 @@ class Download < ApplicationRecord
|
||||
|
||||
validates :file_path, presence: true
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[created_at file_path id ip_address referer release_id updated_at user_agent]
|
||||
%w[created_at deleted_at file_path id ip_address referer release_id updated_at user_agent]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
|
||||
@@ -3,12 +3,14 @@ class Image < ApplicationRecord
|
||||
|
||||
has_many :software_images, dependent: :restrict_with_error
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
attr_accessor :file_upload
|
||||
|
||||
before_save :process_upload, if: -> { file_upload.present? }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[content_type created_at filename id original_filename updated_at]
|
||||
%w[content_type created_at deleted_at filename id original_filename updated_at]
|
||||
end
|
||||
|
||||
def file_path
|
||||
|
||||
@@ -4,8 +4,10 @@ class Member < ApplicationRecord
|
||||
|
||||
validates :nick, presence: true, uniqueness: true
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
%w[avatar_filename created_at id image_id motto nick real_nick updated_at]
|
||||
%w[avatar_filename created_at deleted_at id image_id motto nick real_nick updated_at]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module TimestampFields
|
||||
GO_ZERO_TIME = "0001-01-01T00:00:00Z"
|
||||
TS_FORMAT = "%Y-%m-%dT%H:%M:%S.%3NZ"
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
class EventSerializer < Blueprinter::Base
|
||||
DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
||||
include TimestampFields
|
||||
|
||||
field :name
|
||||
field(:date) { |event| event.date.utc.strftime(DATE_FORMAT) }
|
||||
field(:date) { |event| event.date.utc.strftime(TS_FORMAT) }
|
||||
end
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
class ExternalLinkSerializer < Blueprinter::Base
|
||||
GO_ZERO_TIME = "0001-01-01T00:00:00Z"
|
||||
TS_FORMAT = "%Y-%m-%dT%H:%M:%S.%3NZ"
|
||||
include TimestampFields
|
||||
|
||||
field(:ID) { |el| el.id }
|
||||
field(:CreatedAt) { |el| el.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:UpdatedAt) { |el| el.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:DeletedAt) { |el| el.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field(:id) { |el| el.id }
|
||||
field(:createdAt) { |el| el.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:updatedAt) { |el| el.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:deletedAt) { |el| el.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field(:softwareId) { |el| el.software_id }
|
||||
field :label
|
||||
field :url
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
class MemberSerializer < Blueprinter::Base
|
||||
fields :nick, :real_nick, :motto, :avatar_filename
|
||||
fields :nick, :motto
|
||||
|
||||
field(:image_url) { |member| member.image_id ? "/api/image/#{member.image_id}" : nil }
|
||||
field(:realNick) { |m| m.real_nick }
|
||||
field(:avatarFilename) { |m| m.avatar_filename }
|
||||
field(:imageUrl) { |m| m.image_id ? "/api/image/#{m.image_id}" : nil }
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class ReleaseSerializer < Blueprinter::Base
|
||||
GO_ZERO_TIME = "0001-01-01T00:00:00Z"
|
||||
TS_FORMAT = "%Y-%m-%dT%H:%M:%S.%3NZ"
|
||||
include TimestampFields
|
||||
|
||||
FILE_PATH_FROM = "/softwares/"
|
||||
FILE_PATH_TO = "/file/"
|
||||
|
||||
@@ -13,10 +13,10 @@ class ReleaseSerializer < Blueprinter::Base
|
||||
asset ? asset.path.gsub(FILE_PATH_FROM, FILE_PATH_TO) : ""
|
||||
end
|
||||
|
||||
field(:ID) { |r| r.id }
|
||||
field(:CreatedAt) { |r| r.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:UpdatedAt) { |r| r.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:DeletedAt) { |r| r.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field(:id) { |r| r.id }
|
||||
field(:createdAt) { |r| r.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:updatedAt) { |r| r.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:deletedAt) { |r| r.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field(:softwareId) { |r| r.software_id }
|
||||
field :version
|
||||
field(:cartridgePath) { |r| asset_path(r, "cartridge") }
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
class SoftwareSerializer < Blueprinter::Base
|
||||
GO_ZERO_TIME = "0001-01-01T00:00:00Z"
|
||||
TS_FORMAT = "%Y-%m-%dT%H:%M:%S.%3NZ"
|
||||
include TimestampFields
|
||||
|
||||
field(:ID) { |sw| sw.id }
|
||||
field(:CreatedAt) { |sw| sw.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:UpdatedAt) { |sw| sw.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:DeletedAt) { |sw| sw.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field(:id) { |sw| sw.id }
|
||||
field(:createdAt) { |sw| sw.created_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:updatedAt) { |sw| sw.updated_at&.utc&.strftime(TS_FORMAT) || GO_ZERO_TIME }
|
||||
field(:deletedAt) { |sw| sw.deleted_at&.utc&.strftime(TS_FORMAT) }
|
||||
field :name
|
||||
field :title
|
||||
field :author
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class BuildsService
|
||||
def index
|
||||
platforms = UpdateService::SUPPORTED_PLATFORMS.each_with_object({}) do |platform, hash|
|
||||
platforms = PlatformLink::SUPPORTED_PLATFORMS.each_with_object({}) do |platform, hash|
|
||||
service_class = "SoftwareUpdater::#{platform.camelize}Service".constantize
|
||||
hash[platform] = {
|
||||
label: service_class.label,
|
||||
|
||||
@@ -2,7 +2,7 @@ class DownloadService
|
||||
CONTAINER_BASE = ENV.fetch("FILE_CONTAINER_PATH", "/softwares")
|
||||
BASE_PATH = Pathname.new(CONTAINER_BASE).realpath
|
||||
|
||||
def call(path:, ip:, user_agent:, referer:)
|
||||
def create(path:, ip:, user_agent:, referer:)
|
||||
sanitized = path.to_s
|
||||
full_path = BASE_PATH.join(sanitized).realpath
|
||||
return nil unless full_path.to_s.start_with?(BASE_PATH.to_s)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
class UpdateService
|
||||
SUPPORTED_PLATFORMS = %w[tic80 ebitengine love c64 godot bevy phaser].freeze
|
||||
|
||||
def update(input)
|
||||
unless SUPPORTED_PLATFORMS.include?(input.platform)
|
||||
unless PlatformLink::SUPPORTED_PLATFORMS.include?(input.platform)
|
||||
raise ArgumentError, "Unsupported platform: #{input.platform}"
|
||||
end
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ require "json"
|
||||
class WikiService
|
||||
GRAV_URL = ENV.fetch("WIKI_GRAV_URL", "http://localhost:8080").freeze
|
||||
|
||||
def pages(tag:, limit: nil, body: nil)
|
||||
def index(tag:, limit: nil, body: nil)
|
||||
query = { tag: tag }
|
||||
query[:limit] = limit if limit.present?
|
||||
query[:body] = body if body.present?
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class AddDeletedAtToMissingModels < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
%i[images members downloads admin_users].each do |table|
|
||||
add_column table, :deleted_at, :datetime, precision: 3
|
||||
add_index table, :deleted_at, name: "idx_#{table}_deleted_at"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user