5797 textBox extent:((maxLength * 5)@(info size * 20)); sizeFixed:false. |
5786 textBox extent:((maxLength * 5)@(info size * 20)); sizeFixed:false. |
5798 textBox maxExtent:Screen current extent. |
5787 textBox maxExtent:Screen current extent. |
5799 textBox openModeless. |
5788 textBox openModeless. |
5800 |
5789 |
5801 "Modified: / 25-07-2006 / 09:07:22 / cg" |
5790 "Modified: / 25-07-2006 / 09:07:22 / cg" |
|
5791 ! |
|
5792 |
|
5793 fileFindDuplicateFile |
|
5794 "scan directory for duplicates of the selected files" |
|
5795 |
|
5796 |files filesBySize samePerFile stream textBox| |
|
5797 |
|
5798 files := self currentSelectedFiles. |
|
5799 files isEmpty ifTrue:[^ self]. |
|
5800 |
|
5801 filesBySize := Dictionary new. |
|
5802 files do:[:fn | |
|
5803 |sz entry| |
|
5804 |
|
5805 sz := fn asFilename fileSize. |
|
5806 (filesBySize at:sz ifAbsentPut:[Set new]) add:fn. |
|
5807 ]. |
|
5808 |
|
5809 samePerFile := Dictionary new. |
|
5810 |
|
5811 self currentSelectedDirectories do:[:eachDir | |
|
5812 eachDir recursiveDirectoryContentsAsFilenamesDo:[:eachFile | |
|
5813 eachFile isDirectory ifFalse:[ |
|
5814 |sz possibleMatches| |
|
5815 |
|
5816 sz := eachFile fileSize. |
|
5817 possibleMatches := filesBySize at:sz ifAbsent:nil. |
|
5818 possibleMatches notNil ifTrue:[ |
|
5819 possibleMatches do:[:eachFileWithSameSize | |
|
5820 (eachFileWithSameSize sameContentsAs:eachFile) ifTrue:[ |
|
5821 (samePerFile at:eachFileWithSameSize ifAbsentPut:[Set new]) add:eachFile |
|
5822 ] |
|
5823 ] |
|
5824 ] |
|
5825 ] |
|
5826 ] |
|
5827 ]. |
|
5828 |
|
5829 stream := WriteStream on:''. |
|
5830 samePerFile keysAndValuesDo:[:origFile :sameFiles| |
|
5831 stream nextPutLine:origFile baseName. |
|
5832 (sameFiles asOrderedCollection collect:[:each | each baseName]) sort do:[:eachSameName | |
|
5833 stream nextPutAll:' '; nextPutLine:eachSameName. |
|
5834 ] |
|
5835 ]. |
|
5836 |
|
5837 textBox := TextBox new. |
|
5838 textBox initialText:(stream contents). |
|
5839 textBox title:'Files with same contents'. |
|
5840 textBox readOnly:true. |
|
5841 textBox noCancel. |
|
5842 textBox extent:(350@400). |
|
5843 textBox maxExtent:Screen current extent. |
|
5844 textBox openModeless. "/ showAtPointer. |
|
5845 |
|
5846 "/ |
|
5847 "/ self withActivityIndicationDo:[ |
|
5848 "/ result := Dictionary new. |
|
5849 "/ |
|
5850 "/ infoDir := Dictionary new. |
|
5851 "/ allFiles do:[:fn | |
|
5852 "/ infoDir at:fn put:(fn info) |
|
5853 "/ ]. |
|
5854 "/ |
|
5855 "/ "/ for each, get the files size. |
|
5856 "/ "/ in a first pass, look for files of the same size and |
|
5857 "/ "/ compare them ... |
|
5858 "/ |
|
5859 "/ filesBySize := Dictionary new. |
|
5860 "/ infoDir keysAndValuesDo:[:fn :info | |
|
5861 "/ |sz entry| |
|
5862 "/ |
|
5863 "/ sz := info size. |
|
5864 "/ entry := filesBySize at:sz ifAbsentPut:[Set new]. |
|
5865 "/ entry add:fn. |
|
5866 "/ ]. |
|
5867 "/ |
|
5868 "/ "/ any of same size ? |
|
5869 "/ |
|
5870 "/ filesBySize do:[:entry | |
|
5871 "/ |files| |
|
5872 "/ |
|
5873 "/ entry size > 1 ifTrue:[ |
|
5874 "/ files := entry asArray. |
|
5875 "/ 1 to:files size-1 do:[:idx1 | |
|
5876 "/ idx1+1 to:files size do:[:idx2 | |
|
5877 "/ |fn1 fn2| |
|
5878 "/ |
|
5879 "/ fn1 := files at:idx1. |
|
5880 "/ fn2 := files at:idx2. |
|
5881 "/ |
|
5882 "/ (result at:fn2 ifAbsent:nil) ~= fn1 ifTrue:[ |
|
5883 "/ "/ compare the files |
|
5884 "/ (fn1 sameContentsAs:fn2) ifTrue:[ |
|
5885 "/"/ Transcript show:'Same: '; show:fn1 baseName; show:' and '; showCR:fn2 baseName. |
|
5886 "/ result at:fn1 put:fn2. |
|
5887 "/ ] |
|
5888 "/ ] |
|
5889 "/ ] |
|
5890 "/ ] |
|
5891 "/ ] |
|
5892 "/ ]. |
|
5893 "/ |
|
5894 "/ result := result associations. |
|
5895 "/ result := result collect:[:assoc | |
|
5896 "/ |f1 f2| |
|
5897 "/ |
|
5898 "/ f1 := assoc key asString. |
|
5899 "/ f2 := assoc value asString. |
|
5900 "/ f1 < f2 ifTrue:[ |
|
5901 "/ f2 -> f1 |
|
5902 "/ ] ifFalse:[ |
|
5903 "/ f1 -> f2 |
|
5904 "/ ] |
|
5905 "/ ]. |
|
5906 "/ "/ result sort:[:f1 :f2 | f1 key > f2 key "f2 value < f1 key value"]. |
|
5907 "/ result sort:[:f1 :f2 | " f1 key > f2 key" f2 value < f1 key value]. |
|
5908 "/ |
|
5909 "/ info := OrderedCollection new. |
|
5910 "/ size := self getBestDirectory asString size. |
|
5911 "/ result do:[:assoc | |
|
5912 "/ |fn1 fn2| |
|
5913 "/ |
|
5914 "/ fn1 := assoc key. |
|
5915 "/ fn2 := assoc value. |
|
5916 "/ size > 1 ifTrue:[ |
|
5917 "/ fn1 := ('..', (fn1 copyFrom:(size + 1))). |
|
5918 "/ fn2 := ('..', (fn2 copyFrom:(size + 1))). |
|
5919 "/ ]. |
|
5920 "/ (fn1 includes:Character space) ifTrue:[ |
|
5921 "/ fn1 := '"' , fn1 , '"' |
|
5922 "/ ]. |
|
5923 "/ (fn2 includes:Character space) ifTrue:[ |
|
5924 "/ fn2 := '"' , fn2 , '"' |
|
5925 "/ ]. |
|
5926 "/ info add:(fn1 , ' same as ' , fn2) |
|
5927 "/ ]. |
|
5928 "/ info isEmpty ifTrue:[ |
|
5929 "/ Dialog information:'No duplicate files found.'. |
|
5930 "/ ^ self. |
|
5931 "/ ]. |
|
5932 "/ ]. |
|
5933 "/ stream := WriteStream on:''. |
|
5934 "/ info do:[:el| |
|
5935 "/ stream nextPutLine:el. |
|
5936 "/ ]. |
|
5937 "/ titleStream := WriteStream on:''. |
|
5938 "/ titleStream nextPutAll:'File duplicates in director'. |
|
5939 "/ directories size == 1 ifTrue:[ |
|
5940 "/ titleStream nextPutAll:'y: ', directories first asString. |
|
5941 "/ ] ifFalse:[ |
|
5942 "/ titleStream nextPutLine:'ies: '. |
|
5943 "/ directories do:[:dir| |
|
5944 "/ size > 1 ifTrue:[ |
|
5945 "/ titleStream nextPutAll:'..'. |
|
5946 "/ titleStream nextPutLine:((dir asString) copyFrom:(size + 1)). |
|
5947 "/ ] ifFalse:[ |
|
5948 "/ titleStream nextPutLine:(dir asString). |
|
5949 "/ ]. |
|
5950 "/ ] |
|
5951 "/ ]. |
|
5952 "/ |
|
5953 "/ textBox := TextBox new. |
|
5954 "/ textBox initialText:(stream contents). |
|
5955 "/ textBox title:(titleStream contents). |
|
5956 "/ textBox readOnly:true. |
|
5957 "/ textBox noCancel. |
|
5958 "/ stream := WriteStream on:'Duplicates in '. |
|
5959 "/ directories do:[ :aDirectory | |
|
5960 "/ stream nextPutAll:aDirectory baseName. |
|
5961 "/ stream space. |
|
5962 "/ ]. |
|
5963 "/ textBox label:stream contents. |
|
5964 "/ maxLength := 10. |
|
5965 "/ info do:[: el | |
|
5966 "/ maxLength := maxLength max:(el size). |
|
5967 "/ ]. |
|
5968 "/ textBox extent:((maxLength * 5)@((info size max:40)* 10)). |
|
5969 "/ textBox maxExtent:Screen current extent. |
|
5970 "/ textBox openModeless. "/ showAtPointer. |
|
5971 |
|
5972 "Created: / 11-07-2011 / 12:39:44 / cg" |
5802 ! |
5973 ! |
5803 |
5974 |
5804 fileFindDuplicates |
5975 fileFindDuplicates |
5805 "scan directory for duplicate files" |
5976 "scan directory for duplicate files" |
5806 |
5977 |