<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Script for simultaneously copying the pictures from up to 6 cameras.
The primary goal is to copy the pictures from 4 action-cams, make groups of pictures with a cutoff time, create
a subfolder for each cam and copy the renamed pictures (timestamp added to the filename).
Let's say you have two cams, with sd cards named "front" and "back".

front sdcard :
ROOT/DCIM/YDXJ0025.jpg (timestamp is 2017-02-01_11h21mn10s)
ROOT/DCIM/YDXJ0026.jpg (timestamp is 2017-02-01_11h21mn11s)
ROOT/DCIM/YDXJ0027.jpg (timestamp is 2017-02-01_11h21mn12s)
ROOT/DCIM/YDXJ0028.jpg (timestamp is 2017-02-01_11h26mn42s)
ROOT/DCIM/YDXJ0029.jpg (timestamp is 2017-02-01_11h26mn43s)

back sdcard :
ROOT/DCIM/YDXJ0112.jpg (timestamp is 2017-02-01_11h21mn10s)
ROOT/DCIM/YDXJ0113.jpg (timestamp is 2017-02-01_11h21mn11s)
ROOT/DCIM/YDXJ0114.jpg (timestamp is 2017-02-01_11h21mn12s)
ROOT/DCIM/YDXJ0115.jpg (timestamp is 2017-02-01_11h26mn42s)
ROOT/DCIM/YDXJ0116.jpg (timestamp is 2017-02-01_11h26mn43s)

with the command:
python copy_pic ~/test -s front,back  -c 60

In your test folder you will get:
2017-02-01_11h21mn10s|
			 |front|
				   |2017-02-01_11h21mn10s-Cam_front-YDXJ0025.jpg
			   |2017-02-01_11h21mn11s-Cam_front-YDXJ0026.jpg
			   |2017-02-01_11h21mn12s-Cam_front-YDXJ0027.jpg
			 |back |
			   |2017-02-01_11h21mn10s-Cam_back-YDXJ0112.jpg
			   |2017-02-01_11h21mn11s-Cam_back-YDXJ0113.jpg
			   |2017-02-01_11h21mn12s-Cam_back-YDXJ0114.jpg
2017-02-01_11h26mn42s|
			 |front|
				   |2017-02-01_11h26mn42s-Cam_front-YDXJ0028.jpg
			   |2017-02-01_11h26mn43s-Cam_front-YDXJ0029.jpg
			 |back |
				   |2017-02-01_11h26mn42s-Cam_back-YDXJ0115.jpg
			   |2017-02-01_11h26mn43s-Cam_back-YDXJ0116.jpg


