Skip to content

Instantly share code, notes, and snippets.

@kaitwalla
Created September 2, 2017 04:19
Show Gist options
  • Save kaitwalla/d38427855c73e1d2ba30a5a338a779f6 to your computer and use it in GitHub Desktop.
Save kaitwalla/d38427855c73e1d2ba30a5a338a779f6 to your computer and use it in GitHub Desktop.
A small utility for copying music to a folder with a limit on the number of files per folder (copying music to a USB drive for use in a car)
{"Folders" :
{
"Comedy": false,
"Famous": false,
"Mellow": false,
"Mixes": ["Youtube Mixes"],
"Musicals": false,
"OST - Instrumental": false,
"Standup": false,
"XMas": false
}
}
''' This little command-line utility takes music in an existing folder structure and copies it to a
destination, flattening it out to a single level in the process.
The specific use case is I wanted to copy my music from my collection to the USB drive for my car,
which has a limit of 255 files in a folder. There's an optional third argument if you want to exclude
top or second-level folders; just build a JSON file, and pass the file location
as the third argument.
Exmaple usage:
music_to_usb.py '/Volumes/HDD/Music' '/Volumes/CAR_USB'
music_to_usb.py '/Volumes/HDD/Music' '/Volumes/CAR_USB' 'folders_to_skip.json'
In the JSON file, if you want to exclude second-level folders, just include
them as an array as the parameter of the top-level folder; the top-level folder will not be skipped,
only the specified subfolders. If you want the whole top-level folder skipped, the value
should be false.
skip_folder_json_template:
{"Folders :
{
"Top Level Folder 1": false,
"Only Skip Second Level Folders" : [ "Sub Folder 1", "Sub Folder 2" ],
"Only One Subfolder" : ['Sub Folder 1" ],
"Whole Folder" : false
}
}
'''
import os
import sys
import json
import re
import shutil
if (len(sys.argv) < 3):
print('You need to provide a destination and source folder')
exit()
regex_hidden_folder = '^\..*'
folder_to_copy_from = sys.argv[1]
folder_to_copy_to = sys.argv[2]
def true_false():
while True:
prompt = 'Make sure ' + folder_to_copy_to + ' is empty, otherwise it will fail if there are folders with the same name. To continue, type "Yes" > '
answer = input(prompt).lower()
if answer == 'yes':
return True
else:
return False
if not true_false():
exit()
def make_destination_folder(destination, source, folder_count):
os.makedirs(destination + '/' + source + '-' + str(folder_count) )
def copy_folder(source):
copy_from = folder_to_copy_from + '/' + source
folder_count = 0
file_count = 0
for root, dirs, files in os.walk(copy_from):
for f in files:
# Hidden files
if f[0] == '.':
continue
# If not audio files that can be played in most cars
if f[-3:] != 'mp3' and f[-3:] != 'm4a':
continue
if source in folders_with_ignored_subfolder.keys():
# Get the folder of the file we're working in
current_folder = root.split(source+'/')[1]
if current_folder in folders_with_ignored_subfolder[source]:
continue
#If we're just starting out, we need to create our destination folder
if file_count == 0:
folder_count += 1
make_destination_folder(folder_to_copy_to, source, folder_count)
# My car only recognizes 255 files in a folder, so we have to start new folders after we've reached the limit
if file_count == 255:
folder_count += 1
make_destination_folder(folder_to_copy_to, source, folder_count)
file_count = 0
file_count += 1
old_path = root + '/' + f
new_path = folder_to_copy_to + '/' + source + '-' + str(folder_count) + '/' + f
shutil.copy2(old_path,new_path)
if ( len(sys.argv) == 4):
folders_to_ignore = sys.argv[3]
else:
folders_to_ignore = False
if not (os.path.isdir(folder_to_copy_from) and os.path.isdir(folder_to_copy_to) ):
print('Please check your source and destination folders to make sure they exist.')
exit()
if folders_to_ignore:
if os.path.isfile(folders_to_ignore):
with open(folders_to_ignore, 'r') as json_file:
folder_list = json.load(json_file)['Folders']
folders_to_ignore = []
folders_with_ignored_subfolder = {}
for folder, has_subfolder in folder_list.items():
if not has_subfolder:
folders_to_ignore.append(folder)
else:
folders_with_ignored_subfolder[folder] = []
for subfolder in has_subfolder:
folders_with_ignored_subfolder[folder].append(subfolder)
folders_to_copy = os.listdir(folder_to_copy_from)
for folder in folders_to_copy:
if not folders_to_ignore:
if not re.match(regex_hidden_folder, folder):
copy_folder(folder)
else:
# If we need to ignore the folder, or it's a system folder
if (folder in folders_to_ignore or re.match(regex_hidden_folder, folder) ):
continue
else:
copy_folder(folder)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment