Created
January 15, 2011 00:49
-
-
Save playpauseandstop/780578 to your computer and use it in GitHub Desktop.
Additional wrapper to rsync command with profiles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# Additional wrapper to ``rsync`` command with profiles. | |
# | |
# Requirements | |
# ============ | |
# | |
# * Python_ 2.4 or higher | |
# * rsync_ | |
# | |
# .. _Python: http://www.python.org/ | |
# .. _rsync: http://rsync.samba.org/ | |
# | |
# Installation | |
# ============ | |
# | |
# Place ``sync-it`` somewhere in your ``$PATH`` and give it necessary | |
# permissions (``$ chmod +x``). | |
# | |
# Then, create config file with default options to rsync and profiles to sync | |
# and store it on ``~/.config/sync-it/sync-it.conf``. | |
# | |
# Usage | |
# ===== | |
# | |
# $ sync-it [-i] [-o options] profile | |
# | |
# Example of configuration file | |
# ============================= | |
# | |
# :: | |
# | |
# # You cannot use "rsync" as profile name. But, this block is not | |
# # required. | |
# [rsync] | |
# options = --progress -lzuogthvr --compress-level=9 | |
# | |
# [profile] | |
# src = rsync://server/path/to/src/ | |
# dest = /path/to/dest/ | |
# | |
# [other_profile] | |
# options = -avz # You should redefine rsync options for each profile | |
# src = rsync://server/path/to/other_src/ | |
# dest = ~/path/to/other_dest/ # You should use tilda in profile pathes | |
# | |
import os | |
import sys | |
from ConfigParser import ConfigParser, Error as ConfigParserError | |
from optparse import OptionParser | |
from subprocess import Popen | |
# Application settings | |
__usage__ = 'Usage: %prog [-i] [-o options] profile' | |
__version__ = '0.1-alpha' | |
# Necessary global vars | |
RSYNC = 'rsync' | |
def get_options(): | |
""" | |
Build option parser, read profile from arguments passed to script then try | |
to read configuration for this profile and return configuration as | |
``dict`` instance. | |
""" | |
# Build option parser and parse arguments passed to script | |
parser = OptionParser(usage=__usage__, version=__version__) | |
parser.add_option('-i', '--invert', action='store_true', dest='invert', | |
default=False, help='Switch source and destination pathes for ' \ | |
'selected profile.') | |
parser.add_option('-o', '--options', dest='options', default='', | |
help='Redefine global rsync options for selected profile.', | |
metavar='OPTIONS') | |
options, args = parser.parse_args() | |
if not len(args): | |
parser.error("You should pass 'profile' arg to the script.") | |
profile = args[0] | |
if profile == RSYNC: | |
parser.error('%r is reserved system name and you cannot use it as ' \ | |
'profile name.' % RSYNC) | |
# Trying to read user configuration | |
filename = os.path.expanduser('~/.config/sync-it/sync-it.conf') | |
if not os.path.isfile(filename): | |
parser.error('Cannot read configuration from %r. Please, create ' \ | |
'configuration file there first.' % filename) | |
config = ConfigParser() | |
try: | |
config.read(filename) | |
except ConfigParserError: | |
parser.error('Cannot parse configuration from %r. Please, check ' \ | |
'syntax of your configuration file.' % filename) | |
if not profile in config.sections(): | |
parser.error('Cannot find %r section in your configuration file.' % \ | |
profile) | |
# User rsync options should used instead of profile rsync options | |
if options.options: | |
rsync_options = options.options | |
# Profile rsync options should used instead of global rsync options | |
if config.has_option(profile, 'options'): | |
rsync_options = config.get(profile, 'options') | |
elif config.has_option(RSYNC, 'options'): | |
rsync_options = config.get(RSYNC, 'options') | |
else: | |
rsync_options = '' | |
try: | |
dest = os.path.expanduser(config.get(profile, 'dest')) | |
src = os.path.expanduser(config.get(profile, 'src')) | |
except ConfigParserError, e: | |
parser.error(e) | |
return {'dest': options.invert and src or dest, | |
'options': rsync_options, | |
'profile': profile, | |
'src': options.invert and dest or src} | |
def main(): | |
# Read script options | |
options = get_options() | |
# Execute rsync for selected profile | |
rsync(**options) | |
def rsync(profile, src, dest, options): | |
""" | |
Wrapper to executing rsync command. | |
""" | |
cmd = ' '.join((RSYNC, options, src, dest)) | |
print('$ ' + cmd) | |
process = Popen(cmd, shell=True) | |
status = os.waitpid(process.pid, 0)[1] | |
if __name__ == '__main__': | |
try: | |
main() | |
except KeyboardInterrupt: | |
print('OK OK! Exiting immediately...') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment