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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4af4f96a0da58c51e6f6c7d3e70be0452119fda480bc5cb6c019fc41a911e8ea
4
- data.tar.gz: 03e3391bc8fc42d21b184336e88777931ff8b5165b63eb049006a33aacec9df4
3
+ metadata.gz: 9ce85a0a2a52676f5a29ea74def8271c272b2c7e15cb3f55acb7c219b14e6fc3
4
+ data.tar.gz: 3e8af9aec31f45db69f0520a655569174581412cfe892350b4d407bcc3c16d70
5
5
  SHA512:
6
- metadata.gz: a702cb144753e92805dd1934ba78e9bba46873ecab74cb688f9777ba8966fbae3f03e2aab8bf479802be6b88d26418aa9b57755083e83eecdbbc3b5998946043
7
- data.tar.gz: e48febba67e5baf94113086272d8a86a5fdc7e7fb5ea6f6532bec9abf27e017453a181a45cc3e222f577e01cdfa1125936e395f74cd3c079ad1eda3e30ab82fb
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
@@ -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
@@ -0,0 +1,2 @@
1
+ en:
2
+ assets_invalid_input: "%{input_name} ist keine gültige Asset-Eingabekarte"
data/locales/en.yml ADDED
@@ -0,0 +1,2 @@
1
+ en:
2
+ assets_invalid_input: "%{input_name} is not a valid asset input card"
@@ -1,10 +1,4 @@
1
- def group_name
2
- codename.to_s.sub(/^.+__/, "")
3
- end
4
-
5
- def relative_paths
6
- paths
7
- end
1
+ attr_accessor :group_name
8
2
 
9
3
  format :html do
10
4
  view :core do
@@ -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
@@ -1,76 +1,78 @@
1
1
  include_set Abstract::Pointer
2
+ include_set Abstract::ReadOnly
2
3
 
3
- def mod_name
4
- left&.codename.to_s.sub(/^mod_/, "")
4
+ def item_cards _args={}
5
+ local_group_cards
5
6
  end
6
7
 
7
- def mod
8
- @mod ||= Cardio::Mod.dirs.fetch_mod(mod_name)
8
+ def item_names _args={}
9
+ local_group_cards.map(&:name)
9
10
  end
10
11
 
11
- def assets_path
12
- return unless mod&.assets_path.present?
13
-
14
- File.join mod&.assets_path, subpath
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 manifest_path
22
+ def folder_group_card
18
23
  return unless assets_path
19
-
20
- File.join(assets_path, "manifest.yml")
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 expected_item_keys
24
- return [] unless assets_dir_exists?
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
- if manifest_exists?
27
- manifest.keys.map { |group_key| "#{name}+#{group_key}".to_name.key }
28
- else
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 local_group_name
34
- "local"
41
+ def content?
42
+ assets_path
35
43
  end
36
44
 
37
- def update_items
38
- # return unless groups_changed?
45
+ def mod_name
46
+ left&.codename.to_s.sub(/^mod_/, "")
47
+ end
39
48
 
40
- delete_unused_items do
41
- self.content = ""
42
- return unless assets_dir_exists?
49
+ def mod
50
+ @mod ||= Cardio::Mod.fetch mod_name
51
+ end
43
52
 
44
- ensure_update_items
45
- save!
46
- end
53
+ def manifest_exists?
54
+ @manifest_exists = !manifest_path.nil? if @manifest_exists.nil?
55
+ @manifest_exists
47
56
  end
48
57
 
49
- def ensure_update_items
50
- if manifest_exists?
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 delete_unused_items
58
- @old_items = ::Set.new item_keys
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 assets_dir_exists?
64
- path = assets_path
65
- path && Dir.exist?(path)
66
+ def local_group_name
67
+ "local"
66
68
  end
67
69
 
68
- def manifest_exists?
69
- manifest_path && File.exist?(manifest_path)
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.dig(group_name, "items") || []
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 ||= YAML.load_file manifest_path
83
+ @manifest ||= load_manifest
82
84
  end
83
85
 
84
- def with_manifest_groups
85
- manifest.each_pair do |key, config|
86
- yield key, config
87
- end
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 ensure_manifest_groups_cards
91
- with_manifest_groups { |group_name, config| new_manifest_group group_name, config }
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 new_manifest_group group_name, config
95
- type_id =
96
- config["remote"] ? ::Card::RemoteManifestGroupID : local_manifest_group_type_id
97
- ensure_item group_name, type_id
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 ensure_item field, type_id
101
- item_name = "#{name}+#{field}"
102
- ensure_item_content item_name
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
- card = Card[item_name]
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
- ensure_item_save card, args
109
- card.try :update_machine_output
120
+ source_updates.max > since
110
121
  end
111
122
 
112
- def item_already_coded? card, args
113
- card&.type_id == args[:type_id] && card.codename == args[:codename]
123
+ def manifest_updated_at
124
+ return unless manifest_exists?
125
+ File.mtime(manifest_path)
114
126
  end
115
127
 
116
- def ensure_item_content item_name
117
- @old_items.delete item_name.to_name.key
118
- add_item item_name
128
+ def no_action?
129
+ new? && !assets_path
119
130
  end
120
131
 
121
- def ensure_item_save card, args
122
- if card
123
- card.update args
124
- else
125
- Card.create! args
126
- end
127
- end
132
+ private
128
133
 
129
- def ensure_item_args field, type_id, name
130
- {
131
- type_id: type_id,
132
- codename: "#{mod_name}_group__#{field}",
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 refresh_output force: false
138
- update_items
139
- item_cards.each do |item_card|
140
- item_card.try :refresh_output, force: force
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 make_machine_output_coded verbose=false
145
- item_cards.each do |item_card|
146
- puts "coding machine output for #{item_card.name}" if verbose
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
- def no_action?
152
- new? && !assets_dir_exists?
150
+ raise_manifest_error "items section \"#{name}\" must contain a list"
153
151
  end
154
152
 
155
- private
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,17 @@
1
+ include_set Abstract::VirtualCache
2
+
3
+ def virtual_content
4
+ left.render_asset_input_content
5
+ end
6
+
7
+ def history?
8
+ false
9
+ end
10
+
11
+ def followable?
12
+ false
13
+ end
14
+
15
+ def chunk_list
16
+ :none
17
+ 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, Card::ModScriptAssetsID
10
+ ensure_mod_asset_card :script
3
11
  end
4
12
 
5
13
  def ensure_mod_style_card
6
- ensure_mod_asset_card :style, Card::ModStyleAssetsID
14
+ ensure_mod_asset_card :style
7
15
  end
8
16
 
9
17
  private
10
18
 
11
- def ensure_mod_asset_card asset_type, type_id
12
- asset_card = fetch_mod_assets_card asset_type, type_id
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.update_items
17
- if asset_card.item_cards.present?
18
- add_asset asset_type
24
+ if asset_card.content?
25
+ add_mod_asset_card asset_type
26
+ asset_card.refresh_asset
19
27
  else
20
- drop_asset asset_type, asset_card
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 add_asset asset_type
25
- all_rule(asset_type).add_item! codename_for(asset_type).to_sym
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 drop_asset asset_type, asset_card
38
+ def drop_mod_asset_card asset_type, asset_card
29
39
  asset_card.update codename: nil
30
- asset_card.delete update_referers: true
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
- "#{codename}_#{asset_type}"
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, type_id
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: 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.13.2
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: 2021-08-06 00:00:00.000000000 Z
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.103.2
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.103.2
28
+ version: 1.104.1
29
29
  - !ruby/object:Gem::Dependency
30
- name: card-mod-machines
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.13.2
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.13.2
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.13.2
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.13.2
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/asset_list.rb
68
- - set/abstract/local_folder_group.rb
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.1.6
168
+ rubygems_version: 3.2.15
99
169
  signing_key:
100
170
  specification_version: 4
101
171
  summary: decko asset pipeline
@@ -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