Managing Music Sync with Python

Managing Music Sync with Python

4/17/2016


Introduction

So my mom has this really old mp3 player that she does not want to part ways with. While I don't blame her because it works perfectly fine, we had some trouble getting the mp3 player to sync with her new music. This used to work fine, but after she got a new computer we just couldn't get the sync to work. I know what you're thinking, "All you have to do is drag and drop your new files to your mp3 memory." I know this. However, having a tech-illiterate parent, it's hard for her to do this and remember. So, I just wrote her a program that would do this for her.


Program Structure

Like I mentioned above, I needed this program to identify any new songs in my mom's downloads folder and automatically send them over to her mp3 player. So, what I did was first create a database. Everytime the program is run (I just have her click the file icon when she plugs in her mp3 player), I fetch the latest timestamp, then enter the current timestamp. The latest timestamp will be the last time she ran the program. Then I check that date with the modify date of all files ending with ".mp3" (we're ignoring other formats because she only downloads mp3's from Amazon), and any dates that are newer than the last timestamp will get moved over. Pretty simple, right?


Building the Database

I usually like to build my databases straight in python using sqlite3 because it's super easy. Below is the script that I used to create the DB.


import sqlite3
import datetime

conn = sqlite3.connect('musicManager.db', detect_types=sqlite3.PARSE_DECLTYPES)
c = conn.cursor()
c.execute('''CREATE TABLE rundate
	(
	currentDate timestamp)
	''')
conn.commit()
cur = conn.cursor()
cur.execute("INSERT INTO rundate VALUES(?)", (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),))
conn.commit()
conn.close()

In the script above, you can see the first thing I'm doing is actually creating the database. After that though, I had to enter in the current timestamp. This is because, like I mentioned above, one of the first things in the program that I do is fetch the latest timestamp. So, if I didn't enter the timestamp when I created the DB, the first run of the program would result in an error.


Python Program

Next up is the actual python program that's doing the work. I'm just going to put it all in one chunk, since the program isn't too big.


import sys
import datetime
import time
import os
import shutil
import sqlite3

sys.stdout.write("Mom's Music Manager!" + '\n')
con = sqlite3.connect('musicManager.db')
cur = con.cursor()

def getLastTime():

	# Get the last time the program was ran
	cur.execute("SELECT currentDate FROM rundate ORDER BY currentDate DESC LIMIT 1")
	lastDate = cur.fetchone()
	sys.stdout.write("Last run date was: " + lastDate[0] + '\n')

	# Insert the current timestamp
	cur.execute("INSERT INTO rundate VALUES(?)", (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),))
	con.commit()

	return lastDate

def moveFiles():

	lastDate = getLastTime()

	# Path where the mp3's are stored
	currentPath = "C:\\users\\mom\\downloads"

	# Path where the mp3 player is
	destPath = "E:\\Desktop\\test"

	try:
		# Loop through each mp3 file
		for musicFile in os.listdir(currentPath):
			if musicFile.endswith(".mp3"):

				# Get the mp3's last modified date
				fileTime = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getmtime(currentPath + '\\' + musicFile)))

				# If it's new, then move it over to the mp3 player
				if fileTime < lastDate[0]:
					sys.stdout.write("Moving song: " + musicFile + '\n')
					shutil.move(currentPath + '\\' + musicFile, destPath)
		sys.stdout.write('\n' + "All done!")

	except:
		sys.stdout.write("Be sure the folder with your music is closed. Try it again." + '\n')
		sys.stdout.write("If that still doesn't work, call Dave.")


if __name__ == '__main__':
	moveFiles();

And there's the program. It's working perfectly! If you have any questions or corrections, feel free to let me know in the comments. You can check out the Github repo for this project here. Thanks for reading!



Check out more posts in the Python category!