card-mod-assets 0.13.4 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 -21
- 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: 7f9d0e127bf79045726a27dbaf66a286139002334fe4c033cd19623fc9cb8f03
|
4
|
+
data.tar.gz: 6a1f2cfe3e848187feafb484b072b5a0f2a14115159398356e50a6484db3873a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f5f0481e3982d3683c952143f7f6a6e7250d0aa551792599e553ee319f22bdd03626b1f9153212651eeb3c4f332ec1e332689d43a0a2468f5d6504165ff4abb
|
7
|
+
data.tar.gz: 74796a14ede06d0b95ff3039733deb57a2d96a80ddcc1272160a4060c2b8bd490f2913b28a4cde33aa602bd11daea8ad2a3aceaf2ca4ba7024e2e36a82e05775
|
@@ -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,55 +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?
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
asset_card.update_items
|
20
|
-
if asset_card.item_cards.present?
|
21
|
-
add_asset asset_type
|
22
|
+
asset_card.save! if asset_card.new? || asset_card.codename.blank?
|
23
|
+
|
24
|
+
if asset_card.content?
|
25
|
+
add_mod_asset_card asset_type
|
26
|
+
asset_card.refresh_asset
|
22
27
|
else
|
23
|
-
|
28
|
+
puts "Drop: #{asset_card.name}"
|
29
|
+
drop_mod_asset_card asset_type, asset_card
|
24
30
|
end
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
|
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)
|
29
36
|
end
|
30
37
|
|
31
|
-
def
|
38
|
+
def drop_mod_asset_card asset_type, asset_card
|
32
39
|
asset_card.update codename: nil
|
33
40
|
asset_card.delete
|
34
41
|
all_rule(asset_type).drop_item! asset_card
|
35
42
|
end
|
36
43
|
|
37
44
|
def codename_for asset_type
|
38
|
-
|
45
|
+
[codename, asset_type]
|
39
46
|
end
|
40
47
|
|
41
48
|
def all_rule asset_type
|
42
49
|
Card[:all, asset_type]
|
43
50
|
end
|
44
51
|
|
45
|
-
def fetch_mod_assets_card asset_type
|
52
|
+
def fetch_mod_assets_card asset_type
|
46
53
|
codename = codename_for asset_type
|
47
54
|
if Card::Codename.exists? codename
|
48
55
|
Card[codename.to_sym]
|
49
56
|
else
|
50
|
-
Card.fetch [name, asset_type], new: {
|
51
|
-
type_id:
|
52
|
-
codename: codename
|
57
|
+
card = Card.fetch [name, asset_type], new: {
|
58
|
+
type_id: Card::ListID, codename: codename
|
53
59
|
}
|
60
|
+
card.codename = codename
|
61
|
+
card.type_id = Card::ListID
|
62
|
+
card
|
54
63
|
end
|
55
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.0
|
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: 2021-
|
13
|
+
date: 2021-12-22 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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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.0
|
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
|