mirror of
https://github.com/manyfold3d/manyfold.git
synced 2026-10-22 03:32:18 -05:00
Support multiple collections in path parsing
This commit is contained in:
6 files changed
+40
-21
No files matched your search
@@ -27,7 +27,7 @@ class Components::PathTemplatePreview < Components::Base
|
||||
tr do
|
||||
td(style: "word-break: break-all") { path }
|
||||
td { find_or_new_from_path_component(Creator, parsed[:creator])&.name || "❌" }
|
||||
td { find_or_new_from_path_component(Collection, parsed[:collection])&.name || "❌" }
|
||||
td { parsed[:collections] ? Array(find_or_new_from_path_component(Collection, parsed[:collections])).map(&:name).join(", ") : "❌" }
|
||||
td {
|
||||
parsed[:tags]&.map do |it|
|
||||
Tag tag: ActsAsTaggableOn::Tag.new(name: it), link: false
|
||||
@@ -46,11 +46,15 @@ class Components::PathTemplatePreview < Components::Base
|
||||
|
||||
def find_or_new_from_path_component(klass, path_component)
|
||||
return unless path_component
|
||||
klass.find_by(slug: path_component) ||
|
||||
klass.find_by(
|
||||
name: to_human_name(path_component)
|
||||
) ||
|
||||
klass.new(name: to_human_name(path_component))
|
||||
if path_component.is_a? Array
|
||||
path_component.map { |it| find_or_new_from_path_component(klass, it) }
|
||||
else
|
||||
klass.find_by(slug: path_component) ||
|
||||
klass.find_by(
|
||||
name: to_human_name(path_component)
|
||||
) ||
|
||||
klass.new(name: to_human_name(path_component))
|
||||
end
|
||||
end
|
||||
|
||||
def to_human_name(str)
|
||||
|
||||
@@ -90,7 +90,7 @@ class Scan::Model::ParseMetadataJob < ApplicationJob
|
||||
components = PathParserService.new(library.path_template, path).call
|
||||
{
|
||||
creator: find_or_create_from_path_component(Creator, components[:creator]),
|
||||
collections: [find_or_create_from_path_component(Collection, components[:collection])].compact,
|
||||
collections: Array(find_or_create_from_path_component(Collection, components[:collections])),
|
||||
name: to_human_name(components[:model_name])
|
||||
}.compact_blank
|
||||
end
|
||||
@@ -170,10 +170,14 @@ class Scan::Model::ParseMetadataJob < ApplicationJob
|
||||
|
||||
def find_or_create_from_path_component(klass, path_component)
|
||||
return unless path_component
|
||||
klass.find_by(slug: path_component) ||
|
||||
klass.create_with(slug: path_component.parameterize).find_or_create_by(
|
||||
name: to_human_name(path_component)
|
||||
)
|
||||
if path_component.is_a? Array
|
||||
path_component.map { |it| find_or_create_from_path_component(klass, it) }
|
||||
else
|
||||
klass.find_by(slug: path_component) ||
|
||||
klass.create_with(slug: path_component.parameterize).find_or_create_by(
|
||||
name: to_human_name(path_component)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def to_human_name(str)
|
||||
|
||||
@@ -8,9 +8,10 @@ class PathParserService
|
||||
components = @path.match(path_parse_pattern)&.named_captures&.symbolize_keys
|
||||
return {} if components.nil?
|
||||
components.merge({
|
||||
tags: components[:tags]&.split("/")&.compact_blank,
|
||||
tags: components[:tags]&.split(File::SEPARATOR)&.compact_blank,
|
||||
collections: components[:collection] ? [components.delete(:collection)] : components[:collections]&.split("/")&.compact_blank,
|
||||
model_id: nil # discard ID, never gonna use it in parsing
|
||||
}).compact
|
||||
}).compact_blank
|
||||
end
|
||||
|
||||
private
|
||||
@@ -22,15 +23,17 @@ class PathParserService
|
||||
when "{tags}"
|
||||
"(?<tags>[[:print:]]*)"
|
||||
when "{creator}"
|
||||
"(?<creator>[[:print:]&&[^/]]*?)"
|
||||
"(?<creator>[[:print:]&&[^#{File::SEPARATOR}]]*?)"
|
||||
when "{collection}"
|
||||
"(?<collection>[[:print:]&&[^/]]*?)"
|
||||
"(?<collection>[[:print:]&&[^#{File::SEPARATOR}]]*?)"
|
||||
when "{collections}"
|
||||
"(?<collections>[[:print:]]*)"
|
||||
when "{modelName}"
|
||||
"(?<model_name>[[:print:]&&[^/]]*?)"
|
||||
"(?<model_name>[[:print:]&&[^#{File::SEPARATOR}]]*?)"
|
||||
when "{modelId}"
|
||||
"(?<model_id>#[[:digit:]]+)?"
|
||||
else
|
||||
"[[:print:]&&[^/]]*"
|
||||
"[[:print:]&&[^#{File::SEPARATOR}]]*"
|
||||
end
|
||||
} + "$")
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ class PathTemplateValidator < ActiveModel::EachValidator
|
||||
"tags",
|
||||
"creator",
|
||||
"collection",
|
||||
"collections",
|
||||
"modelName",
|
||||
"modelId"
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<code>{creator}</code>: <%= t ".tokens.creator" %>
|
||||
</li>
|
||||
<li>
|
||||
<code>{collection}</code>: <%= t ".tokens.collection" %>
|
||||
<code>{collections}</code>: <%= t ".tokens.collections" %>
|
||||
</li>
|
||||
<li>
|
||||
<code>{modelName}</code>: <%= t ".tokens.model_name" %>
|
||||
|
||||
@@ -7,10 +7,12 @@ RSpec.describe PathParserService do
|
||||
"{tags}" => %r{^/?.*?(?<tags>[[:print:]]*)$},
|
||||
"{creator}" => %r{^/?.*?(?<creator>[[:print:]&&[^/]]*?)$},
|
||||
"{collection}" => %r{^/?.*?(?<collection>[[:print:]&&[^/]]*?)$},
|
||||
"{collections}" => %r{^/?.*?(?<collections>[[:print:]]*)$},
|
||||
"{tags}/{creator}" => %r{^/?.*?(?<tags>[[:print:]]*)/(?<creator>[[:print:]&&[^/]]*?)$},
|
||||
"{tags}/{creator}/{modelName}{modelId}" => %r{^/?.*?(?<tags>[[:print:]]*)/(?<creator>[[:print:]&&[^/]]*?)/(?<model_name>[[:print:]&&[^/]]*?)(?<model_id>#[[:digit:]]+)?$},
|
||||
"@{creator}{modelId}" => %r{^/?.*?@(?<creator>[[:print:]&&[^/]]*?)(?<model_id>#[[:digit:]]+)?$},
|
||||
"{creator}/{collection}/{tags}/{modelName}{modelId}" => %r{^/?.*?(?<creator>[[:print:]&&[^/]]*?)/(?<collection>[[:print:]&&[^/]]*?)/(?<tags>[[:print:]]*)/(?<model_name>[[:print:]&&[^/]]*?)(?<model_id>#[[:digit:]]+)?$}
|
||||
"{creator}/{collection}/{tags}/{modelName}{modelId}" => %r{^/?.*?(?<creator>[[:print:]&&[^/]]*?)/(?<collection>[[:print:]&&[^/]]*?)/(?<tags>[[:print:]]*)/(?<model_name>[[:print:]&&[^/]]*?)(?<model_id>#[[:digit:]]+)?$},
|
||||
"{collections}/{creator}" => %r{^/?.*?(?<collections>[[:print:]]*)/(?<creator>[[:print:]&&[^/]]*?)$}
|
||||
}.each_pair do |tag, regexp|
|
||||
it "correctly converts #{tag} into a regexp matcher" do
|
||||
service = described_class.new(tag, path)
|
||||
@@ -28,7 +30,7 @@ RSpec.describe PathParserService do
|
||||
model_name: "prefix - name"
|
||||
},
|
||||
"{collection}/{modelName}{modelId}" => {
|
||||
collection: "bottom",
|
||||
collections: ["bottom"],
|
||||
model_name: "prefix - name"
|
||||
},
|
||||
"{tags}/{creator}/{modelName}{modelId}" => {
|
||||
@@ -42,8 +44,13 @@ RSpec.describe PathParserService do
|
||||
"{tags}/{creator}/{collection} - {modelName}{modelId}" => {
|
||||
tags: ["top", "middle"],
|
||||
creator: "bottom",
|
||||
collection: "prefix",
|
||||
collections: ["prefix"],
|
||||
model_name: "name"
|
||||
},
|
||||
"{collections}/{creator}/{modelName}{modelId}" => {
|
||||
collections: ["top", "middle"],
|
||||
creator: "bottom",
|
||||
model_name: "prefix - name"
|
||||
}
|
||||
}.each_pair do |tag, values|
|
||||
it "correctly matches components of #{tag}" do
|
||||
|
||||
Reference in new issue
Block a user