Skip to content

Instantly share code, notes, and snippets.

@dentearl
Created November 24, 2012 01:31
Show Gist options
  • Save dentearl/4137988 to your computer and use it in GitHub Desktop.
Save dentearl/4137988 to your computer and use it in GitHub Desktop.
python and launchd script to create a MacOSX s3 based dropbox
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>com.whatever.s3upload</string>
<key>ProgramArguments</key>
<array>
<string>/Users/yourname/bin/s3upload.py</string>
</array>
<key>QueueDirectories</key>
<array>
<string>/Users/yourname/s3/inbox</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>onDemand</key>
<true/>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/com.whatever.s3upload.plist # load the plist
launchctl list | grep s3upload # verify it's been loaded
launchctl unload ~/Library/LaunchAgents/com.whatever.s3upload.plist # unload the plist for whatever reason
#!/usr/bin/env python
"""
script to upload all items in ~/s3
to my amazon s3 account and make them publically share-able
to be controlled by a launchd rule that watches the directory
~/s3
launchctl load ~/Library/LaunchAgents/com.whatever.s3upload.plist
launchctl list | grep s3upload
launchctl unload ~/Library/LaunchAgents/com.whatever.s3upload.plist
"""
from argparse import ArgumentParser
import boto
import glob
import os
def initOptions(parser):
parser.add_argument('--bucket', dest='bucket', type=str, default='YOUR_BUCKET',
help='bucket to upload to. default=%(default)s')
parser.add_argument('--dir', dest='path', type=str,
default=os.path.expanduser(os.path.join('~', 's3', 'inbox')),
help='directory whose contents are to be uploaded. default=%(default)s')
def checkArgs(args, parser):
if args.bucket is None:
parser.error('Specify --bucket')
if args.path is None:
parser.error('Specify --dir')
if not os.path.exists(args.path):
parser.error('--dir %s does not exist' % args.path)
if not os.path.isdir(args.path):
parser.error('--dir %s is not a directory' % args.path)
def getFiles(args):
tempFiles = glob.glob(os.path.join(args.path, '*'))
files = []
for t in tempFiles:
t = os.path.realpath(t)
if not os.path.basename(t).startswith('.'):
files.append(t)
return files
def uploadFiles(files, args):
if files is None:
return
s3 = boto.connect_s3()
bucket = s3.get_bucket(args.bucket)
for f in files:
key = bucket.new_key(os.path.basename(f))
key.set_contents_from_filename(f)
key.set_acl('public-read')
# move file out of inbox and up one directory into s3
os.rename(f, os.path.join(os.path.dirname(args.path), os.path.basename(f)))
def cleanup(args):
if os.path.exists(os.path.join(args.path, '.DS_Store')):
# The mac adds this meta data file that will cause the
# launchd to restart the script every ~9 seconds. This
# is visible in Console.app with infinitely repeat lines like:
# 11/23/12 5:20:43.550 PM com.apple.launchd.peruser.501[332]: (com.whatever.s3upload) Throttling respawn: Will start in 9 seconds
# It is normal to see 3-4 of these each time the directory changes.
os.unlink(os.path.join(args.path, '.DS_Store'))
def main():
parser = ArgumentParser()
initOptions(parser)
args = parser.parse_args()
checkArgs(args, parser)
files = getFiles(args)
uploadFiles(files, args)
cleanup(args)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment