69 行
2.5 KiB
Ruby
69 行
2.5 KiB
Ruby
class MaterialSyncSuppressionMatcher
|
|
def self.match source_kind:,
|
|
source_uri: nil,
|
|
drive_path: nil,
|
|
drive_file_id: nil,
|
|
source_path: nil,
|
|
source_file_id: nil
|
|
key = MaterialSyncSuppression.normalize_source_key(source_kind:,
|
|
source_uri:,
|
|
drive_path:,
|
|
drive_file_id:,
|
|
source_path:,
|
|
source_file_id:)
|
|
return nil if key.blank?
|
|
|
|
MaterialSyncSuppression.find_by(normalized_source_key: key)
|
|
end
|
|
|
|
def self.match_google_drive_candidate drive_file_id:, relative_path:
|
|
normalized_path = validate_relative_path!(relative_path)
|
|
|
|
exact = [
|
|
normalize_key('google_drive_file', drive_file_id),
|
|
normalize_key('google_drive_path', normalized_path),
|
|
normalize_key('legacy_drive_path', normalized_path),
|
|
].compact
|
|
|
|
suppression =
|
|
MaterialSyncSuppression.find_by(normalized_source_key: exact)
|
|
return suppression if suppression
|
|
|
|
MaterialSyncSuppression
|
|
.where(source_kind: ['google_drive_path_prefix', 'legacy_drive_path_prefix'])
|
|
.where('drive_path = :path OR :path LIKE CONCAT(drive_path, "/%")', path: normalized_path)
|
|
.order(:id)
|
|
.first
|
|
end
|
|
|
|
def self.suppressed?(...)
|
|
match(...).present?
|
|
end
|
|
|
|
def self.validate_relative_path! relative_path
|
|
raw = relative_path.to_s.delete("\0").tr('\\', '/').strip
|
|
raise ArgumentError, 'relative_path is required' if raw.blank?
|
|
raise ArgumentError, 'relative_path must be relative' if raw.start_with?('/')
|
|
raise ArgumentError, 'relative_path must be relative' if raw.match?(/\A[A-Za-z]:\//)
|
|
if raw.start_with?('My Drive/', 'マイドライブ/')
|
|
raise ArgumentError, 'relative_path must be relative to source folder'
|
|
end
|
|
raise ArgumentError, 'relative_path must not contain //' if raw.include?('//')
|
|
raise ArgumentError, 'relative_path must not end with /' if raw.end_with?('/')
|
|
|
|
parts = raw.split('/')
|
|
if parts.any? { |part| part.in?(['.', '..']) }
|
|
raise ArgumentError, 'relative_path must not contain dot segments'
|
|
end
|
|
|
|
raw
|
|
end
|
|
|
|
def self.normalize_key source_kind, value
|
|
return nil if value.blank?
|
|
|
|
MaterialSyncSuppression.normalize_source_key(source_kind:, source_path: value,
|
|
source_file_id: value)
|
|
end
|
|
end
|