card-mod-assets 0.13.2 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/db/migrate_core_cards/202108028112352_death_to_machines.rb +114 -0
- data/lib/card/assets.rb +95 -0
- data/locales/de.yml +2 -0
- data/locales/en.yml +2 -0
- data/set/abstract/01_manifest_group.rb +1 -7
- data/set/abstract/asset_file.rb +6 -12
- data/set/abstract/asset_group.rb +55 -0
- data/set/abstract/asset_inputter.rb +71 -0
- data/set/abstract/asset_outputter.rb +97 -0
- data/set/abstract/folder_group.rb +26 -0
- data/set/abstract/mod_assets.rb +94 -109
- data/set/right/asset_input.rb +17 -0
- data/set/right/asset_output.rb +36 -0
- data/set/type/mod.rb +30 -18
- metadata +82 -12
- data/set/abstract/asset_list.rb +0 -66
- data/set/abstract/local_folder_group.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ce85a0a2a52676f5a29ea74def8271c272b2c7e15cb3f55acb7c219b14e6fc3
|
4
|
+
data.tar.gz: 3e8af9aec31f45db69f0520a655569174581412cfe892350b4d407bcc3c16d70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c51a045909d4ec620eea6c72c73f26ef73c4b72b55b1a3333f1eb600190c4b045acd886c1bb2ee17eb25dd3ee4ddd6a05fcfe685bc6ab8fd59c69c011f5c441e
|
7
|
+
data.tar.gz: bdb404fe90fa57c398896f8192f2d77baab04ee3fa6fbcd14c2835cbb9f28d2f96b4e9c015da0e94b4511efc7a8724d3fc17db1f79fe407f8a4986c11e8a608f
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
class DeathToMachines < Cardio::Migration::Core
|
4
|
+
DEPRECATED_CODE_NAMES = %i[
|
5
|
+
machine_input machine_output machine_cache
|
6
|
+
style_media
|
7
|
+
style_prosemirror script_prosemirror script_prosemirror_config
|
8
|
+
script_ace script_ace_config
|
9
|
+
script_datepicker_config style_datepicker
|
10
|
+
script_tinymce script_tinymce_config
|
11
|
+
script_load_select2 style_select2 script_select2
|
12
|
+
style_bootstrap_cards
|
13
|
+
font_awesome
|
14
|
+
material_icons
|
15
|
+
style_bootstrap_colorpicker
|
16
|
+
style_select2_bootstrap
|
17
|
+
style_libraries
|
18
|
+
script_html5shiv_printshiv
|
19
|
+
smartmenu_css smartmenu_js
|
20
|
+
mod_script_assets mod_style_assets
|
21
|
+
style_bootstrap_compatible
|
22
|
+
style_right_sidebar
|
23
|
+
style_bootstrap_mixins
|
24
|
+
style_bootstrap_breakpoints
|
25
|
+
script_bootstrap
|
26
|
+
script_datepicker
|
27
|
+
script_jquery_helper style_jquery_ui_smoothness
|
28
|
+
style_cards
|
29
|
+
].freeze
|
30
|
+
|
31
|
+
DEPRECATED_CARD_NAMES = [
|
32
|
+
"simple skin",
|
33
|
+
"themeless bootstrap skin",
|
34
|
+
"style: traditional", "style: common", "style: glyphicons",
|
35
|
+
"classic bootstrap skin+*colors", "classic bootstrap skin+*variables",
|
36
|
+
"style: classic cards"
|
37
|
+
].freeze
|
38
|
+
|
39
|
+
def up
|
40
|
+
delete_machine_cards :machine_output
|
41
|
+
delete_machine_cards :machine_input
|
42
|
+
delete_machine_cards :machine_cache
|
43
|
+
delete_group_card
|
44
|
+
delete_old_style_cards
|
45
|
+
|
46
|
+
ensure_code_card "*asset input"
|
47
|
+
ensure_code_card "*asset output"
|
48
|
+
|
49
|
+
drop_all_style_items
|
50
|
+
update_mod_asset_type_id
|
51
|
+
|
52
|
+
Card::Cache.reset_all
|
53
|
+
|
54
|
+
delete_deprecated_code_cards
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def update_mod_asset_type_id
|
60
|
+
return unless Card::Codename.exists? "mod_script_assets"
|
61
|
+
|
62
|
+
Card.search type_id: ["in", Card::ModScriptAssetsID, Card::ModStyleAssetsID] do |card|
|
63
|
+
card.update! type_id: Card::ListID,
|
64
|
+
skip: %i[validate_asset_inputs update_asset_output_file]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def drop_all_style_items
|
69
|
+
Card[:all, :style].item_cards.each do |card|
|
70
|
+
next unless card.left&.type_id == Card::ModID && card.right&.codename == :style
|
71
|
+
Card[:all, :style].drop_item! card
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_deprecated_code_cards
|
76
|
+
DEPRECATED_CODE_NAMES.each do |codename|
|
77
|
+
delete_code_card codename
|
78
|
+
end
|
79
|
+
|
80
|
+
%w[cerulean cosmo cyborg darkly flatly journal lumen
|
81
|
+
paper readable sandstone simplex
|
82
|
+
slate spacelab superhero united yeti bootstrap_default].each do |theme|
|
83
|
+
delete_code_card "theme_#{theme}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete_machine_cards codename
|
88
|
+
Card.search right: codename do |card|
|
89
|
+
card.update_column :codename, ""
|
90
|
+
card.delete!
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def delete_old_style_cards
|
95
|
+
DEPRECATED_CARD_NAMES.each do |doomed|
|
96
|
+
delete_card doomed
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def delete_group_card
|
101
|
+
Card.search type_id: ["in",
|
102
|
+
Card::LocalScriptManifestGroupID,
|
103
|
+
Card::LocalStyleManifestGroupID,
|
104
|
+
Card::LocalScriptFolderGroupID,
|
105
|
+
Card::LocalStyleFolderGroupID] do |card|
|
106
|
+
Card.search left_id: card.id do |field|
|
107
|
+
field.update_column :codename, ""
|
108
|
+
field.delete
|
109
|
+
end
|
110
|
+
card.update_column :codename, ""
|
111
|
+
card.delete! skip: :asset_input_changed_on_delete
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/card/assets.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class Card
|
2
|
+
# Provides methods to refresh script and style assets
|
3
|
+
module Assets
|
4
|
+
REFRESHED = "ASSETS_REFRESHED".freeze
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# FIXME: if we need this (not sure we do? see below), these types should probably
|
8
|
+
# be in a basket so that monkeys can add them.
|
9
|
+
def inputter_types
|
10
|
+
[
|
11
|
+
JavaScriptID,
|
12
|
+
CoffeeScriptID,
|
13
|
+
CssID,
|
14
|
+
ScssID
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def refresh_assets force: false
|
19
|
+
return unless force || refresh_assets?
|
20
|
+
|
21
|
+
inputters = standard_inputters
|
22
|
+
|
23
|
+
# typically nonstandard inputters are standard cards, so their events
|
24
|
+
# should manage normal (non-forced) refreshing.
|
25
|
+
# (standard_inputters, by contrast, are in code, so this refreshing is
|
26
|
+
# needed eg in development mode to detect changes)
|
27
|
+
inputters += nonstandard_inputters if force
|
28
|
+
inputters.each(&:refresh_asset)
|
29
|
+
|
30
|
+
generate_asset_output_files if force
|
31
|
+
end
|
32
|
+
|
33
|
+
def make_output_coded
|
34
|
+
asset_outputters.each(&:make_asset_output_coded)
|
35
|
+
end
|
36
|
+
|
37
|
+
def active_theme_cards
|
38
|
+
style_rule = { left: { type_id: SetID }, right_id: StyleID }
|
39
|
+
Card.search(referred_to_by: style_rule).select do |theme|
|
40
|
+
theme.respond_to? :theme_name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def generate_asset_output_files
|
47
|
+
asset_outputters.each(&:update_asset_output)
|
48
|
+
end
|
49
|
+
|
50
|
+
def script_outputters
|
51
|
+
Card.search(left: { type: :mod }, right_id: ScriptID).flatten
|
52
|
+
end
|
53
|
+
|
54
|
+
def style_outputters
|
55
|
+
[Card[:all, :style]]
|
56
|
+
end
|
57
|
+
|
58
|
+
def asset_outputters
|
59
|
+
script_outputters + style_outputters
|
60
|
+
end
|
61
|
+
|
62
|
+
# MOD+:style and MOD+:script cards, which represent the assets in MOD/assets/style
|
63
|
+
# and MOD/assets/script directories respectively
|
64
|
+
def standard_inputters
|
65
|
+
@standard_inputter_ids ||=
|
66
|
+
Card.search left: { type: :mod }, right_id: [StyleID, ScriptID], return: :id
|
67
|
+
@standard_inputter_ids.map(&:card)
|
68
|
+
end
|
69
|
+
|
70
|
+
# standalone cards, NOT in mod assets directories
|
71
|
+
def nonstandard_inputters
|
72
|
+
Card.search type_id: inputter_types.unshift("in")
|
73
|
+
end
|
74
|
+
|
75
|
+
def refresh_assets?
|
76
|
+
case Cardio.config.asset_refresh
|
77
|
+
when :eager then true
|
78
|
+
when :cautious then cautious_refresh?
|
79
|
+
when :never then false
|
80
|
+
else
|
81
|
+
raise Card::Error,
|
82
|
+
"unknown option for asset refresh: #{Cardio.config.asset_refresh}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# only refresh when cache was cleared
|
87
|
+
def cautious_refresh?
|
88
|
+
return false unless Cache.persistent_cache
|
89
|
+
return false if Card.cache.read REFRESHED
|
90
|
+
|
91
|
+
Card.cache.write REFRESHED, true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/locales/de.yml
ADDED
data/locales/en.yml
ADDED
data/set/abstract/asset_file.rb
CHANGED
@@ -8,6 +8,12 @@ def source_paths
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def files_must_exist!
|
12
|
+
source_paths.select do |path|
|
13
|
+
raise Card::Error, "couldn't locate asset file: #{path}" if unknown_file? path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
11
17
|
def source_files
|
12
18
|
[db_content]
|
13
19
|
end
|
@@ -33,18 +39,6 @@ def new?
|
|
33
39
|
false
|
34
40
|
end
|
35
41
|
|
36
|
-
def compress?
|
37
|
-
@minimize
|
38
|
-
end
|
39
|
-
|
40
|
-
def minimize
|
41
|
-
@minimze = true
|
42
|
-
end
|
43
|
-
|
44
|
-
def local
|
45
|
-
@local = true
|
46
|
-
end
|
47
|
-
|
48
42
|
format do
|
49
43
|
def link_view opts={}
|
50
44
|
opts[:path] = { card: { type: card.type, content: card.db_content } }
|
@@ -0,0 +1,55 @@
|
|
1
|
+
include_set Abstract::ReadOnly
|
2
|
+
include_set Abstract::Sources
|
3
|
+
include_set Abstract::Items
|
4
|
+
|
5
|
+
def virtual?
|
6
|
+
new?
|
7
|
+
end
|
8
|
+
|
9
|
+
def render_items_and_compress format
|
10
|
+
item_cards.compact.map do |mcard|
|
11
|
+
mcard.format(format)._render_compressed
|
12
|
+
end.join "\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
def item_cards _args={}
|
16
|
+
relative_paths.map do |path|
|
17
|
+
new_asset_file_card path
|
18
|
+
end.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_asset_file_card path, name=::File.basename(path)
|
22
|
+
return unless (constants = new_asset_constants path)
|
23
|
+
asset_card = Card.new(name: name, type_id: constants[:type_id], content: path)
|
24
|
+
asset_card.include_set_module constants[:set_module]
|
25
|
+
asset_card.minimize if @minimize
|
26
|
+
asset_card.local if @local
|
27
|
+
asset_card.base_path = base_path
|
28
|
+
asset_card.files_must_exist!
|
29
|
+
asset_card
|
30
|
+
end
|
31
|
+
|
32
|
+
def source_paths
|
33
|
+
paths
|
34
|
+
end
|
35
|
+
|
36
|
+
def local
|
37
|
+
@local = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def source_changed? since:
|
41
|
+
existing_source_paths.any? { |path| ::File.mtime(path) > since }
|
42
|
+
end
|
43
|
+
|
44
|
+
def input_item_cards
|
45
|
+
item_cards # we create virtual cards for manifest groups, hence we have
|
46
|
+
# to override the default which rejects virtual cards.
|
47
|
+
end
|
48
|
+
|
49
|
+
def asset_input_needs_refresh?
|
50
|
+
!asset_input_updated_at || source_changed?(since: asset_input_updated_at)
|
51
|
+
end
|
52
|
+
|
53
|
+
def last_file_change
|
54
|
+
paths.map { |path| ::File.mtime(path) }.max
|
55
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
card_accessor :asset_input, type_id: Card::PlainTextID
|
2
|
+
|
3
|
+
def dependent_asset_inputters
|
4
|
+
referers_responding_to :asset_input
|
5
|
+
end
|
6
|
+
|
7
|
+
def outputters
|
8
|
+
referers_responding_to :update_asset_output
|
9
|
+
end
|
10
|
+
|
11
|
+
def referers_responding_to method_name
|
12
|
+
referers.select { |referer| referer.respond_to? method_name }
|
13
|
+
end
|
14
|
+
|
15
|
+
event :asset_input_changed, :finalize, on: :save do
|
16
|
+
update_asset_input
|
17
|
+
end
|
18
|
+
|
19
|
+
event :asset_input_changed_on_delete, :finalize, on: :delete, before: :clear_references do
|
20
|
+
update_referers_after_input_changed
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_referers_after_input_changed
|
24
|
+
# puts "dependent inputters for #{name}: #{dependent_asset_inputters}"
|
25
|
+
# puts "outputters: #{outputters}"
|
26
|
+
|
27
|
+
dependent_asset_inputters.each(&:update_asset_input)
|
28
|
+
outputters.each(&:update_asset_output)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_asset_input
|
32
|
+
return unless Codename.exists? :asset_input
|
33
|
+
# otherwise the migration that adds the asset_input card fails
|
34
|
+
|
35
|
+
Card::Auth.as_bot do
|
36
|
+
asset_input_card.update content: render_asset_input_content
|
37
|
+
update_referers_after_input_changed
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def asset_input_content
|
42
|
+
return render_asset_input_content if virtual?
|
43
|
+
update_asset_input if asset_input.blank?
|
44
|
+
asset_input
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_asset_input_content
|
48
|
+
format(input_format).render(input_view)
|
49
|
+
end
|
50
|
+
|
51
|
+
def input_view
|
52
|
+
:core
|
53
|
+
end
|
54
|
+
|
55
|
+
def asset_input_updated_at
|
56
|
+
asset_input_card&.updated_at
|
57
|
+
end
|
58
|
+
|
59
|
+
def refresh_asset
|
60
|
+
update_asset_input if asset_input_needs_refresh?
|
61
|
+
end
|
62
|
+
|
63
|
+
def asset_input_needs_refresh?
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
format :html do
|
68
|
+
def edit_success
|
69
|
+
{ reload: true }
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
include_set Abstract::Lock
|
2
|
+
|
3
|
+
card_accessor :asset_output, type: :file
|
4
|
+
|
5
|
+
def output_filetype
|
6
|
+
output_format
|
7
|
+
end
|
8
|
+
|
9
|
+
event :update_asset_output_file, :finalize, on: :save do
|
10
|
+
update_asset_output
|
11
|
+
end
|
12
|
+
|
13
|
+
event :validate_asset_inputs, :validate, on: :save, skip: :allowed do
|
14
|
+
return unless (invalid_input = find_invalid_input)
|
15
|
+
|
16
|
+
errors.add :content, t(:assets_invalid_input, input_name: invalid_input.name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_invalid_input
|
20
|
+
item_cards.find { |c| !c.respond_to?(:asset_input_content) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_asset_output
|
24
|
+
# puts "update_asset_output called: #{name}"
|
25
|
+
lock do
|
26
|
+
store_output input_from_item_cards
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_asset_output_live
|
31
|
+
update_asset_output
|
32
|
+
card_path asset_output_url
|
33
|
+
end
|
34
|
+
|
35
|
+
def input_from_item_cards joint="\n"
|
36
|
+
input_item_cards.map(&:asset_input_content).compact.join(joint)
|
37
|
+
end
|
38
|
+
|
39
|
+
def store_output output
|
40
|
+
handle_file(output) do |file|
|
41
|
+
Card::Auth.as_bot do
|
42
|
+
# FIXME: this is definitely not how we want to do this.
|
43
|
+
# problem is that file object is getting stashed in set_specific attributes,
|
44
|
+
# and then reassigned later. This causes problems in cases where a single
|
45
|
+
# card (eg *all+*style) is updated by multiple inputters, because the old file arg
|
46
|
+
# sticks around in the set specific stash and then reemerges after it's been
|
47
|
+
# unlinked. we need a more general solution
|
48
|
+
# (error reproducible eg when running card:mod:install on wikirate)
|
49
|
+
aoc = asset_output_card
|
50
|
+
aoc.update file: file
|
51
|
+
aoc.set_specific.delete :file
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_file output
|
57
|
+
file = Tempfile.new [id.to_s, ".#{output_filetype}"]
|
58
|
+
file.write output
|
59
|
+
file.close
|
60
|
+
yield file
|
61
|
+
file.unlink
|
62
|
+
end
|
63
|
+
|
64
|
+
view :asset_output_url do
|
65
|
+
asset_output_url
|
66
|
+
end
|
67
|
+
|
68
|
+
def make_asset_output_coded mod
|
69
|
+
mod ||= :assets
|
70
|
+
Card::Auth.as_bot do
|
71
|
+
ENV["STORE_CODED_FILES"] = "true"
|
72
|
+
asset_output_card.update! storage_type: :coded, mod: mod,
|
73
|
+
codename: asset_output_codename
|
74
|
+
ENV["STORE_CODED_FILES"] = nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def asset_output_codename
|
79
|
+
asset_output_card.name.parts.map do |part|
|
80
|
+
Card[part].codename&.to_s || Card[part].name.safe_key
|
81
|
+
end.join "_"
|
82
|
+
end
|
83
|
+
|
84
|
+
def input_item_cards
|
85
|
+
item_cards(known_only: true).compact.reject(&:trash)
|
86
|
+
end
|
87
|
+
|
88
|
+
def asset_output_url
|
89
|
+
# ensure_asset_output
|
90
|
+
asset_output_card.file&.url # (:default, timestamp: false)
|
91
|
+
# to get rid of additional number in url
|
92
|
+
end
|
93
|
+
|
94
|
+
def asset_output_path
|
95
|
+
# ensure_asset_output
|
96
|
+
asset_output_card.file&.path
|
97
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
attr_accessor :assets_path
|
2
|
+
attr_accessor :group_name
|
3
|
+
|
4
|
+
def paths
|
5
|
+
return [] unless (path = assets_path)
|
6
|
+
|
7
|
+
relative_paths.map { |child| ::File.join path, child }
|
8
|
+
end
|
9
|
+
|
10
|
+
def relative_paths
|
11
|
+
return [] unless (path = assets_path)
|
12
|
+
|
13
|
+
Dir.chdir(path) { Dir.glob(search_path).sort }
|
14
|
+
end
|
15
|
+
|
16
|
+
def search_path
|
17
|
+
File.join "**", "*.{#{valid_file_extensions.join(',')}}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def base_path
|
21
|
+
assets_path
|
22
|
+
end
|
23
|
+
|
24
|
+
def minimize?
|
25
|
+
@minimize = true
|
26
|
+
end
|
data/set/abstract/mod_assets.rb
CHANGED
@@ -1,76 +1,78 @@
|
|
1
1
|
include_set Abstract::Pointer
|
2
|
+
include_set Abstract::ReadOnly
|
2
3
|
|
3
|
-
def
|
4
|
-
|
4
|
+
def item_cards _args={}
|
5
|
+
local_group_cards
|
5
6
|
end
|
6
7
|
|
7
|
-
def
|
8
|
-
|
8
|
+
def item_names _args={}
|
9
|
+
local_group_cards.map(&:name)
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# group cards that don't refer to remote sources
|
13
|
+
def local_group_cards
|
14
|
+
@local_group_cards ||=
|
15
|
+
if manifest_exists?
|
16
|
+
local_manifest_group_cards
|
17
|
+
else
|
18
|
+
[folder_group_card].compact
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
|
-
def
|
22
|
+
def folder_group_card
|
18
23
|
return unless assets_path
|
19
|
-
|
20
|
-
|
24
|
+
card = new_assets_group_card local_group_name, folder_group_type_id
|
25
|
+
card.assets_path = assets_path
|
26
|
+
card
|
21
27
|
end
|
22
28
|
|
23
|
-
def
|
24
|
-
|
29
|
+
def local_manifest_group_cards
|
30
|
+
manifest.map do |group_name, config|
|
31
|
+
next if remote_group?(group_name, config)
|
32
|
+
new_local_manifest_group_card group_name
|
33
|
+
end.compact
|
34
|
+
end
|
25
35
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
["#{name}+#{local_group_name}".to_name.key]
|
30
|
-
end
|
36
|
+
def remote_group_urls
|
37
|
+
return unless manifest_exists?
|
38
|
+
manifest_group_items "remote"
|
31
39
|
end
|
32
40
|
|
33
|
-
def
|
34
|
-
|
41
|
+
def content?
|
42
|
+
assets_path
|
35
43
|
end
|
36
44
|
|
37
|
-
def
|
38
|
-
|
45
|
+
def mod_name
|
46
|
+
left&.codename.to_s.sub(/^mod_/, "")
|
47
|
+
end
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
|
49
|
+
def mod
|
50
|
+
@mod ||= Cardio::Mod.fetch mod_name
|
51
|
+
end
|
43
52
|
|
44
|
-
|
45
|
-
|
46
|
-
|
53
|
+
def manifest_exists?
|
54
|
+
@manifest_exists = !manifest_path.nil? if @manifest_exists.nil?
|
55
|
+
@manifest_exists
|
47
56
|
end
|
48
57
|
|
49
|
-
def
|
50
|
-
|
51
|
-
ensure_manifest_groups_cards
|
52
|
-
else
|
53
|
-
ensure_item local_group_name, local_folder_group_type_id
|
54
|
-
end
|
58
|
+
def assets_path
|
59
|
+
@assets_path ||= mod&.subpath "assets", subpath
|
55
60
|
end
|
56
61
|
|
57
|
-
def
|
58
|
-
@
|
59
|
-
yield
|
60
|
-
remove_deprecated_items @old_items
|
62
|
+
def manifest_path
|
63
|
+
@manifest_path ||= mod&.subpath "assets", subpath, "manifest.yml"
|
61
64
|
end
|
62
65
|
|
63
|
-
def
|
64
|
-
|
65
|
-
path && Dir.exist?(path)
|
66
|
+
def local_group_name
|
67
|
+
"local"
|
66
68
|
end
|
67
69
|
|
68
|
-
def
|
69
|
-
|
70
|
+
def remote_group? name, _config
|
71
|
+
name == "remote" # || config["remote"]
|
70
72
|
end
|
71
73
|
|
72
74
|
def manifest_group_items group_name
|
73
|
-
manifest
|
75
|
+
manifest&.dig(group_name, "items") || []
|
74
76
|
end
|
75
77
|
|
76
78
|
def manifest_group_minimize? group_name
|
@@ -78,93 +80,76 @@ def manifest_group_minimize? group_name
|
|
78
80
|
end
|
79
81
|
|
80
82
|
def manifest
|
81
|
-
@manifest ||=
|
83
|
+
@manifest ||= load_manifest
|
82
84
|
end
|
83
85
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
def load_manifest
|
87
|
+
return unless manifest_exists?
|
88
|
+
manifest = YAML.load_file manifest_path
|
89
|
+
validate_manifest manifest
|
90
|
+
manifest
|
88
91
|
end
|
89
92
|
|
90
|
-
def
|
91
|
-
|
93
|
+
def validate_manifest manifest
|
94
|
+
if (remote_index = manifest.keys.find_index("remote")) && remote_index.positive?
|
95
|
+
raise_manifest_error "only the first group can be a remote group"
|
96
|
+
end
|
97
|
+
manifest.each do |name, config|
|
98
|
+
validate_manifest_item name, config
|
99
|
+
end
|
92
100
|
end
|
93
101
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
102
|
+
def group_card_args field, type_id, name
|
103
|
+
{
|
104
|
+
type_id: type_id,
|
105
|
+
codename: "#{mod_name}_group__#{field}",
|
106
|
+
name: name
|
107
|
+
}
|
98
108
|
end
|
99
109
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
110
|
+
def source_changed? since:
|
111
|
+
source_updates =
|
112
|
+
if manifest_exists?
|
113
|
+
[manifest_updated_at, local_manifest_group_cards.map(&:last_file_change)].flatten
|
114
|
+
else
|
115
|
+
folder_group_card&.paths&.map { |path| File.mtime(path) }
|
116
|
+
end
|
103
117
|
|
104
|
-
|
105
|
-
args = ensure_item_args field, type_id, item_name
|
106
|
-
return if item_already_coded? card, args
|
118
|
+
return unless source_updates.present?
|
107
119
|
|
108
|
-
|
109
|
-
card.try :update_machine_output
|
120
|
+
source_updates.max > since
|
110
121
|
end
|
111
122
|
|
112
|
-
def
|
113
|
-
|
123
|
+
def manifest_updated_at
|
124
|
+
return unless manifest_exists?
|
125
|
+
File.mtime(manifest_path)
|
114
126
|
end
|
115
127
|
|
116
|
-
def
|
117
|
-
|
118
|
-
add_item item_name
|
128
|
+
def no_action?
|
129
|
+
new? && !assets_path
|
119
130
|
end
|
120
131
|
|
121
|
-
|
122
|
-
if card
|
123
|
-
card.update args
|
124
|
-
else
|
125
|
-
Card.create! args
|
126
|
-
end
|
127
|
-
end
|
132
|
+
private
|
128
133
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
name: name
|
134
|
-
}
|
134
|
+
def new_local_manifest_group_card group_name
|
135
|
+
card = new_assets_group_card group_name, local_manifest_group_type_id
|
136
|
+
card.group_name = group_name
|
137
|
+
card
|
135
138
|
end
|
136
139
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
140
|
+
def new_assets_group_card group_name, type_id
|
141
|
+
item_name = "#{name}+group: #{group_name}"
|
142
|
+
card = Card.new group_card_args(group_name, type_id, item_name)
|
143
|
+
card
|
142
144
|
end
|
143
145
|
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
item_card.try(:make_machine_output_coded, mod_name)
|
148
|
-
end
|
149
|
-
end
|
146
|
+
def validate_manifest_item name, config
|
147
|
+
raise_manifest_error "no items section in group \"#{name}\"" unless config["items"]
|
148
|
+
return if config["items"].is_a? Array
|
150
149
|
|
151
|
-
|
152
|
-
new? && !assets_dir_exists?
|
150
|
+
raise_manifest_error "items section \"#{name}\" must contain a list"
|
153
151
|
end
|
154
152
|
|
155
|
-
|
156
|
-
|
157
|
-
# def groups_changed?
|
158
|
-
# expected_items = expected_item_keys
|
159
|
-
# actual_items = item_keys
|
160
|
-
# difference = (expected_items + actual_items) - (expected_items & actual_items)
|
161
|
-
# difference.present?
|
162
|
-
# end
|
163
|
-
|
164
|
-
def remove_deprecated_items items
|
165
|
-
items.each do |deprecated_item|
|
166
|
-
next unless (item_card = Card.fetch(deprecated_item))
|
167
|
-
item_card.update codename: nil
|
168
|
-
item_card.delete
|
169
|
-
end
|
153
|
+
def raise_manifest_error msg
|
154
|
+
raise Card::Error, "invalid manifest format in #{manifest_path}: #{msg}"
|
170
155
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
def followable?
|
2
|
+
false
|
3
|
+
end
|
4
|
+
|
5
|
+
def ok_to_read
|
6
|
+
left.ok_to_read
|
7
|
+
end
|
8
|
+
|
9
|
+
def history?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
event :remove_codename, :prepare_to_validate,
|
14
|
+
on: :delete,
|
15
|
+
when: proc { |c| c.codename.present? } do
|
16
|
+
# load file before deleting codename otherwise it will fail later
|
17
|
+
attachment
|
18
|
+
self.codename = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
format do
|
22
|
+
def outputter
|
23
|
+
left
|
24
|
+
end
|
25
|
+
|
26
|
+
view :not_found do
|
27
|
+
return super() unless update_asset_output_live?
|
28
|
+
|
29
|
+
root.error_status = 302
|
30
|
+
outputter.update_asset_output_live
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_asset_output_live?
|
34
|
+
outputter.is_a?(Abstract::AssetOutputter) && !outputter.locked?
|
35
|
+
end
|
36
|
+
end
|
data/set/type/mod.rb
CHANGED
@@ -1,52 +1,64 @@
|
|
1
|
+
# TODO: We can't detect file removal for folder group
|
2
|
+
|
3
|
+
include_set List
|
4
|
+
|
5
|
+
def modname
|
6
|
+
codename.to_s.gsub(/^mod_/, "")
|
7
|
+
end
|
8
|
+
|
1
9
|
def ensure_mod_script_card
|
2
|
-
ensure_mod_asset_card :script
|
10
|
+
ensure_mod_asset_card :script
|
3
11
|
end
|
4
12
|
|
5
13
|
def ensure_mod_style_card
|
6
|
-
ensure_mod_asset_card :style
|
14
|
+
ensure_mod_asset_card :style
|
7
15
|
end
|
8
16
|
|
9
17
|
private
|
10
18
|
|
11
|
-
def ensure_mod_asset_card asset_type
|
12
|
-
asset_card = fetch_mod_assets_card asset_type
|
19
|
+
def ensure_mod_asset_card asset_type
|
20
|
+
asset_card = fetch_mod_assets_card asset_type
|
13
21
|
return if asset_card.no_action?
|
14
|
-
asset_card.save! if asset_card.new?
|
22
|
+
asset_card.save! if asset_card.new? || asset_card.codename.blank?
|
15
23
|
|
16
|
-
asset_card.
|
17
|
-
|
18
|
-
|
24
|
+
if asset_card.content?
|
25
|
+
add_mod_asset_card asset_type
|
26
|
+
asset_card.refresh_asset
|
19
27
|
else
|
20
|
-
|
28
|
+
puts "Drop: #{asset_card.name}"
|
29
|
+
drop_mod_asset_card asset_type, asset_card
|
21
30
|
end
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
25
|
-
|
33
|
+
def add_mod_asset_card asset_type
|
34
|
+
target = asset_type == :style ? Card[:style_mods] : all_rule(asset_type)
|
35
|
+
target.add_item! codename_for(asset_type)
|
26
36
|
end
|
27
37
|
|
28
|
-
def
|
38
|
+
def drop_mod_asset_card asset_type, asset_card
|
29
39
|
asset_card.update codename: nil
|
30
|
-
asset_card.delete
|
40
|
+
asset_card.delete
|
31
41
|
all_rule(asset_type).drop_item! asset_card
|
32
42
|
end
|
33
43
|
|
34
44
|
def codename_for asset_type
|
35
|
-
|
45
|
+
[codename, asset_type]
|
36
46
|
end
|
37
47
|
|
38
48
|
def all_rule asset_type
|
39
49
|
Card[:all, asset_type]
|
40
50
|
end
|
41
51
|
|
42
|
-
def fetch_mod_assets_card asset_type
|
52
|
+
def fetch_mod_assets_card asset_type
|
43
53
|
codename = codename_for asset_type
|
44
54
|
if Card::Codename.exists? codename
|
45
55
|
Card[codename.to_sym]
|
46
56
|
else
|
47
|
-
Card.fetch [name, asset_type], new: {
|
48
|
-
type_id:
|
49
|
-
codename: codename
|
57
|
+
card = Card.fetch [name, asset_type], new: {
|
58
|
+
type_id: Card::ListID, codename: codename
|
50
59
|
}
|
60
|
+
card.codename = codename
|
61
|
+
card.type_id = Card::ListID
|
62
|
+
card
|
51
63
|
end
|
52
64
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: card-mod-assets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan McCutchen
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-01-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: card
|
@@ -18,42 +18,104 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: 1.104.1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 1.
|
28
|
+
version: 1.104.1
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: execjs
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - "~>"
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '2.7'
|
36
|
+
- - "!="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 2.8.0
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - "~>"
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.7'
|
46
|
+
- - "!="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 2.8.0
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: card-mod-virtual
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.14.1
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.14.1
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: card-mod-format
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.14.1
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.14.1
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: card-mod-list
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.14.1
|
84
|
+
type: :runtime
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.14.1
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: card-mod-carrierwave
|
31
93
|
requirement: !ruby/object:Gem::Requirement
|
32
94
|
requirements:
|
33
95
|
- - '='
|
34
96
|
- !ruby/object:Gem::Version
|
35
|
-
version: 0.
|
97
|
+
version: 0.14.1
|
36
98
|
type: :runtime
|
37
99
|
prerelease: false
|
38
100
|
version_requirements: !ruby/object:Gem::Requirement
|
39
101
|
requirements:
|
40
102
|
- - '='
|
41
103
|
- !ruby/object:Gem::Version
|
42
|
-
version: 0.
|
104
|
+
version: 0.14.1
|
43
105
|
- !ruby/object:Gem::Dependency
|
44
106
|
name: card-mod-content
|
45
107
|
requirement: !ruby/object:Gem::Requirement
|
46
108
|
requirements:
|
47
109
|
- - '='
|
48
110
|
- !ruby/object:Gem::Version
|
49
|
-
version: 0.
|
111
|
+
version: 0.14.1
|
50
112
|
type: :runtime
|
51
113
|
prerelease: false
|
52
114
|
version_requirements: !ruby/object:Gem::Requirement
|
53
115
|
requirements:
|
54
116
|
- - '='
|
55
117
|
- !ruby/object:Gem::Version
|
56
|
-
version: 0.
|
118
|
+
version: 0.14.1
|
57
119
|
description: ''
|
58
120
|
email:
|
59
121
|
- info@decko.org
|
@@ -62,12 +124,20 @@ extensions: []
|
|
62
124
|
extra_rdoc_files: []
|
63
125
|
files:
|
64
126
|
- db/migrate_core_cards/20200806112346_add_mod_type.rb
|
127
|
+
- db/migrate_core_cards/202108028112352_death_to_machines.rb
|
128
|
+
- lib/card/assets.rb
|
129
|
+
- locales/de.yml
|
130
|
+
- locales/en.yml
|
65
131
|
- set/abstract/01_manifest_group.rb
|
66
132
|
- set/abstract/asset_file.rb
|
67
|
-
- set/abstract/
|
68
|
-
- set/abstract/
|
133
|
+
- set/abstract/asset_group.rb
|
134
|
+
- set/abstract/asset_inputter.rb
|
135
|
+
- set/abstract/asset_outputter.rb
|
136
|
+
- set/abstract/folder_group.rb
|
69
137
|
- set/abstract/local_manifest_group.rb
|
70
138
|
- set/abstract/mod_assets.rb
|
139
|
+
- set/right/asset_input.rb
|
140
|
+
- set/right/asset_output.rb
|
71
141
|
- set/type/mod.rb
|
72
142
|
- set/type/remote_manifest_group.rb
|
73
143
|
homepage: https://decko.org
|
@@ -95,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
165
|
- !ruby/object:Gem::Version
|
96
166
|
version: '0'
|
97
167
|
requirements: []
|
98
|
-
rubygems_version: 3.
|
168
|
+
rubygems_version: 3.2.15
|
99
169
|
signing_key:
|
100
170
|
specification_version: 4
|
101
171
|
summary: decko asset pipeline
|
data/set/abstract/asset_list.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
include_set Abstract::ReadOnly
|
2
|
-
include_set Abstract::Sources
|
3
|
-
include_set Abstract::Items
|
4
|
-
|
5
|
-
def refresh_output force: false
|
6
|
-
update_items! if refresh_output? || force
|
7
|
-
end
|
8
|
-
|
9
|
-
def refresh_output?
|
10
|
-
!output_updated_at || source_changed?(since: output_updated_at)
|
11
|
-
end
|
12
|
-
|
13
|
-
event :update_asset_list, :prepare_to_store, on: :save do
|
14
|
-
self.db_content = relative_paths.join("\n")
|
15
|
-
end
|
16
|
-
|
17
|
-
def render_items_and_compress format
|
18
|
-
item_cards.map do |mcard|
|
19
|
-
js = mcard.format(format)._render_core
|
20
|
-
js = mcard.compress js if minimize?
|
21
|
-
"// #{mcard.name}\n#{js}"
|
22
|
-
end.join "\n"
|
23
|
-
end
|
24
|
-
|
25
|
-
def update_items!
|
26
|
-
Card::Auth.as_bot do
|
27
|
-
save!
|
28
|
-
end
|
29
|
-
regenerate_machine_output
|
30
|
-
end
|
31
|
-
|
32
|
-
def item_name_to_path name
|
33
|
-
name
|
34
|
-
end
|
35
|
-
|
36
|
-
def fetch_item_card name, _args={}
|
37
|
-
new_asset_file_card item_name_to_path(name)
|
38
|
-
end
|
39
|
-
|
40
|
-
def new_asset_file_card path, name=::File.basename(path)
|
41
|
-
return unless (constants = new_asset_constants path)
|
42
|
-
asset_card = Card.new(name: name, type_id: constants[:type_id], content: path)
|
43
|
-
asset_card.include_set_module constants[:set_module]
|
44
|
-
asset_card.minimize if @minimize
|
45
|
-
asset_card.local if @local
|
46
|
-
asset_card.base_path = base_path
|
47
|
-
asset_card
|
48
|
-
end
|
49
|
-
|
50
|
-
def source_paths
|
51
|
-
paths
|
52
|
-
end
|
53
|
-
|
54
|
-
def self_machine_input?
|
55
|
-
true
|
56
|
-
end
|
57
|
-
|
58
|
-
def local
|
59
|
-
@local = true
|
60
|
-
end
|
61
|
-
|
62
|
-
def source_changed? since:
|
63
|
-
difference = (relative_paths + item_names) - (relative_paths & item_names)
|
64
|
-
difference.present? ||
|
65
|
-
existing_source_paths.any? { |path| ::File.mtime(path) > since }
|
66
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
def paths
|
2
|
-
return [] unless (path = left&.assets_path)
|
3
|
-
|
4
|
-
relative_paths.map { |child| ::File.join path, child }
|
5
|
-
end
|
6
|
-
|
7
|
-
def relative_paths
|
8
|
-
return [] unless (path = left&.assets_path)
|
9
|
-
|
10
|
-
Dir.children path
|
11
|
-
end
|
12
|
-
|
13
|
-
def item_name_to_path name
|
14
|
-
::File.join base_path, name
|
15
|
-
end
|
16
|
-
|
17
|
-
def base_path
|
18
|
-
left&.assets_path
|
19
|
-
end
|
20
|
-
|
21
|
-
def minimize?
|
22
|
-
@minimize = true
|
23
|
-
end
|