Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't duplicate previously-merged models during rescan #564

Merged
merged 2 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions app/jobs/model_scan_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,31 @@ def self.file_pattern
"*.{#{lower.zip(upper).flatten.join(",")}}"
end

def model_file_paths(library)
library.model_files.reload.map do |x|
File.join(library.path, x.model.path, x.filename)
end
end

def perform(model)
# For each file in the model, create a file object
model_path = File.join(model.library.path, model.path)
all_file_paths = model_file_paths(model.library)
Dir.open(model_path) do |dir|
Dir.glob([
File.join(dir.path, ModelScanJob.file_pattern),
File.join(dir.path, "files", ModelScanJob.file_pattern)
]).each do |filename|
# Create the file
file = model.model_files.find_or_create_by(filename: filename.gsub(model_path + "/", ""))
# Try to guess if the file is presupported
if !(
File.join(model_path, filename).split(/[[:punct:]]|[[:space:]]/).map(&:downcase) &
["presupported", "supported", "sup", "wsupports", "withsupports"]
).empty?
file.update!(presupported: true)
unless all_file_paths.include?(filename)
# Create the file
file = model.model_files.find_or_create_by(filename: filename.gsub(model_path + "/", ""))
# Try to guess if the file is presupported
if !(
File.join(model_path, filename).split(/[[:punct:]]|[[:space:]]/).map(&:downcase) &
["presupported", "supported", "sup", "wsupports", "withsupports"]
).empty?
file.update!(presupported: true)
end
end
end
end
Expand All @@ -34,5 +43,7 @@ def perform(model)
model.model_files.reload
model.preview_file = model.model_files.first unless model.preview_file
model.autogenerate_tags_from_path! if model.tags.empty?
# If this model has no files, self destruct
model.destroy if model.model_files.reload.count == 0
end
end
1 change: 1 addition & 0 deletions app/models/library.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Library < ApplicationRecord
has_many :models, dependent: :destroy
has_many :model_files, through: :models
validates :path, presence: true, uniqueness: true, existing_path: true

default_scope { order(:path) }
Expand Down
27 changes: 27 additions & 0 deletions spec/jobs/model_scan_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,32 @@
expect { ModelScanJob.perform_now(thing) }.to change { thing.model_files.count }.from(2).to(1)
expect(thing.model_files.first.filename).to eq "files/part_one.stl"
end

it "does not recreate parts that have been merged into other models" do
# Set up one model nested inside another
model_one = create(:model, path: "model_one", library: library)
ModelScanJob.perform_now(model_one)
nested_model = create(:model, path: "model_one/nested_model", library: library)
ModelScanJob.perform_now(nested_model)
# Check initial conditions
expect(Model.count).to eq 2
expect(ModelFile.count).to eq 3
expect(model_one.model_files.count).to eq 2
expect(nested_model.model_files.count).to eq 1
# Merge the models
nested_model.merge_into_parent!
# Check that worked
expect(Model.count).to eq 1
expect(ModelFile.count).to eq 3
expect(model_one.model_files.count).to eq 3
# Now recreate the nested model and rescan
nested_model = create(:model, path: "model_one/nested_model", library: library)
ModelScanJob.perform_now(nested_model)
# That should not have changed anything apart from creating an empty model which will be cleaned up later
expect(Model.count).to eq 1
expect(ModelFile.count).to eq 3
expect(model_one.model_files.count).to eq 3
expect(nested_model.model_files.count).to eq 0
end
end
end