#source : http://stackoverflow.com/questions/12672981/python-os-independent-list-of-available-storage-devices
"""
""" TODO :
- Add a parameter to skip the "group to copy" question
- Calculate the total size to copy, and the space left on the destination
"""
import os, subprocess, sys, pyexiv2, datetime, shutil, time, argparse
from threading import Thread
from Queue import Queue


def arg_parse():
    """ Parse the command line you use to launch the script """
    parser = argparse.ArgumentParser(description="A tool to copy pictures from multiple external sources",
                                     version="0.01")

    parser.add_argument("destination", nargs="?", help="Path destination for the pictures", default=os.getcwd())
    parser.add_argument("-s", "--source", help="Name of the volume's sources", default="avant, droite, arriere, gauche")
    parser.add_argument("-c", "--cut", help="Min time between two pictures to create a new group (in seconds)",
                        default=10, type=int)
    parser.add_argument("-a", "--allgroups", help="Copy all groups of pictures without asking.", action="store_true")
    args = parser.parse_args()
    print(args)
    return args


def list_jpg(directory, camid=None):
    """ Search for all the jpg found in a folder and all the subfolders

	Return a list of list containing the camid, the complete path of the
	picture (string), and his DatetimeOriginal (datetime object from the Exif header)
	[['camid', '/mypath/mydirectory/mypicture.jpg', 'datetime.datetime']]
	"""

    file_list = []
    for root, subfolders, files in os.walk(directory):
        file_list += [os.path.join(root, filename) for filename in files if filename.lower().endswith(".jpg")]
    files = []
    # get DateTimeOriginal data from the images and sort the list by timestamp
    for filepath in file_list:
        metadata = pyexiv2.ImageMetadata(filepath)
        metadata.read()
        try:
            t = metadata["Exif.Photo.DateTimeOriginal"].value
            # print t
            # print type(t)
            # s = metadata["Exif.Photo.SubSecTimeOriginal"].value
            files.append([camid, filepath, t])
        except KeyError, e:
            # if any of the required tags are not set the image is not added to the list
            print("Skipping {0}: {1}".format(filename, e))

    # files.sort(key=lambda timestamp: timestamp[1])
    # print_list(files)
    return files


# return file_list

def get_drive_path(volumename, alldrivelist, drive_type=None):
    """Return the drive letter (windows) or mount point (linux) of a volume's name

	volumename is the name of the volume you want the mount point.

	alldrivelist is a list of drives or volume:
	- Windows: The list should be a list of list, like [['M6500', 3, 'C:', 'OS', 'BEACZ44B'], ['M6500', 3, 'G:', 'FRONT', '964D8E43']]
	with 'M6500', the hostname (string), 3, the drive type (int), 'C:' the drive letter (string),
	'OS' the drive name (string), and 'BEACZ44B' as the drive serial number (string)
	
	- Gnu/Linux: The list should be the /proc/mounts files content, filtered (only dev/sdx lines)

	drive_type could be use to include only some type of drive e.g. only the removable drive (Windows only)
	"""
    if drive_type != None:
        alldrivelist = [drive for drive in alldrivelist if drive[drive_type_index] == drive_type]
    if 'win32' in sys.platform:
        for drive in alldrivelist:
            if drive[3].lower() == volumename:
                return drive[2]
    elif 'linux' in sys.platform:
        for drive in alldrivelist:
            for elt in drive.split():
                if volumename in elt.lower():
                    return elt
    elif 'darwin' in sys.platform:
        for drive in alldrivelist:
            if drive.lower() == volumename.lower():
                return "/Volumes/" + drive


def get_drivelist():
    """Return a list of drives connected to the computer
	- Windows:  return host, name,volumename, drivetype, volumeserialnumber
	- Gnu/Linux: /proc/mounts files content, filtered (only dev/sdx lines)
	"""
    if 'win32' in sys.platform:
        drivelist = subprocess.Popen('wmic logicaldisk get name,volumename, drivetype, volumeserialnumber /format:CSV',
                                     shell=True, stdout=subprocess.PIPE)
        drivelistout, err = drivelist.communicate()
        drivelist = drivelistout.replace("\r", "").split("\n")
        drivelist = [drive.split(",") for drive in drivelist if drive != ""]
        drive_type_index = drivelist[0].index("DriveType")
        drive_letter_index = drivelist[0].index("Name")
        volume_name_index = drivelist[0].index("VolumeName")
        del drivelist[0]  # Delete columns name
        for drive in drivelist:  # convert drive type to integer
            drive[drive_type_index] = int(drive[drive_type_index])
            # drivefiltered = [drive for drive in drivelist if drive[drive_type_index] == str(2)] #We keep only the drives with type 2

<commit_msg>More lower() for volumename check<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Script for simultaneously copying the pictures from up to 6 cameras.
The primary goal is to copy the pictures from 4 action-cams, make groups of pictures with a cutoff time, create
a subfolder for each cam and copy the renamed pictures (timestamp added to the filename).
Let's say you have two cams, with sd cards named "front" and "back".

front sdcard :
ROOT/DCIM/YDXJ0025.jpg (timestamp is 2017-02-01_11h21mn10s)
ROOT/DCIM/YDXJ0026.jpg (timestamp is 2017-02-01_11h21mn11s)
ROOT/DCIM/YDXJ0027.jpg (timestamp is 2017-02-01_11h21mn12s)
ROOT/DCIM/YDXJ0028.jpg (timestamp is 2017-02-01_11h26mn42s)
ROOT/DCIM/YDXJ0029.jpg (timestamp is 2017-02-01_11h26mn43s)

back sdcard :
ROOT/DCIM/YDXJ0112.jpg (timestamp is 2017-02-01_11h21mn10s)
ROOT/DCIM/YDXJ0113.jpg (timestamp is 2017-02-01_11h21mn11s)
ROOT/DCIM/YDXJ0114.jpg (timestamp is 2017-02-01_11h21mn12s)
ROOT/DCIM/YDXJ0115.jpg (timestamp is 2017-02-01_11h26mn42s)
ROOT/DCIM/YDXJ0116.jpg (timestamp is 2017-02-01_11h26mn43s)

with the command:
python copy_pic ~/test -s front,back  -c 60

In your test folder you will get:
2017-02-01_11h21mn10s|
			 |front|
				   |2017-02-01_11h21mn10s-Cam_front-YDXJ0025.jpg
			   |2017-02-01_11h21mn11s-Cam_front-YDXJ0026.jpg
			   |2017-02-01_11h21mn12s-Cam_front-YDXJ0027.jpg
			 |back |
			   |2017-02-01_11h21mn10s-Cam_back-YDXJ0112.jpg
			   |2017-02-01_11h21mn11s-Cam_back-YDXJ0113.jpg
			   |2017-02-01_11h21mn12s-Cam_back-YDXJ0114.jpg
2017-02-01_11h26mn42s|
			 |front|
				   |2017-02-01_11h26mn42s-Cam_front-YDXJ0028.jpg
			   |2017-02-01_11h26mn43s-Cam_front-YDXJ0029.jpg
			 |back |
				   |2017-02-01_11h26mn42s-Cam_back-YDXJ0115.jpg
			   |2017-02-01_11h26mn43s-Cam_back-YDXJ0116.jpg


#source : http://stackoverflow.com/questions/12672981/python-os-independent-list-of-available-storage-devices
"""
""" TODO :
- Add a parameter to skip the "group to copy" question
- Calculate the total size to copy, and the space left on the destination
"""
import os, subprocess, sys, pyexiv2, datetime, shutil, time, argparse
from threading import Thread
from Queue import Queue


