| 1 |  |  | # -*- coding: utf-8 -*- | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | """Check if contents of directory has changed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | import argparse | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | import os | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | import hashlib | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | from .listfiles import list_files | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | from .path import Path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | def digest(dirname): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |     """Returns the md5 digest of all interesting files in `dirname`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     md5 = hashlib.md5() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     fnames = [fname for _, fname in list_files(Path(dirname))] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |     for fname in sorted(fnames): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |         md5.update(open(os.path.join(dirname, fname), 'rb').read()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     return md5.hexdigest() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 21 |  |  | def changed(dirname, glob='**/*', filename='.md5', args=None): | 
            
                                                                        
                            
            
                                    
            
            
                | 22 |  |  |     """Has `glob` changed in `dirname` | 
            
                                                                        
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 24 |  |  |     Args: | 
            
                                                                        
                            
            
                                    
            
            
                | 25 |  |  |         dirname: directory to measure | 
            
                                                                        
                            
            
                                    
            
            
                | 26 |  |  |         filename: filename to store checksum | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |     """ | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |     root = Path(dirname) | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |     if not root.exists(): | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |         # if dirname doesn't exist it is changed (by definition) | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |         return True | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |     cachefile = root / filename | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |     current_digest = cachefile.open().read() if cachefile.exists() else "" | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |      | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |     _digest = digest(dirname) | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |     if args and args.verbose:  # pragma: nocover | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         print "md5:", _digest | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |     has_changed = current_digest != _digest | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |     if has_changed: | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |         with open(os.path.join(dirname, filename), 'w') as fp: | 
            
                                                                        
                            
            
                                    
            
            
                | 43 |  |  |             fp.write(_digest) | 
            
                                                                        
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 45 |  |  |     return has_changed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | class Directory(Path): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     def changed(self, glob='**/*', filename='.md5', force=False): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         return changed(self, glob, filename) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | def main():  # pragma: nocover | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     p = argparse.ArgumentParser() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     p.add_argument( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         'directory', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |         help="Directory to check" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     p.add_argument( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         '--verbose', '-v', action='store_true', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         help="increase verbosity" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |     args = p.parse_args() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |     import sys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     _changed = changed(sys.argv[1], args=args) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |     sys.exit(_changed) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  | if __name__ == "__main__":  # pragma: nocover | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 71 |  |  |     main() | 
            
                                                        
            
                                    
            
            
                | 72 |  |  |  |