From 4e8b561f70111c33a280dfa6487a382fd8fdec24 Mon Sep 17 00:00:00 2001 From: Leeingnyo Date: Sun, 12 Sep 2021 00:37:48 +0900 Subject: [PATCH] Apply contents signature of directories --- src/library/title.cr | 10 ++++++---- src/util/signature.cr | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/library/title.cr b/src/library/title.cr index 51b82c9..5caefa0 100644 --- a/src/library/title.cr +++ b/src/library/title.cr @@ -32,6 +32,7 @@ class Title }) end @id = id + @contents_signature = Dir.contents_signature dir @title = File.basename dir @encoded_title = URI.encode @title @title_ids = [] of String @@ -71,12 +72,13 @@ class Title def examine : Bool return false unless Dir.exists? @dir # no title, should be removed - signature = Dir.signature @dir - # `signature` doesn't reflect movings, renames in nested titles - # return true if @signature == signature # not changed, preserve + contents_signature = Dir.contents_signature @dir + # not changed, preserve + return true if @contents_signature == contents_signature # fix title - @signature = signature + @contents_signature = contents_signature + @signature = Dir.signature @dir storage = Storage.default id = storage.get_title_id dir, signature if id.nil? diff --git a/src/util/signature.cr b/src/util/signature.cr index d1a0040..f2bf103 100644 --- a/src/util/signature.cr +++ b/src/util/signature.cr @@ -48,4 +48,27 @@ class Dir end Digest::CRC32.checksum(signatures.sort.join).to_u64 end + + # Returns the contents signature of the directory at dirname for checking + # to rescan. + # Rescan conditions: + # - When a file added, moved, removed, renamed (including which in nested + # directories) + def self.contents_signature(dirname) : String + signatures = [] of String + self.open dirname do |dir| + dir.entries.sort.each do |fn| + next if fn.starts_with? "." + path = File.join dirname, fn + if File.directory? path + signatures << Dir.contents_signature path + else + # Only add its signature value to `signatures` when it is a + # supported file + signatures << fn if is_supported_file fn + end + end + end + Digest::SHA1.hexdigest(signatures.sort.join) + end end