def arg_parse():
    """ Parse the command line you use to launch the script """
    parser = argparse.ArgumentParser(description="A tool to copy pictures from multiple external sources",
                                     version="0.01")

    parser.add_argument("destination", nargs="?", help="Path destination for the pictures", default=os.getcwd())
    parser.add_argument("-s", "--source", help="Name of the volume's sources", default="avant, droite, arriere, gauche")
    parser.add_argument("-c", "--cut", help="Min time between two pictures to create a new group (in seconds)",
                        default=10, type=int)
    parser.add_argument("-a", "--allgroups", help="Copy all groups of pictures without asking.", action="store_true")
    args = parser.parse_args()
    print(args)
    return args


def list_jpg(directory, camid=None):
    """ Search for all the jpg found in a folder and all the subfolders

	Return a list of list containing the camid, the complete path of the
	picture (string), and his DatetimeOriginal (datetime object from the Exif header)
	[['camid', '/mypath/mydirectory/mypicture.jpg', 'datetime.datetime']]
	"""

    file_list = []
    for root, subfolders, files in os.walk(directory):
        file_list += [os.path.join(root, filename) for filename in files if filename.lower().endswith(".jpg")]
    files = []
    # get DateTimeOriginal data from the images and sort the list by timestamp
    for filepath in file_list:
        metadata = pyexiv2.ImageMetadata(filepath)
        metadata.read()
        try:
            t = metadata["Exif.Photo.DateTimeOriginal"].value
            # print t
            # print type(t)
            # s = metadata["Exif.Photo.SubSecTimeOriginal"].value
            files.append([camid, filepath, t])
        except KeyError, e:
            # if any of the required tags are not set the image is not added to the list
            print("Skipping {0}: {1}".format(filename, e))

    # files.sort(key=lambda timestamp: timestamp[1])
    # print_list(files)
    return files


# return file_list

def get_drive_path(volumename, alldrivelist, drive_type=None):
    """Return the drive letter (windows) or mount point (linux) of a volume's name

	volumename is the name of the volume you want the mount point.

	alldrivelist is a list of drives or volume:
	- Windows: The list should be a list of list, like [['M6500', 3, 'C:', 'OS', 'BEACZ44B'], ['M6500', 3, 'G:', 'FRONT', '964D8E43']]
	with 'M6500', the hostname (string), 3, the drive type (int), 'C:' the drive letter (string),
	'OS' the drive name (string), and 'BEACZ44B' as the drive serial number (string)
	
	- Gnu/Linux: The list should be the /proc/mounts files content, filtered (only dev/sdx lines)

	drive_type could be use to include only some type of drive e.g. only the removable drive (Windows only)
	"""
    if drive_type != None:
        alldrivelist = [drive for drive in alldrivelist if drive[drive_type_index] == drive_type]
    if 'win32' in sys.platform:
        for drive in alldrivelist:
            if drive[3].lower() == volumename.lower():
                return drive[2]
    elif 'linux' in sys.platform:
        for drive in alldrivelist:
            for elt in drive.split():
                if volumename.lower() in elt.lower():
                    return elt
    elif 'darwin' in sys.platform:
        for drive in alldrivelist:
            if drive.lower() == volumename.lower():
                return "/Volumes/" + drive


def get_drivelist():
    """Return a list of drives connected to the computer
	- Windows:  return host, name,volumename, drivetype, volumeserialnumber
	- Gnu/Linux: /proc/mounts files content, filtered (only dev/sdx lines)
	"""
    if 'win32' in sys.platform:
        drivelist = subprocess.Popen('wmic logicaldisk get name,volumename, drivetype, volumeserialnumber /format:CSV',
                                     shell=True, stdout=subprocess.PIPE)
        drivelistout, err = drivelist.communicate()
        drivelist = drivelistout.replace("\r", "").split("\n")
        drivelist = [drive.split(",") for drive in drivelist if drive != ""]
        drive_type_index = drivelist[0].index("DriveType")
        drive_letter_index = drivelist[0].index("Name")
        volume_name_index = drivelist[0].index("VolumeName")
        del drivelist[0]  # Delete columns name
        for drive in drivelist:  # convert drive type to integer
            drive[drive_type_index] = int(drive[drive_type_index])
            # drivefiltered = [drive for drive in drivelist if drive[drive_type_index] == str(2)] #We keep only the drives with type 2


{'fraction_non_alphanumeric': 0.1099290780141844, 'fraction_numerical': 0.06619385342789598, 'mean_word_length': 3.2263502965969404, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2805808', 'n_tokens_mistral': 5131, 'n_tokens_neox': 4409, 'n_words': 1292}