diff --git a/app/jobs/scan/check_model_integrity_job.rb b/app/jobs/scan/check_model_integrity_job.rb
index d2b97be9a..44067f736 100644
--- a/app/jobs/scan/check_model_integrity_job.rb
+++ b/app/jobs/scan/check_model_integrity_job.rb
@@ -7,6 +7,8 @@ def perform(model_id)
Problem.create_or_clear(model, :missing, !File.exist?(File.join(model.library.path, model.path)))
Problem.create_or_clear model, :empty, (model.model_files.count == 0)
Problem.create_or_clear model, :nesting, model.contains_other_models?
+ Problem.create_or_clear model, :no_image, model.image_files.empty?
+ Problem.create_or_clear model, :no_3d_model, model.three_d_files.empty?
model.model_files.each do |f|
Problem.create_or_clear(f, :missing, !File.exist?(File.join(model.library.path, model.path, f.filename)))
end
diff --git a/app/models/model.rb b/app/models/model.rb
index e6e51bb75..d3c0c01e8 100644
--- a/app/models/model.rb
+++ b/app/models/model.rb
@@ -107,6 +107,14 @@ def new?
tags.where(name: SiteSettings.model_tags_auto_tag_new).any?
end
+ def image_files
+ model_files.select(&:is_image?)
+ end
+
+ def three_d_files
+ model_files.select(&:is_3d_model?)
+ end
+
private
def normalize_license
diff --git a/app/models/model_file.rb b/app/models/model_file.rb
index f7eb84bcc..0899a9a93 100644
--- a/app/models/model_file.rb
+++ b/app/models/model_file.rb
@@ -18,6 +18,10 @@ def is_image?
SupportedMimeTypes.image_extensions.include? extension
end
+ def is_3d_model?
+ SupportedMimeTypes.model_extensions.include? extension
+ end
+
def mime_type
Mime::Type.lookup_by_extension(extension)
end
diff --git a/app/models/problem.rb b/app/models/problem.rb
index 18f05aa10..2033046f5 100644
--- a/app/models/problem.rb
+++ b/app/models/problem.rb
@@ -16,7 +16,9 @@ class Problem < ApplicationRecord
:destination_exists, # No longer used, but kept for compatibility
:nesting,
:inefficient,
- :duplicate
+ :duplicate,
+ :no_image,
+ :no_3d_model
]
enum :category, CATEGORIES
@@ -32,7 +34,9 @@ class Problem < ApplicationRecord
empty: :info,
nesting: :warning,
inefficient: :info,
- duplicate: :warning
+ duplicate: :warning,
+ no_image: :silent,
+ no_3d_model: :silent
}
def self.create_or_clear(problematic, cat, present, options = {})
diff --git a/app/views/problems/_model_no_3d_model.html.erb b/app/views/problems/_model_no_3d_model.html.erb
new file mode 100644
index 000000000..e75c8c368
--- /dev/null
+++ b/app/views/problems/_model_no_3d_model.html.erb
@@ -0,0 +1,4 @@
+
<%= icon("question-square", t(".title")) %> |
+<%= link_to problem.problematic.name, [problem.problematic.library, problem.problematic] %> |
+<%= t ".title" %> |
+<%= link_to "Open", [problem.problematic.library, problem.problematic], class: "btn btn-primary" %> |
diff --git a/app/views/problems/_model_no_image.html.erb b/app/views/problems/_model_no_image.html.erb
new file mode 100644
index 000000000..e75c8c368
--- /dev/null
+++ b/app/views/problems/_model_no_image.html.erb
@@ -0,0 +1,4 @@
+<%= icon("question-square", t(".title")) %> |
+<%= link_to problem.problematic.name, [problem.problematic.library, problem.problematic] %> |
+<%= t ".title" %> |
+<%= link_to "Open", [problem.problematic.library, problem.problematic], class: "btn btn-primary" %> |
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5a7c78aca..f5f6c18fd 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -110,6 +110,8 @@ en:
inefficient: Inefficient formats
missing: Missing files or folders
nesting: Model contains other models
+ no_3d_model: Model has no 3D files
+ no_image: Model has no image files
filters:
apply_filters: Apply
category: Category
@@ -143,6 +145,12 @@ en:
description: The model folder on disk contains other models. You may wish to merge them into this one, or move them out.
title: Contains other models
warning: Bulk merging moves all files from the models above into this one, and removes them. File metadata is preserved, but any model metadata will be lost!
+ model_no_3d_model:
+ description: This model contains no 3D files. That is unlikely to be correct.
+ title: No 3D files in model
+ model_no_image:
+ description: This model contains no image files. Adding one might make it easier to browse.
+ title: No image files in model
severities:
danger: Danger
info: Info
diff --git a/spec/jobs/scan/check_model_integrity_job_spec.rb b/spec/jobs/scan/check_model_integrity_job_spec.rb
index 20cf28330..3100153df 100644
--- a/spec/jobs/scan/check_model_integrity_job_spec.rb
+++ b/spec/jobs/scan/check_model_integrity_job_spec.rb
@@ -2,29 +2,49 @@
require "support/mock_directory"
RSpec.describe Scan::CheckModelIntegrityJob do
- around do |ex|
- MockDirectory.create([
- "model_one/test.stl"
- ]) do |path|
- @library_path = path
- ex.run
+ context "when checking for missing files" do
+ around do |ex|
+ MockDirectory.create([
+ "model_one/test.stl"
+ ]) do |path|
+ @library_path = path
+ ex.run
+ end
+ end
+
+ # rubocop:disable RSpec/InstanceVariable
+ let(:library) { create(:library, path: @library_path) }
+ # rubocop:enable RSpec/InstanceVariable
+
+ it "flags models with no folder as a problem" do
+ model = create(:model, library: library, path: "missing")
+ described_class.perform_now(model.id)
+ expect(model.problems.map(&:category)).to include("missing")
end
- end
- # rubocop:disable RSpec/InstanceVariable
- let(:library) { create(:library, path: @library_path) }
- # rubocop:enable RSpec/InstanceVariable
+ it "flags up problems for files that don't exist on disk" do
+ thing = create(:model, path: "model_one", library: library)
+ create(:model_file, filename: "missing.stl", model: thing)
+ described_class.perform_now(thing.id)
+ expect(thing.model_files.first.problems.map(&:category)).to include("missing")
+ end
+ end
- it "flags models with no folder as a problem" do
- model = create(:model, library: library, path: "missing")
- expect { described_class.perform_now(model.id) }.to change(Problem, :count).from(0).to(2)
- expect(model.problems.map(&:category)).to eq ["missing", "empty"]
+ context "when checking for missing image files" do
+ it "flags models without images as a problem" do
+ model = create(:model)
+ create(:model_file, filename: "3d.stl", model: model)
+ described_class.perform_now(model.id)
+ expect(model.problems.map(&:category)).to include("no_image")
+ end
end
- it "flags up problems for files that don't exist on disk" do
- thing = create(:model, path: "model_one", library: library)
- create(:model_file, filename: "missing.stl", model: thing)
- expect { described_class.perform_now(thing.id) }.to change(Problem, :count).from(0).to(1)
- expect(thing.model_files.first.problems.first.category).to eq "missing"
+ context "when checking for missing 3d files" do
+ it "flags models without 3d files as a problem" do
+ model = create(:model)
+ create(:model_file, filename: "image.jpg", model: model)
+ described_class.perform_now(model.id)
+ expect(model.problems.map(&:category)).to include("no_3d_model")
+ end
end
end