update concerns
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
require "zip"
|
||||
require "fileutils"
|
||||
|
||||
module SoftwareUpdater
|
||||
module ArchiveExtraction
|
||||
private
|
||||
|
||||
def base_path
|
||||
@base_path ||= ENV.fetch("FILE_CONTAINER_PATH", "/softwares")
|
||||
end
|
||||
|
||||
def full_path(filename)
|
||||
File.join(base_path, filename)
|
||||
end
|
||||
|
||||
def dir_exists?(dirname)
|
||||
File.directory?(full_path(dirname))
|
||||
end
|
||||
|
||||
def delete_dir(dirname)
|
||||
FileUtils.rm_rf(full_path(dirname))
|
||||
end
|
||||
|
||||
def create_dir(dirname)
|
||||
FileUtils.mkdir_p(full_path(dirname))
|
||||
end
|
||||
|
||||
def unzip_file(zip_filename, dest_dirname)
|
||||
dest = full_path(dest_dirname)
|
||||
Zip::File.open(full_path(zip_filename)) do |zip|
|
||||
zip.each do |entry|
|
||||
entry_dest = File.join(dest, entry.name)
|
||||
FileUtils.mkdir_p(File.dirname(entry_dest))
|
||||
entry.extract(entry_dest) { true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_zip_to_dir(zip_file, dir_name)
|
||||
delete_dir(dir_name) if dir_exists?(dir_name)
|
||||
create_dir(dir_name)
|
||||
unzip_file(zip_file, dir_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
require "json"
|
||||
|
||||
module SoftwareUpdater
|
||||
module MetadataParsing
|
||||
METADATA_KEYS = %i[name title author desc site repo license].freeze
|
||||
|
||||
private
|
||||
|
||||
def parse_json_metadata(path)
|
||||
raw = JSON.parse(File.read(path), symbolize_names: true)
|
||||
raw.slice(*METADATA_KEYS)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module SoftwareUpdater
|
||||
module SoftwarePersistence
|
||||
private
|
||||
|
||||
def update_or_create_software(attrs)
|
||||
software = Software.unscoped.find_or_initialize_by(name: attrs[:name])
|
||||
software.assign_attributes(attrs.except(:name))
|
||||
software.deleted_at = nil
|
||||
software.save!
|
||||
software
|
||||
end
|
||||
|
||||
def upsert_external_link(software_id, label, url)
|
||||
link = ExternalLink.unscoped.find_or_initialize_by(software_id: software_id, label: label)
|
||||
link.url = url
|
||||
link.deleted_at = nil
|
||||
link.save!
|
||||
end
|
||||
|
||||
def create_release_if_not_exists(attrs)
|
||||
existing = Release.unscoped.find_by(software_id: attrs[:software_id], version: attrs[:version])
|
||||
return existing if existing
|
||||
|
||||
Release.create!(attrs)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
module SoftwareUpdater
|
||||
module Updatable
|
||||
extend ActiveSupport::Concern
|
||||
include ArchiveExtraction
|
||||
include MetadataParsing
|
||||
include SoftwarePersistence
|
||||
|
||||
class_methods do
|
||||
def platform(value = nil)
|
||||
@platform = value if value
|
||||
@platform ||= name.demodulize.delete_suffix("Service").downcase
|
||||
end
|
||||
end
|
||||
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
prepare_files(versioned)
|
||||
|
||||
metadata = parse_metadata(versioned)
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: self.class.platform))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
{ software_id: software.id, version: version }.merge(release_paths(versioned))
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_files(versioned)
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
end
|
||||
|
||||
def parse_metadata(versioned)
|
||||
parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
end
|
||||
|
||||
def release_paths(versioned)
|
||||
{ html_folder_path: full_path(versioned) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,73 +0,0 @@
|
||||
require "zip"
|
||||
require "json"
|
||||
require "fileutils"
|
||||
|
||||
module SoftwareUpdater
|
||||
class BaseService
|
||||
def initialize
|
||||
@base_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def full_path(filename)
|
||||
File.join(@base_path, filename)
|
||||
end
|
||||
|
||||
def dir_exists?(dirname)
|
||||
File.directory?(full_path(dirname))
|
||||
end
|
||||
|
||||
def delete_dir(dirname)
|
||||
FileUtils.rm_rf(full_path(dirname))
|
||||
end
|
||||
|
||||
def create_dir(dirname)
|
||||
FileUtils.mkdir_p(full_path(dirname))
|
||||
end
|
||||
|
||||
def unzip_file(zip_filename, dest_dirname)
|
||||
dest = full_path(dest_dirname)
|
||||
Zip::File.open(full_path(zip_filename)) do |zip|
|
||||
zip.each do |entry|
|
||||
entry_dest = File.join(dest, entry.name)
|
||||
FileUtils.mkdir_p(File.dirname(entry_dest))
|
||||
entry.extract(entry_dest) { true }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_zip_to_dir(zip_file, dir_name)
|
||||
delete_dir(dir_name) if dir_exists?(dir_name)
|
||||
create_dir(dir_name)
|
||||
unzip_file(zip_file, dir_name)
|
||||
end
|
||||
|
||||
def parse_json_metadata(path)
|
||||
raw = JSON.parse(File.read(path), symbolize_names: true)
|
||||
raw.slice(:name, :title, :author, :desc, :site, :repo, :license)
|
||||
end
|
||||
|
||||
def update_or_create_software(attrs)
|
||||
software = Software.unscoped.find_or_initialize_by(name: attrs[:name])
|
||||
software.assign_attributes(attrs.except(:name))
|
||||
software.deleted_at = nil
|
||||
software.save!
|
||||
software
|
||||
end
|
||||
|
||||
def upsert_external_link(software_id, label, url)
|
||||
link = ExternalLink.unscoped.find_or_initialize_by(software_id: software_id, label: label)
|
||||
link.url = url
|
||||
link.deleted_at = nil
|
||||
link.save!
|
||||
end
|
||||
|
||||
def create_release_if_not_exists(attrs)
|
||||
existing = Release.unscoped.find_by(software_id: attrs[:software_id], version: attrs[:version])
|
||||
return existing if existing
|
||||
|
||||
Release.create!(attrs)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,24 +1,5 @@
|
||||
module SoftwareUpdater
|
||||
class BevyService < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "bevy"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
html_folder_path: full_path(versioned)
|
||||
)
|
||||
end
|
||||
end
|
||||
class BevyService
|
||||
include Updatable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
module SoftwareUpdater
|
||||
class C64Service < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
class C64Service
|
||||
include Updatable
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
private
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "c64"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
def prepare_files(_versioned)
|
||||
# a c64 buildhez nem tartozik html zip, csak a .prg fájl
|
||||
end
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
cartridge_path: full_path("#{versioned}.prg")
|
||||
)
|
||||
end
|
||||
def release_paths(versioned)
|
||||
{ cartridge_path: full_path("#{versioned}.prg") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
module SoftwareUpdater
|
||||
class EbitengineService < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "ebitengine"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
html_folder_path: full_path(versioned)
|
||||
)
|
||||
end
|
||||
end
|
||||
class EbitengineService
|
||||
include Updatable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
module SoftwareUpdater
|
||||
class GodotService < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "godot"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
html_folder_path: full_path(versioned)
|
||||
)
|
||||
end
|
||||
end
|
||||
class GodotService
|
||||
include Updatable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
module SoftwareUpdater
|
||||
class LoveService < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "love"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
html_folder_path: full_path(versioned)
|
||||
)
|
||||
end
|
||||
end
|
||||
class LoveService
|
||||
include Updatable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
module SoftwareUpdater
|
||||
class PhaserService < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
|
||||
metadata = parse_json_metadata(full_path("#{versioned}.metadata.json"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "phaser"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
html_folder_path: full_path(versioned)
|
||||
)
|
||||
end
|
||||
end
|
||||
class PhaserService
|
||||
include Updatable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,34 +1,27 @@
|
||||
module SoftwareUpdater
|
||||
class Tic80Service < BaseService
|
||||
def update(name, version)
|
||||
versioned = "#{name}-#{version}"
|
||||
docs_dir = "#{versioned}-docs"
|
||||
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
extract_zip_to_dir("#{versioned}-docs.zip", docs_dir)
|
||||
|
||||
metadata = parse_lua_metadata(full_path("#{versioned}.lua"))
|
||||
site_url = metadata.delete(:site)
|
||||
repo_url = metadata.delete(:repo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
software = update_or_create_software(metadata.merge(platform: "tic80"))
|
||||
upsert_external_link(software.id, "Source Code", site_url) if site_url.present?
|
||||
upsert_external_link(software.id, "Repository", repo_url) if repo_url.present?
|
||||
|
||||
create_release_if_not_exists(
|
||||
software_id: software.id,
|
||||
version: version,
|
||||
cartridge_path: full_path("#{versioned}.tic"),
|
||||
source_path: full_path("#{versioned}.lua"),
|
||||
html_folder_path: full_path(versioned),
|
||||
docs_folder_path: full_path(docs_dir)
|
||||
)
|
||||
end
|
||||
end
|
||||
class Tic80Service
|
||||
include Updatable
|
||||
|
||||
private
|
||||
|
||||
def prepare_files(versioned)
|
||||
extract_zip_to_dir("#{versioned}.html.zip", versioned)
|
||||
extract_zip_to_dir("#{versioned}-docs.zip", "#{versioned}-docs")
|
||||
end
|
||||
|
||||
def parse_metadata(versioned)
|
||||
parse_lua_metadata(full_path("#{versioned}.lua"))
|
||||
end
|
||||
|
||||
def release_paths(versioned)
|
||||
{
|
||||
cartridge_path: full_path("#{versioned}.tic"),
|
||||
source_path: full_path("#{versioned}.lua"),
|
||||
html_folder_path: full_path(versioned),
|
||||
docs_folder_path: full_path("#{versioned}-docs")
|
||||
}
|
||||
end
|
||||
|
||||
def parse_lua_metadata(source_path)
|
||||
metadata = {}
|
||||
File.foreach(source_path) do |line|
|
||||
@@ -39,7 +32,7 @@ module SoftwareUpdater
|
||||
value = parts[1].strip
|
||||
metadata[key] = value
|
||||
end
|
||||
metadata.slice(:name, :title, :author, :desc, :site, :repo, :license)
|
||||
metadata.slice(*MetadataParsing::METADATA_KEYS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
class UpdateService
|
||||
PLATFORM_SERVICES = {
|
||||
"tic80" => "SoftwareUpdater::Tic80Service",
|
||||
"ebitengine" => "SoftwareUpdater::EbitengineService",
|
||||
"love" => "SoftwareUpdater::LoveService",
|
||||
"c64" => "SoftwareUpdater::C64Service",
|
||||
"godot" => "SoftwareUpdater::GodotService",
|
||||
"bevy" => "SoftwareUpdater::BevyService",
|
||||
"phaser" => "SoftwareUpdater::PhaserService"
|
||||
}.freeze
|
||||
SUPPORTED_PLATFORMS = %w[tic80 ebitengine love c64 godot bevy phaser].freeze
|
||||
|
||||
def update(input)
|
||||
service_class = PLATFORM_SERVICES[input.platform]
|
||||
raise ArgumentError, "Unsupported platform: #{input.platform}" unless service_class
|
||||
service_class.constantize.new.update(input.name, input.version)
|
||||
unless SUPPORTED_PLATFORMS.include?(input.platform)
|
||||
raise ArgumentError, "Unsupported platform: #{input.platform}"
|
||||
end
|
||||
|
||||
"SoftwareUpdater::#{input.platform.camelize}Service".constantize.new.update(input.name, input.version)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user