Python ftpsync

I modified this script, it supports explicit SSL. Also, had to fix a bug, it only stores the filename, so if you have pictures in their own folders, and some have the same name, it won’t work, it’ll upload the file. Now it stores the path, and the “os.stat(path).st_mtime”, no converting it to a readable format.
And .ftpsync is stored in the folder you run it in, the folder you sync. Don’t see the point in uploading that. I made a script to generate that file too. And it checks if the time in the file is less then, instead of not equal to. Might not matter which way you do it though.
The script isn’t done. Got to add the other parameters to argparse.
And it works in Python 3 now, you might need it for the explicit SSL patch to work.
Script with a bunch of stolen code below, for generating the .ftpsync file. I wanted to do it, because I already uploaded the files some other way. No point in uploading everything again.
gen_sync_file.py

#!/usr/bin/env python
import os, sys, pickle, re, argparse
parser = argparse.ArgumentParser()
parser.add_argument('--f', default=False,
                    help='file to look for in .ftpsync')
parser.add_argument('--d', default=False)
args = parser.parse_args()
findinsync = args.f
checkdate = args.d
ignored = []
timetable = {}
def get_ignored(filename):
    global ignored
    ignore_file = open(os.path.join(os.getcwd(), filename))
    for line in ignore_file.readlines():
        if line.strip()[:1] != "#": ignored.append(line.strip())
    ignore_file.close()
def is_ignored(filename):
    global ignored
    for ignore in ignored:
        pattern = ignore.replace('*', '(.*)')
        compiled = re.compile(pattern)
        if compiled.search(filename):
            return True
    return False
def gen_sync_file(localdir):
	global f
	global timetable
	# Recursive directories
	for file in os.listdir(localdir):
		path = os.path.join(localdir, file)
		if not is_ignored(file):
			if os.path.isfile(path) and file != '.ftpignore' and file != '.ftpsync':
				localtime = os.stat(path).st_mtime
				print(path)
				print(localtime)
				print("Localtime:" + str(localtime))
				timetable[path] = localtime
				print("Saving:" + str(timetable[path]))
			if os.path.isdir(path):
				gen_sync_file(path)
if findinsync == False and checkdate == False:
	if os.path.isfile(".ftpignore"):
		get_ignored(".ftpignore")
	if os.path.isfile(".ftpsync"):
		print(".ftpsync exists!")
		exit()
	gen_sync_file(os.getcwd())
	with open(".ftpsync", "wb") as f:
		f.write(bytes(pickle.dumps(timetable)))
	#for ftime in timetable:
		#print(ftime + ":" + str(timetable[ftime]))
if findinsync != False:
	try:
		f = open(".ftpsync", "rb")
		timetable = pickle.loads(f.read())
		if findinsync == 'all':
			print(timetable)
			print(len(timetable))
		else:
			print(timetable[findinsync])
	except Exception as e:
		print (e)
	f.close
if checkdate != False:
	print(os.stat(checkdate).st_mtime)

And you could change all the files to with open.
You can write apps for your phone with Python. I tried two different FTP programs, they won’t show anything. One did once, but not anymore. Tapping a folder and nothing was in it.
License for the stolen code:

MIT License
Copyright (c) 2013-2017 Dariusz Dawidowski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Also, can you resume FTP uploads in Python? Got to add that before releasing it. That may never happen though. To lazy, and it works. To lazy to add the other options to the argparser.
You can download gen_sync_file.py.
It has other options too, when I was debugging it, I was trying to figure out why the date was wrong, because more then one file has the same name.
–d path/to/any/file will tell you the mtime of the file. –f will tell you the stored value, didn’t test that since changing it to path, but it should work if you enter the full path.
And if it says invalid login, pass it in ‘ instead of “.
Update
ftpsync
I didn’t really test the -c and –delete arguments, don’t need them.

ftpsync v2.0.0
usage: ftpsync [-h] [-p port] [--ssl] [-c [C [C ...]]] [--delete] server
positional arguments:
  server          user:password@server/path/to/folder
optional arguments:
  -h, --help      show this help message and exit
  -p port         port
  --ssl           enable SSL
  -c [C [C ...]]  run raw FTP command
  --delete        delete non-existing files on server side

Update
Moved the ftpsync script here.