Merge branch 'pr-82'
This commit is contained in:
		
						commit
						4a985a6c5d
					
				| @ -15,9 +15,10 @@ | |||||||
|       How can I help you? <em>-- Elodie</em><i></i> |       How can I help you? <em>-- Elodie</em><i></i> | ||||||
|     </div> |     </div> | ||||||
|     <form class="importPhotos" action="" method="post"> |     <form class="importPhotos" action="" method="post"> | ||||||
|       <div class="content"> |       <div id="content" class="content"> | ||||||
|         <p> |         <p> | ||||||
|           Let me know where your photos are and where you'd like me to put them as I sort them. |           Let me know where your photos are and where you'd like me to put them as I sort them. | ||||||
|  |           <small><em>(You can drop your photos here to update its information.)</em></small> | ||||||
|         </p> |         </p> | ||||||
|         <div> |         <div> | ||||||
|           <label for="source"><i class="icon-folder-open"></i> What folder are your photos in now?</label> |           <label for="source"><i class="icon-folder-open"></i> What folder are your photos in now?</label> | ||||||
|  | |||||||
| @ -6,6 +6,8 @@ var __process__ = {}; | |||||||
| 
 | 
 | ||||||
| if(typeof(require) === 'function') { | if(typeof(require) === 'function') { | ||||||
|   var ipc = require('ipc'); |   var ipc = require('ipc'); | ||||||
|  |   var path = require('path'); | ||||||
|  |   var os = require('os'); | ||||||
|   ipc.on('files', function(files) { |   ipc.on('files', function(files) { | ||||||
|     __process__.files = files; |     __process__.files = files; | ||||||
|   }); |   }); | ||||||
| @ -32,7 +34,11 @@ if(typeof(require) === 'function') { | |||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
|   ipc.on('update-photos-success', function(args) { |   ipc.on('update-photos-success', function(args) { | ||||||
|     var response = JSON.parse(args['stdout']); |     if(os.platform() == 'win32'){ | ||||||
|  |         var response = JSON.parse(args['stdout'].replace(/\\/g, '\\\\')); | ||||||
|  |     }else{ | ||||||
|  |         var response = JSON.parse(args['stdout']); | ||||||
|  |     } | ||||||
|     handlers.setSuccessTitle(); |     handlers.setSuccessTitle(); | ||||||
|     handlers.removeProgressIcons(); |     handlers.removeProgressIcons(); | ||||||
|     handlers.updateStatus(response); |     handlers.updateStatus(response); | ||||||
| @ -43,7 +49,28 @@ if(typeof(require) === 'function') { | |||||||
|       ipc.send(name, message); |       ipc.send(name, message); | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| } |    | ||||||
|  |   window.onload = function () { | ||||||
|  |     var broadcast = new Broadcast(); | ||||||
|  |     window.ondragover = function (e){ e.preventDefault(); return false }; | ||||||
|  | 	window.ondragover = function (e){ e.preventDefault(); return false }; | ||||||
|  | 	var holder = document.getElementById('content'); | ||||||
|  | 	if(holder != null){ | ||||||
|  |         holder.ondrop = function (e) { | ||||||
|  |           e.preventDefault(); | ||||||
|  |           files = [] | ||||||
|  |           for (var i = 0; i < e.dataTransfer.files.length; ++i) { | ||||||
|  |             console.log(e.dataTransfer.files[i].path); | ||||||
|  | 			files.push(e.dataTransfer.files[i].path); | ||||||
|  |           } | ||||||
|  |           broadcast.send('load-update-photos', files); | ||||||
|  |           return false; | ||||||
|  |         }; | ||||||
|  | 	  } | ||||||
|  | 	}; | ||||||
|  | 	 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| function Handlers() { | function Handlers() { | ||||||
|   var self = this; |   var self = this; | ||||||
| @ -161,7 +188,7 @@ function Handlers() { | |||||||
|     html = '<label>You selected ' + (files.length > 1 ? 'these photos' : 'this photo') + '</label>'; |     html = '<label>You selected ' + (files.length > 1 ? 'these photos' : 'this photo') + '</label>'; | ||||||
|     for(var i=0; i<files.length && i<16; i++) { |     for(var i=0; i<files.length && i<16; i++) { | ||||||
|       if(files[i].match(/(mov|mp4|3gp|avi)/i) === null) { |       if(files[i].match(/(mov|mp4|3gp|avi)/i) === null) { | ||||||
|         html += '<div class="center-cropped" style="background-image:url(\'file://'+files[i]+'\');" title="'+files[i]+'"></div>'; |         html += '<div class="center-cropped" style="background-image:url(\'file://'+fileUrl(files[i])+'\');" title="'+files[i]+'"></div>'; | ||||||
|       } else { |       } else { | ||||||
|         html += '<div class="center-cropped video"></div>'; |         html += '<div class="center-cropped video"></div>'; | ||||||
|       } |       } | ||||||
| @ -200,6 +227,22 @@ function Handlers() { | |||||||
|       el.style.display = 'block'; |       el.style.display = 'block'; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  | 
 | ||||||
|  |   function fileUrl(str) { | ||||||
|  |     if (typeof str !== 'string') { | ||||||
|  |         throw new Error('Expected a string'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     var pathName = path.resolve(str).replace(/\\/g, '/'); | ||||||
|  | 
 | ||||||
|  |     // Windows drive letter must be prefixed with a slash
 | ||||||
|  |     if (pathName[0] !== '/') { | ||||||
|  |         pathName = '/' + pathName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return encodeURI('file://' + pathName); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| } | } | ||||||
| var handlers = new Handlers(); | var handlers = new Handlers(); | ||||||
| window.addEventListener('click', handlers.dispatch); | window.addEventListener('click', handlers.dispatch); | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ | |||||||
|       <a href="index.html" class="right"><i class="icon-media-add"></i></a> |       <a href="index.html" class="right"><i class="icon-media-add"></i></a> | ||||||
|     </div> |     </div> | ||||||
|     <form class="updatePhotos" action="" method="post"> |     <form class="updatePhotos" action="" method="post"> | ||||||
|       <div class="content"> |       <div id="content" class="content"> | ||||||
|         <div class="location"> |         <div class="location"> | ||||||
|           <label for="location-field"><i class="icon-map"></i>Change geolocation</label> |           <label for="location-field"><i class="icon-map"></i>Change geolocation</label> | ||||||
|           <input id="location-field" type="text" placeholder="i.e. Sunnyvale, CA"> |           <input id="location-field" type="text" placeholder="i.e. Sunnyvale, CA"> | ||||||
|  | |||||||
| @ -16,3 +16,4 @@ ipc.on('update-photos', broadcast.updatePhotos); | |||||||
| ipc.on('launch-finder', broadcast.launchFinder); | ipc.on('launch-finder', broadcast.launchFinder); | ||||||
| ipc.on('launch-url', broadcast.launchUrl); | ipc.on('launch-url', broadcast.launchUrl); | ||||||
| ipc.on('program-quit', broadcast.programQuit); | ipc.on('program-quit', broadcast.programQuit); | ||||||
|  | ipc.on('load-update-photos', toolbarUi.onDropFiles); | ||||||
| @ -1,5 +1,5 @@ | |||||||
| var exports = module.exports = {}; | var exports = module.exports = {}; | ||||||
| 
 | var path = require('path'); | ||||||
| var exec = require('child_process').exec, | var exec = require('child_process').exec, | ||||||
|     config = require('./config.js'); |     config = require('./config.js'); | ||||||
| 
 | 
 | ||||||
| @ -24,7 +24,7 @@ exports.importPhotos = function(event, args) { | |||||||
|   args['source'] = args['source'].normalize(); |   args['source'] = args['source'].normalize(); | ||||||
|   args['destination'] = args['destination'].normalize(); |   args['destination'] = args['destination'].normalize(); | ||||||
| 
 | 
 | ||||||
|   update_command = __dirname + '/../../dist/elodie/elodie import --source="' + args['source'] +  '" --destination="' + args['destination'] + '"'; |   update_command = path.normalize(__dirname + '/../../dist/elodie/elodie') + ' import --source="' + args['source'] +  '" --destination="' + args['destination'] + '"'; | ||||||
|   //update_command = __dirname + '/../../elodie.py import --source="' + args['source'] +  '" --destination="' + args['destination'] + '"';
 |   //update_command = __dirname + '/../../elodie.py import --source="' + args['source'] +  '" --destination="' + args['destination'] + '"';
 | ||||||
|    |    | ||||||
|   console.log(update_command); |   console.log(update_command); | ||||||
| @ -73,8 +73,8 @@ exports.updatePhotos = function(event, args) { | |||||||
|     return files |     return files | ||||||
|   } |   } | ||||||
|   files = normalize(args['files']) |   files = normalize(args['files']) | ||||||
| 
 |   elodie_path = path.normalize(__dirname + '/../../dist/elodie/elodie'); | ||||||
|   update_command = __dirname + '/../../dist/elodie/elodie update' |   update_command = elodie_path +' update' | ||||||
|   //update_command = __dirname + '/../../elodie.py update'
 |   //update_command = __dirname + '/../../elodie.py update'
 | ||||||
|   if(args['location'].length > 0) { |   if(args['location'].length > 0) { | ||||||
|     update_command += ' --location="' + args['location'] + '"'; |     update_command += ' --location="' + args['location'] + '"'; | ||||||
|  | |||||||
| @ -1,13 +1,14 @@ | |||||||
| var exports = module.exports = {}; | var exports = module.exports = {}; | ||||||
| var fs = require('fs'), | var fs = require('fs'), | ||||||
|  |     os = require('os'), | ||||||
|     defaultConfigFile = (function() { |     defaultConfigFile = (function() { | ||||||
|       var f = __dirname; |       var f = __dirname; | ||||||
|       for(var i=0; i<2; i++) { |       for(var i=0; i<2; i++) { | ||||||
|         f = f.substr(0, f.lastIndexOf('/')); |         f = f.substr(0, f.lastIndexOf(os.platform() == 'win32' ? '\\' : '/')); | ||||||
|       } |       } | ||||||
|       return f + '/config.ini-sample'; |       return f + (os.platform() == 'win32' ? '\\config.ini-sample': '/config.ini-sample'); | ||||||
|     })(), |     })(), | ||||||
|     configFile = (process.env.HOME || process.env.USERPROFILE) + '/.elodie/config.ini', |     configFile = (process.env.HOME || process.env.USERPROFILE) + (os.platform() == 'win32' ? '\\.elodie\\config.ini' : '/.elodie/config.ini'), | ||||||
|     hasConfig, |     hasConfig, | ||||||
|     setConfig; |     setConfig; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,11 +5,15 @@ var menubar = require('menubar'), | |||||||
|     tray = require('tray'), |     tray = require('tray'), | ||||||
|     config = require('./config.js'), |     config = require('./config.js'), | ||||||
|     loadUrl = null; |     loadUrl = null; | ||||||
|  | var os = require('os') | ||||||
|  | 
 | ||||||
|  | var s_dir = __dirname.substr(0,__dirname.lastIndexOf(os.platform() == 'win32' ? '\\' : '/')) +  | ||||||
|  |                               (os.platform() == 'win32' ? '\\html' : '/html'); | ||||||
|                                                |                                                | ||||||
| exports.app = app = menubar( | exports.app = app = menubar( | ||||||
|   { |   { | ||||||
|     preloadWindow: true, |     preloadWindow: true, | ||||||
|     dir: __dirname.substr(0, __dirname.lastIndexOf('/')) + '/html', |     dir: s_dir, | ||||||
|     index: 'index.html', |     index: 'index.html', | ||||||
|     pages: { |     pages: { | ||||||
|       'blank': 'blank.html', |       'blank': 'blank.html', | ||||||
| @ -18,7 +22,9 @@ exports.app = app = menubar( | |||||||
|     }, |     }, | ||||||
|     width: 400, |     width: 400, | ||||||
|     height: 500, |     height: 500, | ||||||
|     'window-position': 'trayCenter' |     'window-position': 'trayCenter', | ||||||
|  | 	'frame': os.platform() == 'win32' ? true : false, | ||||||
|  | 	'always-on-top': os.platform() == 'win32' ? true : false | ||||||
|   } |   } | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| @ -59,6 +65,18 @@ exports.ready = function() { | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | exports.onDropFiles = function(event, args) { | ||||||
|  |   var files = args; | ||||||
|  |   loadUrl = app.getOption('pages')['location']; | ||||||
|  |   app.showWindow(); | ||||||
|  |   | ||||||
|  |   app.window.webContents.on('did-finish-load', function() { | ||||||
|  |   app.window.webContents.send('files', files); | ||||||
|  |   app.window.webContents.send('preview', files); | ||||||
|  |  }); | ||||||
|  | }; | ||||||
|  |   | ||||||
|  | 
 | ||||||
| exports.createWindow = function() { | exports.createWindow = function() { | ||||||
|   console.log('create-window') |   console.log('create-window') | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ Settings used by Elodie. | |||||||
| from os import path | from os import path | ||||||
| 
 | 
 | ||||||
| #: If True, debug messages will be printed. | #: If True, debug messages will be printed. | ||||||
| debug = True | debug = False | ||||||
| 
 | 
 | ||||||
| #: Directory in which to store Elodie settings. | #: Directory in which to store Elodie settings. | ||||||
| application_directory = '{}/.elodie'.format(path.expanduser('~')) | application_directory = '{}/.elodie'.format(path.expanduser('~')) | ||||||
| @ -20,4 +20,7 @@ location_db = '{}/location.json'.format(application_directory) | |||||||
| script_directory = path.dirname(path.dirname(path.abspath(__file__))) | script_directory = path.dirname(path.dirname(path.abspath(__file__))) | ||||||
| 
 | 
 | ||||||
| #: Path to Elodie's ExifTool config file. | #: Path to Elodie's ExifTool config file. | ||||||
| exiftool_config = '%s/configs/ExifTool_config' % script_directory | exiftool_config = path.join(script_directory, 'configs', 'ExifTool_config') | ||||||
|  | 
 | ||||||
|  | #: Accepted language in responses from MapQuest | ||||||
|  | accepted_language = 'en' | ||||||
|  | |||||||
| @ -68,7 +68,7 @@ class FileSystem(object): | |||||||
|                     extensions is None or |                     extensions is None or | ||||||
|                     filename.lower().endswith(extensions) |                     filename.lower().endswith(extensions) | ||||||
|                 ): |                 ): | ||||||
|                     files.append('%s/%s' % (dirname, filename)) |                     files.append(os.path.join(dirname, filename)) | ||||||
|         return files |         return files | ||||||
| 
 | 
 | ||||||
|     def get_current_directory(self): |     def get_current_directory(self): | ||||||
| @ -164,7 +164,7 @@ class FileSystem(object): | |||||||
|             path.append('Unknown Location') |             path.append('Unknown Location') | ||||||
| 
 | 
 | ||||||
|         # return '/'.join(path[::-1]) |         # return '/'.join(path[::-1]) | ||||||
|         return '/'.join(path) |         return os.path.join(*path) | ||||||
| 
 | 
 | ||||||
|     def process_file(self, _file, destination, media, **kwargs): |     def process_file(self, _file, destination, media, **kwargs): | ||||||
|         move = False |         move = False | ||||||
| @ -179,9 +179,9 @@ class FileSystem(object): | |||||||
| 
 | 
 | ||||||
|         directory_name = self.get_folder_path(metadata) |         directory_name = self.get_folder_path(metadata) | ||||||
| 
 | 
 | ||||||
|         dest_directory = '%s/%s' % (destination, directory_name) |         dest_directory = os.path.join(destination, directory_name) | ||||||
|         file_name = self.get_file_name(media) |         file_name = self.get_file_name(media) | ||||||
|         dest_path = '%s/%s' % (dest_directory, file_name) |         dest_path = os.path.join(dest_directory, file_name) | ||||||
| 
 | 
 | ||||||
|         db = Db() |         db = Db() | ||||||
|         checksum = db.checksum(_file) |         checksum = db.checksum(_file) | ||||||
|  | |||||||
| @ -161,9 +161,10 @@ def reverse_lookup(lat, lon): | |||||||
| 
 | 
 | ||||||
|     try: |     try: | ||||||
|         params = {'format': 'json', 'key': key, 'lat': lat, 'lon': lon} |         params = {'format': 'json', 'key': key, 'lat': lat, 'lon': lon} | ||||||
|  |         headers = {"Accept-Language": constants.accepted_language} | ||||||
|         r = requests.get( |         r = requests.get( | ||||||
|             'http://open.mapquestapi.com/nominatim/v1/reverse.php?%s' % |             'http://open.mapquestapi.com/nominatim/v1/reverse.php?%s' % | ||||||
|             urllib.urlencode(params) |             urllib.urlencode(params), headers=headers | ||||||
|         ) |         ) | ||||||
|         return r.json() |         return r.json() | ||||||
|     except requests.exceptions.RequestException as e: |     except requests.exceptions.RequestException as e: | ||||||
|  | |||||||
| @ -98,7 +98,7 @@ class Db(object): | |||||||
|         :returns: str or None |         :returns: str or None | ||||||
|         """ |         """ | ||||||
|         hasher = hashlib.sha256() |         hasher = hashlib.sha256() | ||||||
|         with open(file_path, 'r') as f: |         with open(file_path, 'rb') as f: | ||||||
|             buf = f.read(blocksize) |             buf = f.read(blocksize) | ||||||
| 
 | 
 | ||||||
|             while len(buf) > 0: |             while len(buf) > 0: | ||||||
|  | |||||||
| @ -106,9 +106,10 @@ class Media(object): | |||||||
| 
 | 
 | ||||||
|         source = self.source |         source = self.source | ||||||
|         process_output = subprocess.Popen( |         process_output = subprocess.Popen( | ||||||
|             ['%s "%s"' % (exiftool, source)], |             '%s "%s"' % (exiftool, source), | ||||||
|             stdout=subprocess.PIPE, |             stdout=subprocess.PIPE, | ||||||
|             shell=True |             shell=True, | ||||||
|  |             universal_newlines=True | ||||||
|         ) |         ) | ||||||
|         output = process_output.stdout.read() |         output = process_output.stdout.read() | ||||||
| 
 | 
 | ||||||
| @ -224,8 +225,8 @@ class Media(object): | |||||||
|         if(constants.debug is True): |         if(constants.debug is True): | ||||||
|             print '%s -config "%s" -xmp-elodie:Album="%s" "%s"' % (exiftool, exiftool_config, name, source)  # noqa |             print '%s -config "%s" -xmp-elodie:Album="%s" "%s"' % (exiftool, exiftool_config, name, source)  # noqa | ||||||
|         process_output = subprocess.Popen( |         process_output = subprocess.Popen( | ||||||
|             ['%s -config "%s" -xmp-elodie:Album="%s" "%s"' % |             '%s -config "%s" -xmp-elodie:Album="%s" "%s"' % | ||||||
|                 (exiftool, exiftool_config, name, source)], |             (exiftool, exiftool_config, name, source), | ||||||
|             stdout=subprocess.PIPE, |             stdout=subprocess.PIPE, | ||||||
|             shell=True |             shell=True | ||||||
|         ) |         ) | ||||||
|  | |||||||
| @ -156,9 +156,10 @@ class Video(Media): | |||||||
| 
 | 
 | ||||||
|         source = self.source |         source = self.source | ||||||
|         process_output = subprocess.Popen( |         process_output = subprocess.Popen( | ||||||
|             ['%s "%s"' % (exiftool, source)], |             '%s "%s"' % (exiftool, source), | ||||||
|             stdout=subprocess.PIPE, |             stdout=subprocess.PIPE, | ||||||
|             shell=True |             shell=True, | ||||||
|  |             universal_newlines=True | ||||||
|         ) |         ) | ||||||
|         return process_output.stdout.read() |         return process_output.stdout.read() | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,9 @@ import sys | |||||||
| 
 | 
 | ||||||
| import re | import re | ||||||
| import shutil | import shutil | ||||||
|  | from datetime import datetime | ||||||
|  | from datetime import timedelta | ||||||
|  | import time | ||||||
| 
 | 
 | ||||||
| sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))) | sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))) | ||||||
| 
 | 
 | ||||||
| @ -12,13 +15,14 @@ from elodie.filesystem import FileSystem | |||||||
| from elodie.media.media import Media | from elodie.media.media import Media | ||||||
| from elodie.media.photo import Photo | from elodie.media.photo import Photo | ||||||
| from elodie.media.video import Video | from elodie.media.video import Video | ||||||
|  | from nose.plugins.skip import SkipTest | ||||||
| 
 | 
 | ||||||
| os.environ['TZ'] = 'GMT' | os.environ['TZ'] = 'GMT' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_create_directory_success(): | def test_create_directory_success(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     folder = '%s/%s' % (helper.temp_dir(), helper.random_string(10)) |     folder = os.path.join(helper.temp_dir(), helper.random_string(10)) | ||||||
|     status = filesystem.create_directory(folder) |     status = filesystem.create_directory(folder) | ||||||
| 
 | 
 | ||||||
|     # Needs to be a subdirectory |     # Needs to be a subdirectory | ||||||
| @ -34,7 +38,7 @@ def test_create_directory_success(): | |||||||
| 
 | 
 | ||||||
| def test_create_directory_recursive_success(): | def test_create_directory_recursive_success(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     folder = '%s/%s/%s' % (helper.temp_dir(), helper.random_string(10), helper.random_string(10)) |     folder = os.path.join(helper.temp_dir(), helper.random_string(10), helper.random_string(10)) | ||||||
|     status = filesystem.create_directory(folder) |     status = filesystem.create_directory(folder) | ||||||
| 
 | 
 | ||||||
|     # Needs to be a subdirectory |     # Needs to be a subdirectory | ||||||
| @ -47,6 +51,8 @@ def test_create_directory_recursive_success(): | |||||||
|     shutil.rmtree(folder) |     shutil.rmtree(folder) | ||||||
| 
 | 
 | ||||||
| def test_create_directory_invalid_permissions(): | def test_create_directory_invalid_permissions(): | ||||||
|  |     if os.name == 'nt': | ||||||
|  |        raise SkipTest("It isn't implemented on Windows") | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     status = filesystem.create_directory('/apathwhichdoesnotexist/afolderwhichdoesnotexist') |     status = filesystem.create_directory('/apathwhichdoesnotexist/afolderwhichdoesnotexist') | ||||||
| 
 | 
 | ||||||
| @ -54,7 +60,7 @@ def test_create_directory_invalid_permissions(): | |||||||
| 
 | 
 | ||||||
| def test_delete_directory_if_empty(): | def test_delete_directory_if_empty(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     folder = '%s/%s' % (helper.temp_dir(), helper.random_string(10)) |     folder = os.path.join(helper.temp_dir(), helper.random_string(10)) | ||||||
|     os.makedirs(folder) |     os.makedirs(folder) | ||||||
| 
 | 
 | ||||||
|     assert os.path.isdir(folder) == True |     assert os.path.isdir(folder) == True | ||||||
| @ -67,7 +73,7 @@ def test_delete_directory_if_empty(): | |||||||
| 
 | 
 | ||||||
| def test_delete_directory_if_empty_when_not_empty(): | def test_delete_directory_if_empty_when_not_empty(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     folder = '%s/%s/%s' % (helper.temp_dir(), helper.random_string(10), helper.random_string(10)) |     folder = os.path.join(helper.temp_dir(), helper.random_string(10), helper.random_string(10)) | ||||||
|     os.makedirs(folder) |     os.makedirs(folder) | ||||||
|     parent_folder = os.path.dirname(folder) |     parent_folder = os.path.dirname(folder) | ||||||
| 
 | 
 | ||||||
| @ -126,14 +132,14 @@ def test_get_file_name_plain(): | |||||||
|     media = Photo(helper.get_file('plain.jpg')) |     media = Photo(helper.get_file('plain.jpg')) | ||||||
|     file_name = filesystem.get_file_name(media) |     file_name = filesystem.get_file_name(media) | ||||||
| 
 | 
 | ||||||
|     assert file_name == '2015-12-05_00-59-26-plain.jpg', file_name |     assert file_name == helper.path_tz_fix('2015-12-05_00-59-26-plain.jpg'), file_name | ||||||
| 
 | 
 | ||||||
| def test_get_file_name_with_title(): | def test_get_file_name_with_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     media = Photo(helper.get_file('with-title.jpg')) |     media = Photo(helper.get_file('with-title.jpg')) | ||||||
|     file_name = filesystem.get_file_name(media) |     file_name = filesystem.get_file_name(media) | ||||||
| 
 | 
 | ||||||
|     assert file_name == '2015-12-05_00-59-26-with-title-some-title.jpg', file_name |     assert file_name == helper.path_tz_fix('2015-12-05_00-59-26-with-title-some-title.jpg'), file_name | ||||||
| 
 | 
 | ||||||
| def test_get_folder_name_by_date(): | def test_get_folder_name_by_date(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
| @ -152,34 +158,34 @@ def test_get_folder_path_plain(): | |||||||
|     media = Photo(helper.get_file('plain.jpg')) |     media = Photo(helper.get_file('plain.jpg')) | ||||||
|     path = filesystem.get_folder_path(media.get_metadata()) |     path = filesystem.get_folder_path(media.get_metadata()) | ||||||
| 
 | 
 | ||||||
|     assert path == '2015-12-Dec/Unknown Location', path |     assert path == os.path.join('2015-12-Dec','Unknown Location'), path | ||||||
| 
 | 
 | ||||||
| def test_get_folder_path_with_title(): | def test_get_folder_path_with_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     media = Photo(helper.get_file('with-title.jpg')) |     media = Photo(helper.get_file('with-title.jpg')) | ||||||
|     path = filesystem.get_folder_path(media.get_metadata()) |     path = filesystem.get_folder_path(media.get_metadata()) | ||||||
| 
 | 
 | ||||||
|     assert path == '2015-12-Dec/Unknown Location', path |     assert path == os.path.join('2015-12-Dec','Unknown Location'), path | ||||||
| 
 | 
 | ||||||
| def test_get_folder_path_with_location(): | def test_get_folder_path_with_location(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     media = Photo(helper.get_file('with-location.jpg')) |     media = Photo(helper.get_file('with-location.jpg')) | ||||||
|     path = filesystem.get_folder_path(media.get_metadata()) |     path = filesystem.get_folder_path(media.get_metadata()) | ||||||
| 
 | 
 | ||||||
|     assert path == '2015-12-Dec/Sunnyvale', path |     assert path == os.path.join('2015-12-Dec','Sunnyvale'), path | ||||||
| 
 | 
 | ||||||
| def test_get_folder_path_with_location_and_title(): | def test_get_folder_path_with_location_and_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     media = Photo(helper.get_file('with-location-and-title.jpg')) |     media = Photo(helper.get_file('with-location-and-title.jpg')) | ||||||
|     path = filesystem.get_folder_path(media.get_metadata()) |     path = filesystem.get_folder_path(media.get_metadata()) | ||||||
| 
 | 
 | ||||||
|     assert path == '2015-12-Dec/Sunnyvale', path |     assert path == os.path.join('2015-12-Dec','Sunnyvale'), path | ||||||
| 
 | 
 | ||||||
| def test_process_file_plain(): | def test_process_file_plain(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('plain.jpg'), origin) |     shutil.copyfile(helper.get_file('plain.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -193,7 +199,7 @@ def test_process_file_plain(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Unknown Location/2015-12-05_00-59-26-photo.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Unknown Location','2015-12-05_00-59-26-photo.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_title(): | def test_process_file_with_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
| @ -213,13 +219,13 @@ def test_process_file_with_title(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Unknown Location/2015-12-05_00-59-26-photo-some-title.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Unknown Location','2015-12-05_00-59-26-photo-some-title.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_location(): | def test_process_file_with_location(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('with-location.jpg'), origin) |     shutil.copyfile(helper.get_file('with-location.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -233,13 +239,13 @@ def test_process_file_with_location(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Sunnyvale/2015-12-05_00-59-26-photo.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Sunnyvale','2015-12-05_00-59-26-photo.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_location_and_title(): | def test_process_file_with_location_and_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('with-location-and-title.jpg'), origin) |     shutil.copyfile(helper.get_file('with-location-and-title.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -253,13 +259,13 @@ def test_process_file_with_location_and_title(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Sunnyvale/2015-12-05_00-59-26-photo-some-title.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Sunnyvale','2015-12-05_00-59-26-photo-some-title.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_album(): | def test_process_file_with_album(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('with-album.jpg'), origin) |     shutil.copyfile(helper.get_file('with-album.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -273,13 +279,13 @@ def test_process_file_with_album(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Test Album/2015-12-05_00-59-26-photo.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Test Album','2015-12-05_00-59-26-photo.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_album_and_title(): | def test_process_file_with_album_and_title(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('with-album-and-title.jpg'), origin) |     shutil.copyfile(helper.get_file('with-album-and-title.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -293,13 +299,13 @@ def test_process_file_with_album_and_title(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Test Album/2015-12-05_00-59-26-photo-some-title.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Test Album','2015-12-05_00-59-26-photo-some-title.jpg')) in destination, destination | ||||||
| 
 | 
 | ||||||
| def test_process_file_with_album_and_title_and_location(): | def test_process_file_with_album_and_title_and_location(): | ||||||
|     filesystem = FileSystem() |     filesystem = FileSystem() | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| 
 | 
 | ||||||
|     origin = '%s/photo.jpg' % folder |     origin = os.path.join(folder,'photo.jpg') | ||||||
|     shutil.copyfile(helper.get_file('with-album-and-title-and-location.jpg'), origin) |     shutil.copyfile(helper.get_file('with-album-and-title-and-location.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     media = Photo(origin) |     media = Photo(origin) | ||||||
| @ -313,4 +319,4 @@ def test_process_file_with_album_and_title_and_location(): | |||||||
| 
 | 
 | ||||||
|     assert origin_checksum is not None, origin_checksum |     assert origin_checksum is not None, origin_checksum | ||||||
|     assert origin_checksum == destination_checksum, destination_checksum |     assert origin_checksum == destination_checksum, destination_checksum | ||||||
|     assert '2015-12-Dec/Test Album/2015-12-05_00-59-26-photo-some-title.jpg' in destination, destination |     assert helper.path_tz_fix(os.path.join('2015-12-Dec','Test Album','2015-12-05_00-59-26-photo-some-title.jpg')) in destination, destination | ||||||
|  | |||||||
| @ -3,6 +3,11 @@ import os | |||||||
| import random | import random | ||||||
| import string | import string | ||||||
| import tempfile | import tempfile | ||||||
|  | import re | ||||||
|  | import time | ||||||
|  | 
 | ||||||
|  | from datetime import datetime | ||||||
|  | from datetime import timedelta | ||||||
| 
 | 
 | ||||||
| def checksum(file_path, blocksize=65536): | def checksum(file_path, blocksize=65536): | ||||||
|     hasher = hashlib.sha256() |     hasher = hashlib.sha256() | ||||||
| @ -17,14 +22,14 @@ def checksum(file_path, blocksize=65536): | |||||||
| 
 | 
 | ||||||
| def create_working_folder(): | def create_working_folder(): | ||||||
|     temporary_folder = tempfile.gettempdir() |     temporary_folder = tempfile.gettempdir() | ||||||
|     folder = '%s/%s/%s' % (temporary_folder, random_string(10), random_string(10)) |     folder = os.path.join(temporary_folder, random_string(10), random_string(10)) | ||||||
|     os.makedirs(folder) |     os.makedirs(folder) | ||||||
| 
 | 
 | ||||||
|     return (temporary_folder, folder) |     return (temporary_folder, folder) | ||||||
| 
 | 
 | ||||||
| def get_file(name): | def get_file(name): | ||||||
|     current_folder = os.path.dirname(os.path.realpath(__file__)) |     current_folder = os.path.dirname(os.path.realpath(__file__)) | ||||||
|     return '%s/files/%s' % (current_folder, name) |     return os.path.join(current_folder, 'files', name) | ||||||
| 
 | 
 | ||||||
| def get_test_location(): | def get_test_location(): | ||||||
|     return (61.013710, 99.196656, 'Siberia') |     return (61.013710, 99.196656, 'Siberia') | ||||||
| @ -53,3 +58,37 @@ def random_coordinate(coordinate, precision): | |||||||
| 
 | 
 | ||||||
| def temp_dir(): | def temp_dir(): | ||||||
|     return tempfile.gettempdir() |     return tempfile.gettempdir() | ||||||
|  | 
 | ||||||
|  | def is_windows(): | ||||||
|  |     return os.name == 'nt' | ||||||
|  | 
 | ||||||
|  | # path_tz_fix(file_name) | ||||||
|  | # Change timestamp in file_name by the offset | ||||||
|  | # between UTC and local time, i.e. | ||||||
|  | #  2015-12-05_00-59-26-with-title-some-title.jpg -> | ||||||
|  | #  2015-12-04_20-59-26-with-title-some-title.jpg | ||||||
|  | # (Windows only) | ||||||
|  | 
 | ||||||
|  | def path_tz_fix(file_name): | ||||||
|  |   if is_windows(): | ||||||
|  |       # Calculate the offset between UTC and local time | ||||||
|  |       tz_shift = (datetime.fromtimestamp(0) - | ||||||
|  |                   datetime.utcfromtimestamp(0)).seconds/3600 | ||||||
|  |       # replace timestamp in file_name | ||||||
|  |       m = re.search('(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})',file_name) | ||||||
|  |       t_date = datetime.fromtimestamp(time.mktime(time.strptime(m.group(0), '%Y-%m-%d_%H-%M-%S'))) | ||||||
|  |       s_date_fix = (t_date-timedelta(hours=tz_shift)).strftime('%Y-%m-%d_%H-%M-%S') | ||||||
|  |       return re.sub('\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}',s_date_fix,file_name) | ||||||
|  |   else: | ||||||
|  |       return file_name | ||||||
|  | 
 | ||||||
|  | # time_convert(s_time) | ||||||
|  | # Change s_time (struct_time) by the offset | ||||||
|  | # between UTC and local time | ||||||
|  | # (Windows only) | ||||||
|  | 
 | ||||||
|  | def time_convert(s_time): | ||||||
|  |     if is_windows(): | ||||||
|  |         return time.gmtime((time.mktime(s_time))) | ||||||
|  |     else: | ||||||
|  |         return s_time | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| import os | import os | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| import datetime | from datetime import datetime | ||||||
| import shutil | import shutil | ||||||
| import tempfile | import tempfile | ||||||
| import time | import time | ||||||
| @ -95,7 +95,8 @@ def test_get_date_taken(): | |||||||
|     photo = Photo(helper.get_file('plain.jpg')) |     photo = Photo(helper.get_file('plain.jpg')) | ||||||
|     date_taken = photo.get_date_taken() |     date_taken = photo.get_date_taken() | ||||||
| 
 | 
 | ||||||
|     assert date_taken == (2015, 12, 5, 0, 59, 26, 5, 339, 0), date_taken | #    assert date_taken == (2015, 12, 5, 0, 59, 26, 5, 339, 0), date_taken | ||||||
|  |     assert date_taken == helper.time_convert((2015, 12, 5, 0, 59, 26, 5, 339, 0)), date_taken | ||||||
| 
 | 
 | ||||||
| def test_get_date_taken_without_exif(): | def test_get_date_taken_without_exif(): | ||||||
|     source = helper.get_file('no-exif.jpg') |     source = helper.get_file('no-exif.jpg') | ||||||
| @ -125,7 +126,7 @@ def test_set_date_taken_with_missing_datetimeoriginal(): | |||||||
|     shutil.copyfile(helper.get_file('no-exif.jpg'), origin) |     shutil.copyfile(helper.get_file('no-exif.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     photo = Photo(origin) |     photo = Photo(origin) | ||||||
|     status = photo.set_date_taken(datetime.datetime(2013, 9, 30, 7, 6, 5)) |     status = photo.set_date_taken(datetime(2013, 9, 30, 7, 6, 5)) | ||||||
| 
 | 
 | ||||||
|     assert status == True, status |     assert status == True, status | ||||||
| 
 | 
 | ||||||
| @ -136,7 +137,8 @@ def test_set_date_taken_with_missing_datetimeoriginal(): | |||||||
| 
 | 
 | ||||||
|     shutil.rmtree(folder) |     shutil.rmtree(folder) | ||||||
| 
 | 
 | ||||||
|     assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken'] |     #assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken'] | ||||||
|  |     assert date_taken == helper.time_convert((2013, 9, 30, 7, 6, 5, 0, 273, 0)), metadata['date_taken'] | ||||||
| 
 | 
 | ||||||
| def test_set_date_taken(): | def test_set_date_taken(): | ||||||
|     temporary_folder, folder = helper.create_working_folder() |     temporary_folder, folder = helper.create_working_folder() | ||||||
| @ -145,7 +147,7 @@ def test_set_date_taken(): | |||||||
|     shutil.copyfile(helper.get_file('plain.jpg'), origin) |     shutil.copyfile(helper.get_file('plain.jpg'), origin) | ||||||
| 
 | 
 | ||||||
|     photo = Photo(origin) |     photo = Photo(origin) | ||||||
|     status = photo.set_date_taken(datetime.datetime(2013, 9, 30, 7, 6, 5)) |     status = photo.set_date_taken(datetime(2013, 9, 30, 7, 6, 5)) | ||||||
| 
 | 
 | ||||||
|     assert status == True, status |     assert status == True, status | ||||||
| 
 | 
 | ||||||
| @ -156,7 +158,8 @@ def test_set_date_taken(): | |||||||
| 
 | 
 | ||||||
|     shutil.rmtree(folder) |     shutil.rmtree(folder) | ||||||
| 
 | 
 | ||||||
|     assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken'] |     #assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken'] | ||||||
|  |     assert date_taken == helper.time_convert((2013, 9, 30, 7, 6, 5, 0, 273, 0)), metadata['date_taken'] | ||||||
| 
 | 
 | ||||||
| def test_set_location(): | def test_set_location(): | ||||||
|     raise SkipTest('gh-31, precision is lost in conversion from decimal to dms') |     raise SkipTest('gh-31, precision is lost in conversion from decimal to dms') | ||||||
|  | |||||||
| @ -2,3 +2,4 @@ click>=6.2,<7.0 | |||||||
| LatLon>=1.0.2,<2.0 | LatLon>=1.0.2,<2.0 | ||||||
| requests>=2.9.1,<3.0 | requests>=2.9.1,<3.0 | ||||||
| send2trash>=1.3.0,<2.0 | send2trash>=1.3.0,<2.0 | ||||||
|  | mock>=1.3.0 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jaisen Mathai
						Jaisen Mathai