Add initial screen to add config information
This commit is contained in:
parent
42b481ea60
commit
a7aee65ca0
|
@ -0,0 +1,34 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="js/handlers.js"></script>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Lato:400,100,300,100italic,300italic' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="css/bootstrap.css"></script>
|
||||||
|
<link rel="stylesheet" href="css/boilerplate.css"></script>
|
||||||
|
<link rel="stylesheet" href="css/styles.css"></script>
|
||||||
|
<link rel="stylesheet" href="css/fontello/css/animation.css"></script>
|
||||||
|
<link rel="stylesheet" href="css/fontello/css/elodie.css"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="titlebar">
|
||||||
|
<!--<a href="" class="left quit quitProgram"><i class="icon-cancel-circle"></i></a>
|
||||||
|
<a href="" class="left minus minimizeProgram"><i class="icon-minus-circle"></i></a>-->
|
||||||
|
How can I help you? <em>-- Elodie</em><i></i>
|
||||||
|
</div>
|
||||||
|
<form class="updateConfig" action="" method="post">
|
||||||
|
<div class="content">
|
||||||
|
<p>
|
||||||
|
Doesn't look like you have a MapQuest API key. Get one for free <a href="#" data-url="https://developer.mapquest.com/plan_purchase/steps/business_edition/business_edition_free">here</a>.
|
||||||
|
</p>
|
||||||
|
<div class="location">
|
||||||
|
<label for="mapquest-api-key-field"><i class="icon-map"></i>MapQuest API Key</label>
|
||||||
|
<input id="mapquest-api-key-field" type="text" placeholder="i.e. pzjNKTtTjLydLtxUBwdgKAIC8OQbGLUy">
|
||||||
|
<button type="submit" class="push">Get Started<i></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
document.getElementById('location-field').focus();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -22,6 +22,15 @@ if(typeof(require) === 'function') {
|
||||||
//var response = JSON.parse(args['stdout']);
|
//var response = JSON.parse(args['stdout']);
|
||||||
handlers.removeProgressIcons();
|
handlers.removeProgressIcons();
|
||||||
});
|
});
|
||||||
|
ipc.on('update-config-status', function(args) {
|
||||||
|
if(args) {
|
||||||
|
// @TODO: We should really handle this in the nodejs code.
|
||||||
|
handlers.removeProgressIcons();
|
||||||
|
location.href = 'index.html';
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
ipc.on('update-photos-success', function(args) {
|
ipc.on('update-photos-success', function(args) {
|
||||||
var response = JSON.parse(args['stdout']);
|
var response = JSON.parse(args['stdout']);
|
||||||
handlers.setSuccessTitle();
|
handlers.setSuccessTitle();
|
||||||
|
@ -62,6 +71,12 @@ function Handlers() {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
broadcast.send('launch-finder', tgt);
|
broadcast.send('launch-finder', tgt);
|
||||||
};
|
};
|
||||||
|
this.click.launchUrl = function(ev) {
|
||||||
|
var el = ev.target,
|
||||||
|
tgt = el.dataset.url;
|
||||||
|
ev.preventDefault();
|
||||||
|
broadcast.send('launch-url', tgt);
|
||||||
|
};
|
||||||
this.click.quitProgram = function(ev) {
|
this.click.quitProgram = function(ev) {
|
||||||
//ev.preventDefault();
|
//ev.preventDefault();
|
||||||
console.log('quit');
|
console.log('quit');
|
||||||
|
@ -84,6 +99,23 @@ function Handlers() {
|
||||||
document.querySelector('button.push i').className = 'icon-spin animate-spin';
|
document.querySelector('button.push i').className = 'icon-spin animate-spin';
|
||||||
broadcast.send('import-photos', params);
|
broadcast.send('import-photos', params);
|
||||||
};
|
};
|
||||||
|
this.submit.updateConfig = function(ev) {
|
||||||
|
var el = ev.target,
|
||||||
|
cls = el.className,
|
||||||
|
params;
|
||||||
|
|
||||||
|
ev.preventDefault();
|
||||||
|
document.querySelector('button.push i').className = 'icon-spin animate-spin';
|
||||||
|
|
||||||
|
params = {};
|
||||||
|
params['mapQuestKey'] = document.querySelector('input[id="mapquest-api-key-field"]').value;
|
||||||
|
|
||||||
|
if(params['mapQuestKey'].length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcast.send('update-config', params);
|
||||||
|
};
|
||||||
this.submit.updatePhotos = function(ev) {
|
this.submit.updatePhotos = function(ev) {
|
||||||
var el = ev.target,
|
var el = ev.target,
|
||||||
cls = el.className,
|
cls = el.className,
|
||||||
|
@ -97,8 +129,9 @@ function Handlers() {
|
||||||
params['album'] = document.querySelector('input[id="album-field"]').value;
|
params['album'] = document.querySelector('input[id="album-field"]').value;
|
||||||
params['title'] = document.querySelector('input[id="title-field"]').value;
|
params['title'] = document.querySelector('input[id="title-field"]').value;
|
||||||
|
|
||||||
if(params['location'].length === 0 && params['datetime'].length === 0 && params['album'].length === 0 && params['title'].length === 0)
|
if(params['location'].length === 0 && params['datetime'].length === 0 && params['album'].length === 0 && params['title'].length === 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
params['files'] = __process__.files;
|
params['files'] = __process__.files;
|
||||||
broadcast.send('update-photos', params);
|
broadcast.send('update-photos', params);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var ipc = require('ipc');
|
var ipc = require('ipc'),
|
||||||
var toolbarUi = require('./modules/toolbar-ui.js');
|
toolbarUi = require('./modules/toolbar-ui.js'),
|
||||||
var broadcast = require('./modules/broadcast.js');
|
broadcast = require('./modules/broadcast.js');
|
||||||
|
|
||||||
toolbarUi.app.on('ready', toolbarUi.ready);
|
toolbarUi.app.on('ready', toolbarUi.ready);
|
||||||
toolbarUi.app.on('create-window', toolbarUi.createWindow);
|
toolbarUi.app.on('create-window', toolbarUi.createWindow);
|
||||||
|
@ -11,6 +11,8 @@ toolbarUi.app.on('hide', toolbarUi.show);
|
||||||
toolbarUi.app.on('after-hide', toolbarUi.afterHide);
|
toolbarUi.app.on('after-hide', toolbarUi.afterHide);
|
||||||
|
|
||||||
ipc.on('import-photos', broadcast.importPhotos);
|
ipc.on('import-photos', broadcast.importPhotos);
|
||||||
|
ipc.on('update-config', broadcast.updateConfig);
|
||||||
ipc.on('update-photos', broadcast.updatePhotos);
|
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('program-quit', broadcast.programQuit);
|
ipc.on('program-quit', broadcast.programQuit);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
var exports = module.exports = {};
|
var exports = module.exports = {};
|
||||||
|
|
||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec,
|
||||||
|
config = require('./config.js');
|
||||||
|
|
||||||
// The main process listens for events from the web renderer.
|
// The main process listens for events from the web renderer.
|
||||||
// When photos are dragged onto the toolbar and photos are requested to be updated it will fire an 'update-photos' ipc event.
|
// When photos are dragged onto the toolbar and photos are requested to be updated it will fire an 'update-photos' ipc event.
|
||||||
|
@ -39,6 +40,16 @@ exports.importPhotos = function(event, args) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.updateConfig = function(event, args) {
|
||||||
|
var params = args,
|
||||||
|
status;
|
||||||
|
status = config.writeConfig(params);
|
||||||
|
if(status) {
|
||||||
|
event.sender.send('update-config-status', true);
|
||||||
|
} else {
|
||||||
|
event.sender.send('update-config-status', false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// When photos are dragged onto the toolbar and photos are requested to be updated it will fire an 'update-photos' ipc event.
|
// When photos are dragged onto the toolbar and photos are requested to be updated it will fire an 'update-photos' ipc event.
|
||||||
// The web renderer will send the list of photos, type of update and new value to apply
|
// The web renderer will send the list of photos, type of update and new value to apply
|
||||||
|
@ -99,6 +110,12 @@ exports.launchFinder = function(event, path) {
|
||||||
shell.showItemInFolder(path);
|
shell.showItemInFolder(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.launchUrl = function(event, url) {
|
||||||
|
console.log(url);
|
||||||
|
var shell = require('shell');
|
||||||
|
shell.openExternal(url);
|
||||||
|
};
|
||||||
|
|
||||||
exports.programQuit = function(event, path) {
|
exports.programQuit = function(event, path) {
|
||||||
console.log('program-quit');
|
console.log('program-quit');
|
||||||
//mb.tray.destroy();
|
//mb.tray.destroy();
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
var exports = module.exports = {};
|
||||||
|
var fs = require('fs'),
|
||||||
|
defaultConfigFile = (function() {
|
||||||
|
var f = __dirname;
|
||||||
|
for(var i=0; i<2; i++) {
|
||||||
|
f = f.substr(0, f.lastIndexOf('/'));
|
||||||
|
}
|
||||||
|
return f + '/config.ini-sample';
|
||||||
|
})(),
|
||||||
|
configFile = (process.env.HOME || process.env.USERPROFILE) + '/.elodie/config.ini',
|
||||||
|
hasConfig,
|
||||||
|
setConfig;
|
||||||
|
|
||||||
|
exports.hasConfig = function() {
|
||||||
|
console.log(defaultConfigFile);
|
||||||
|
console.log(configFile);
|
||||||
|
return fs.existsSync(configFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.writeConfig = function(params) {
|
||||||
|
var contents;
|
||||||
|
try {
|
||||||
|
if(exports.hasConfig()) {
|
||||||
|
contents = fs.readFileSync(configFile).toString();
|
||||||
|
} else {
|
||||||
|
contents = fs.readFileSync(defaultConfigFile).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(contents);
|
||||||
|
contents = contents.replace(/key=[\s\S]+$/,'key='+params['mapQuestKey']);
|
||||||
|
fs.writeFileSync(configFile, contents);
|
||||||
|
return true;
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,6 +3,7 @@ var exports = module.exports = {};
|
||||||
var menubar = require('menubar'),
|
var menubar = require('menubar'),
|
||||||
menu = require('menu'),
|
menu = require('menu'),
|
||||||
tray = require('tray'),
|
tray = require('tray'),
|
||||||
|
config = require('./config.js'),
|
||||||
loadUrl = null;
|
loadUrl = null;
|
||||||
|
|
||||||
exports.app = app = menubar(
|
exports.app = app = menubar(
|
||||||
|
@ -12,6 +13,7 @@ exports.app = app = menubar(
|
||||||
index: 'index.html',
|
index: 'index.html',
|
||||||
pages: {
|
pages: {
|
||||||
'blank': 'blank.html',
|
'blank': 'blank.html',
|
||||||
|
'config': 'config.html',
|
||||||
'location': 'location.html'
|
'location': 'location.html'
|
||||||
},
|
},
|
||||||
width: 400,
|
width: 400,
|
||||||
|
@ -21,7 +23,8 @@ exports.app = app = menubar(
|
||||||
);
|
);
|
||||||
|
|
||||||
exports.ready = function() {
|
exports.ready = function() {
|
||||||
console.log('app is ready')
|
console.log('app is ready');
|
||||||
|
|
||||||
var template = [{
|
var template = [{
|
||||||
label: "Application",
|
label: "Application",
|
||||||
submenu: [
|
submenu: [
|
||||||
|
@ -65,9 +68,12 @@ exports.afterCreateWindow = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.show = function() {
|
exports.show = function() {
|
||||||
if(loadUrl === null) {
|
if(!config.hasConfig()) {
|
||||||
|
loadUrl = this.getOption('pages')['config'];
|
||||||
|
} else if(loadUrl === null) {
|
||||||
loadUrl = this.getOption('index');
|
loadUrl = this.getOption('index');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.window.loadUrl('file://' + this.getOption('dir') + '/' + loadUrl);
|
this.window.loadUrl('file://' + this.getOption('dir') + '/' + loadUrl);
|
||||||
loadUrl = null;
|
loadUrl = null;
|
||||||
//app.window.openDevTools();
|
//app.window.openDevTools();
|
||||||
|
|
|
@ -38,7 +38,7 @@ def _import(params):
|
||||||
if(media is None):
|
if(media is None):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if(type(media).__name__ == 'Video'):
|
if(media.__name__ == 'Video'):
|
||||||
filesystem.set_date_from_path_video(media)
|
filesystem.set_date_from_path_video(media)
|
||||||
|
|
||||||
dest_path = filesystem.process_file(current_file, destination, media, allowDuplicate=False, move=False)
|
dest_path = filesystem.process_file(current_file, destination, media, allowDuplicate=False, move=False)
|
||||||
|
@ -46,7 +46,7 @@ def _import(params):
|
||||||
print '%s -> %s' % (current_file, dest_path)
|
print '%s -> %s' % (current_file, dest_path)
|
||||||
elif(params['--file'] is not None):
|
elif(params['--file'] is not None):
|
||||||
current_file = params['--file']
|
current_file = params['--file']
|
||||||
media = Media.get_class_by_file(current_file)
|
media = Media.get_class_by_file(current_file, [Photo, Video])
|
||||||
if(media.__name__ == 'Video'):
|
if(media.__name__ == 'Video'):
|
||||||
filesystem.set_date_from_path_video(media)
|
filesystem.set_date_from_path_video(media)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ block_cipher = None
|
||||||
a = Analysis(['elodie.py'],
|
a = Analysis(['elodie.py'],
|
||||||
pathex=['/Users/jaisenmathai/dev/tools/elodie'],
|
pathex=['/Users/jaisenmathai/dev/tools/elodie'],
|
||||||
binaries=None,
|
binaries=None,
|
||||||
datas=[('config.ini',''),('configs/ExifTool_config', 'configs')],
|
datas=[('configs/ExifTool_config', 'configs')],
|
||||||
hiddenimports=[],
|
hiddenimports=[],
|
||||||
hookspath=None,
|
hookspath=None,
|
||||||
runtime_hooks=None,
|
runtime_hooks=None,
|
||||||
|
|
|
@ -122,6 +122,7 @@ class FileSystem:
|
||||||
if(len(path) < 2):
|
if(len(path) < 2):
|
||||||
path.append('Unknown Location')
|
path.append('Unknown Location')
|
||||||
|
|
||||||
|
#return '/'.join(path[::-1])
|
||||||
return '/'.join(path)
|
return '/'.join(path)
|
||||||
|
|
||||||
def process_file(self, _file, destination, media, **kwargs):
|
def process_file(self, _file, destination, media, **kwargs):
|
||||||
|
|
|
@ -74,7 +74,7 @@ def dms_to_decimal(degrees, minutes, seconds, sign=' '):
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_key():
|
def get_key():
|
||||||
config_file = '%s/config.ini' % path.dirname(path.dirname(path.abspath(__file__)))
|
config_file = '%s/config.ini' % constants.application_directory
|
||||||
if not path.exists(config_file):
|
if not path.exists(config_file):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ Media class for general video operations
|
||||||
class Media(object):
|
class Media(object):
|
||||||
# class / static variable accessible through get_valid_extensions()
|
# class / static variable accessible through get_valid_extensions()
|
||||||
video_extensions = ('avi','m4v','mov','mp4','3gp')
|
video_extensions = ('avi','m4v','mov','mp4','3gp')
|
||||||
photo_extensions = ('jpg', 'jpeg', 'nef', 'dng')
|
photo_extensions = ('jpg', 'jpeg', 'nef', 'dng', 'gif')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@param, source, string, The fully qualified path to the video file
|
@param, source, string, The fully qualified path to the video file
|
||||||
|
@ -335,6 +335,7 @@ class Media(object):
|
||||||
name = 'Video'
|
name = 'Video'
|
||||||
|
|
||||||
for i in classes:
|
for i in classes:
|
||||||
|
print i.__name__
|
||||||
if(name == i.__name__):
|
if(name == i.__name__):
|
||||||
return i(_file)
|
return i(_file)
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ from elodie import geolocation
|
||||||
Photo class for general photo operations
|
Photo class for general photo operations
|
||||||
"""
|
"""
|
||||||
class Photo(Media):
|
class Photo(Media):
|
||||||
|
__name__ = 'Photo'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@param, source, string, The fully qualified path to the photo file
|
@param, source, string, The fully qualified path to the photo file
|
||||||
|
|
|
@ -24,8 +24,7 @@ from media import Media
|
||||||
Video class for general video operations
|
Video class for general video operations
|
||||||
"""
|
"""
|
||||||
class Video(Media):
|
class Video(Media):
|
||||||
# class / static variable accessible through get_valid_extensions()
|
__name__ = 'Video'
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@param, source, string, The fully qualified path to the video file
|
@param, source, string, The fully qualified path to the video file
|
||||||
|
|
77
import.py
77
import.py
|
@ -1,77 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from elodie import arguments
|
|
||||||
from elodie.media.photo import Photo
|
|
||||||
from elodie.media.video import Video
|
|
||||||
from elodie.filesystem import FileSystem
|
|
||||||
from elodie.localstorage import Db
|
|
||||||
|
|
||||||
def help():
|
|
||||||
return """
|
|
||||||
usage: ./import.py --type=photo --source=/path/to/photos --destination=/path/to/destination
|
|
||||||
|
|
||||||
--type Valid values are 'photo' or 'video'. Only files of *type* are imported.
|
|
||||||
--file Full path to a photo or video to be imported. The --type argument should match the file type of the file.
|
|
||||||
@TODO: Automatically determine *type* from *file*
|
|
||||||
--source Full path to a directory which will be recursively crawled for files of *type*.
|
|
||||||
--destination Full path to a directory where organized photos will be placed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def parse_arguments(args):
|
|
||||||
config = {
|
|
||||||
'type': 'photo',
|
|
||||||
'file': None,
|
|
||||||
'source': None,
|
|
||||||
'destination': None
|
|
||||||
}
|
|
||||||
|
|
||||||
if('destination' not in args):
|
|
||||||
help()
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
config.update(args)
|
|
||||||
return config
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
|
|
||||||
destination = config['destination']
|
|
||||||
if(config['type'] == 'photo'):
|
|
||||||
media_type = Photo
|
|
||||||
else:
|
|
||||||
media_type = Video
|
|
||||||
|
|
||||||
if(config['source'] is not None):
|
|
||||||
source = config['source']
|
|
||||||
|
|
||||||
for current_file in filesystem.get_all_files(source, media_type.get_valid_extensions()):
|
|
||||||
media = media_type(current_file)
|
|
||||||
|
|
||||||
if(media_type.__name__ == 'Video'):
|
|
||||||
filesystem.set_date_from_path_video(media)
|
|
||||||
|
|
||||||
dest_path = filesystem.process_file(current_file, destination, media, allowDuplicate=False, move=False)
|
|
||||||
if(dest_path is not None):
|
|
||||||
print '%s -> %s' % (current_file, dest_path)
|
|
||||||
elif(config['file'] is not None):
|
|
||||||
media = media_type(config['file'])
|
|
||||||
if(media_type.__name__ == 'Video'):
|
|
||||||
filesystem.set_date_from_path_video(media)
|
|
||||||
|
|
||||||
dest_path = filesystem.process_file(config['file'], destination, media, allowDuplicate=False, move=False)
|
|
||||||
if(dest_path is not None):
|
|
||||||
print '%s -> %s' % (current_file, dest_path)
|
|
||||||
else:
|
|
||||||
help()
|
|
||||||
|
|
||||||
db = Db()
|
|
||||||
filesystem = FileSystem()
|
|
||||||
args = arguments.parse(sys.argv[1:], None, ['file=','type=','source=','destination='], help())
|
|
||||||
config = parse_arguments(args)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(config)
|
|
||||||
sys.exit(0)
|
|
137
update.py
137
update.py
|
@ -1,137 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import os
|
|
||||||
import pyexiv2
|
|
||||||
import re
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from elodie import arguments
|
|
||||||
from elodie import constants
|
|
||||||
from elodie import geolocation
|
|
||||||
from elodie.media.photo import Media
|
|
||||||
from elodie.media.photo import Photo
|
|
||||||
from elodie.media.video import Video
|
|
||||||
from elodie.filesystem import FileSystem
|
|
||||||
from elodie.localstorage import Db
|
|
||||||
|
|
||||||
def parse_arguments(args):
|
|
||||||
config = {
|
|
||||||
'title': None,
|
|
||||||
'time': None,
|
|
||||||
'location': None,
|
|
||||||
'album': None,
|
|
||||||
'process': 'yes'
|
|
||||||
}
|
|
||||||
|
|
||||||
config.update(args)
|
|
||||||
return config
|
|
||||||
|
|
||||||
def main(config, args):
|
|
||||||
location_coords = None
|
|
||||||
for arg in args:
|
|
||||||
file_path = arg
|
|
||||||
if(arg[:2] == '--'):
|
|
||||||
continue
|
|
||||||
elif(not os.path.exists(arg)):
|
|
||||||
if(constants.debug == True):
|
|
||||||
print 'Could not find %s' % arg
|
|
||||||
print '{"source":"%s", "error_msg":"Could not find %s"}' % (file_path, arg)
|
|
||||||
continue
|
|
||||||
|
|
||||||
destination = os.path.dirname(os.path.dirname(os.path.dirname(file_path)))
|
|
||||||
|
|
||||||
_class = None
|
|
||||||
extension = os.path.splitext(file_path)[1][1:].lower()
|
|
||||||
if(extension in Photo.get_valid_extensions()):
|
|
||||||
_class = Photo
|
|
||||||
elif(extension in Video.get_valid_extensions()):
|
|
||||||
_class = Video
|
|
||||||
|
|
||||||
if(_class is None):
|
|
||||||
continue
|
|
||||||
|
|
||||||
media = _class(file_path)
|
|
||||||
|
|
||||||
updated = False
|
|
||||||
if(config['location'] is not None):
|
|
||||||
if(location_coords is None):
|
|
||||||
location_coords = geolocation.coordinates_by_name(config['location'])
|
|
||||||
|
|
||||||
if(location_coords is not None and 'latitude' in location_coords and 'longitude' in location_coords):
|
|
||||||
location_status = media.set_location(location_coords['latitude'], location_coords['longitude'])
|
|
||||||
if(location_status != True):
|
|
||||||
if(constants.debug == True):
|
|
||||||
print 'Failed to update location'
|
|
||||||
print '{"source":"%s", "error_msg":"Failed to update location"}' % file_path
|
|
||||||
sys.exit(1)
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
|
|
||||||
if(config['time'] is not None):
|
|
||||||
time_string = config['time']
|
|
||||||
time_format = '%Y-%m-%d %H:%M:%S'
|
|
||||||
if(re.match('^\d{4}-\d{2}-\d{2}$', time_string)):
|
|
||||||
time_string = '%s 00:00:00' % time_string
|
|
||||||
|
|
||||||
if(re.match('^\d{4}-\d{2}-\d{2}$', time_string) is None and re.match('^\d{4}-\d{2}-\d{2} \d{2}:\d{2}\d{2}$', time_string)):
|
|
||||||
if(constants.debug == True):
|
|
||||||
print 'Invalid time format. Use YYYY-mm-dd hh:ii:ss or YYYY-mm-dd'
|
|
||||||
print '{"source":"%s", "error_msg":"Invalid time format. Use YYYY-mm-dd hh:ii:ss or YYYY-mm-dd"}' % file_path
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if(time_format is not None):
|
|
||||||
time = datetime.strptime(time_string, time_format)
|
|
||||||
media.set_datetime(time)
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
if(config['album'] is not None):
|
|
||||||
media.set_album(config['album'])
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
# Updating a title can be problematic when doing it 2+ times on a file.
|
|
||||||
# You would end up with img_001.jpg -> img_001-first-title.jpg -> img_001-first-title-second-title.jpg.
|
|
||||||
# To resolve that we have to track the prior title (if there was one.
|
|
||||||
# Then we massage the updated_media's metadata['base_name'] to remove the old title.
|
|
||||||
# Since FileSystem.get_file_name() relies on base_name it will properly rename the file by updating the title
|
|
||||||
# instead of appending it.
|
|
||||||
remove_old_title_from_name = False
|
|
||||||
if(config['title'] is not None):
|
|
||||||
# We call get_metadata() to cache it before making any changes
|
|
||||||
metadata = media.get_metadata()
|
|
||||||
title_update_status = media.set_title(config['title'])
|
|
||||||
original_title = metadata['title']
|
|
||||||
if(title_update_status and original_title is not None):
|
|
||||||
# @TODO: We should move this to a shared method since FileSystem.get_file_name() does it too.
|
|
||||||
original_title = re.sub('\W+', '-', original_title.lower())
|
|
||||||
original_base_name = metadata['base_name']
|
|
||||||
remove_old_title_from_name = True
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
if(updated == True):
|
|
||||||
updated_media = _class(file_path)
|
|
||||||
# See comments above on why we have to do this when titles get updated.
|
|
||||||
if(remove_old_title_from_name is True and len(original_title) > 0):
|
|
||||||
updated_media.get_metadata()
|
|
||||||
updated_media.set_metadata_basename(original_base_name.replace('-%s' % original_title, ''))
|
|
||||||
|
|
||||||
dest_path = filesystem.process_file(file_path, destination, updated_media, move=True, allowDuplicate=True)
|
|
||||||
if(constants.debug == True):
|
|
||||||
print '%s -> %s' % (file_path, dest_path)
|
|
||||||
|
|
||||||
print '{"source":"%s", "destination":"%s"}' % (file_path, dest_path)
|
|
||||||
# If the folder we moved the file out of or its parent are empty we delete it.
|
|
||||||
filesystem.delete_directory_if_empty(os.path.dirname(file_path))
|
|
||||||
filesystem.delete_directory_if_empty(os.path.dirname(os.path.dirname(file_path)))
|
|
||||||
|
|
||||||
db = Db()
|
|
||||||
filesystem = FileSystem()
|
|
||||||
args = arguments.parse(sys.argv[1:], None, ['title=','album=','time=','location=','process='], './update.py --time=<string time> --location=<string location> --process=no file1 file2...fileN')
|
|
||||||
config = parse_arguments(args)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(config, sys.argv)
|
|
||||||
sys.exit(0)
|
|
Loading…
Reference in New Issue