pymv reads file names listed in an xml file and moves them to a
directory. It can also move files not listed in the xml file to the
directory.
"""moves files listed in xml file to dst directory."""
import sys, os, shutil, optparse, re
from xml.dom import minidom
def domv(src, dst, simulate=True):
"mv src dst"
if (not simulate) and os.path.exists(src):
try:
shutil.move(src,dst)
except IOError, err:
print err.message
except OSError, err:
print err.message
def mkre(s):
"""*.mp3 => ^.*\.mp3$"""
return '^%s$' % re.escape(s).replace('\*', '.*')
def get_nodes(xmldoc, base, tag, attrib, value, no_attrib, from_attrib):
"""retrieves file names from nodes that looks like:
<tag attrib="value">filename.txt</tag> => base/filename.txt
when no_attrib=True, attrib="value" is not tested."""
elements = xmldoc.getElementsByTagName(tag)
if (attrib is None) or (value is None): #attribute not given.
no_attrib = True #don't filter using attribute
from_attrib = False #don't get filename from attribute
if no_attrib: #don't want to filter using attribute
attrib_test = lambda x: True
else: #want to filter using attribute
print mkre(value)
attrib_test = lambda x: re.match(mkre(value), str(x))
if from_attrib: #get filenames from attrib
result = []
for x in elements:
attribute = x.getAttribute(attrib)
if attrib_test(attribute):
result.append(os.path.join(base, attribute))
return result
#get filenames from node.data
return [os.path.join(base, x.firstChild.data)
for x in elements
if attrib_test(x.getAttribute(attrib)) and x.hasChildNodes()]
def main(argv=None):
if argv is None:
argv = sys.argv
cliparser = optparse.OptionParser(
usage='Usage: %prog [options] xml destdir')
cliparser.add_option('-f', '--flip'
, action="store_true"
, help="moves files not listed in xml [default: %default]")
cliparser.add_option('-b', '--base'
, help="location of files listed in xml [default: where xml is located]")
cliparser.add_option('-t', '--tag'
, help="tag name to be searched for file names [default: %default]")
cliparser.add_option('-a', '--attrib'
, help="attributes to match [default: %default]")
cliparser.add_option('-v', '--attrib-val'
, help="attribute value to match. * matches everything. *.mp3 matches attrib=\"anything.mp3\" [default: %default]")
cliparser.add_option('-n', '--no-attrib'
, action="store_true"
, help="don't test for attrib when selecting xml node [default: %default]")
cliparser.add_option('-s', '--simulate'
, action="store_true"
, help="simulate. don't actually move files [default: %default]")
cliparser.add_option('--from-attrib'
, action="store_true"
, help="get filename from attribute, not from node.data [default: %default]")
cliparser.set_defaults(flip=False
, tag="file"
, attrib=None
, attrib_val=None
, no_attrib=False
, simulate=False
, from_attrib=False)
(options, args) = cliparser.parse_args()
arg_len = len(args)
if arg_len < 2:
cliparser.error("should pass xml, destdir")
xmlf = os.path.abspath(args[0])
dst = os.path.abspath(args[1])
if options.base:
base = os.path.abspath(options.base)
else:
#set to where xmlf is located
base = os.path.dirname(xmlf)
tag = options.tag
attrib = options.attrib
value = options.attrib_val
no_attrib = options.no_attrib
simulate = options.simulate
from_attrib = options.from_attrib
xmldoc = minidom.parse(xmlf)
print 'Searching nodes: <%s %s="%s">' % (tag, attrib, value)
filenames = get_nodes(xmldoc, base, tag, attrib, value
, no_attrib, from_attrib)
if simulate:
for x in filenames:
print x
if not os.path.exists(dst):
print "%(dst)s doesn't exist. Creating %(dst)s" % {'dst':dst}
if not simulate:
os.mkdir(dst)
elif not os.path.isdir(dst): #dst exists but not directory.
print """%(dst)s exists. And it's not a directory.
Make sure %(dst)s is a directory.""" % {'dst':dst}
sys.exit(1)
if options.flip:
for x in os.listdir(base):
src = os.path.join(base, x)
if os.path.isfile(src)\
and (src not in filenames)\
and (not src == xmlf):
print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
domv(src, dst, simulate)
else:
for x in filenames:
print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
domv(x, dst, simulate)
if __name__ == "__main__":
main()
pymv reads file names listed in an xml file and moves them to a directory. It can also move files not listed in the xml file to the directory.
"""moves files listed in xml file to dst directory."""
import sys, os, shutil, optparse, re
from xml.dom import minidom
def domv(src, dst, simulate=True):
"mv src dst"
if (not simulate) and os.path.exists(src):
try:
shutil.move(src,dst)
except IOError, err:
print err.message
except OSError, err:
print err.message
def mkre(s):
"""*.mp3 => ^.*\.mp3$"""
return '^%s$' % re.escape(s).replace('\*', '.*')
def get_nodes(xmldoc, base, tag, attrib, value, no_attrib, from_attrib):
"""retrieves file names from nodes that looks like:
<tag attrib="value">filename.txt</tag> => base/filename.txt
when no_attrib=True, attrib="value" is not tested."""
elements = xmldoc.getElementsByTagName(tag)
if (attrib is None) or (value is None): #attribute not given.
no_attrib = True #don't filter using attribute
from_attrib = False #don't get filename from attribute
if no_attrib: #don't want to filter using attribute
attrib_test = lambda x: True
else: #want to filter using attribute
print mkre(value)
attrib_test = lambda x: re.match(mkre(value), str(x))
if from_attrib: #get filenames from attrib
result = []
for x in elements:
attribute = x.getAttribute(attrib)
if attrib_test(attribute):
result.append(os.path.join(base, attribute))
return result
#get filenames from node.data
return [os.path.join(base, x.firstChild.data)
for x in elements
if attrib_test(x.getAttribute(attrib)) and x.hasChildNodes()]
def main(argv=None):
if argv is None:
argv = sys.argv
cliparser = optparse.OptionParser(
usage='Usage: %prog [options] xml destdir')
cliparser.add_option('-f', '--flip'
, action="store_true"
, help="moves files not listed in xml [default: %default]")
cliparser.add_option('-b', '--base'
, help="location of files listed in xml [default: where xml is located]")
cliparser.add_option('-t', '--tag'
, help="tag name to be searched for file names [default: %default]")
cliparser.add_option('-a', '--attrib'
, help="attributes to match [default: %default]")
cliparser.add_option('-v', '--attrib-val'
, help="attribute value to match. * matches everything. *.mp3 matches attrib=\"anything.mp3\" [default: %default]")
cliparser.add_option('-n', '--no-attrib'
, action="store_true"
, help="don't test for attrib when selecting xml node [default: %default]")
cliparser.add_option('-s', '--simulate'
, action="store_true"
, help="simulate. don't actually move files [default: %default]")
cliparser.add_option('--from-attrib'
, action="store_true"
, help="get filename from attribute, not from node.data [default: %default]")
cliparser.set_defaults(flip=False
, tag="file"
, attrib=None
, attrib_val=None
, no_attrib=False
, simulate=False
, from_attrib=False)
(options, args) = cliparser.parse_args()
arg_len = len(args)
if arg_len < 2:
cliparser.error("should pass xml, destdir")
xmlf = os.path.abspath(args[0])
dst = os.path.abspath(args[1])
if options.base:
base = os.path.abspath(options.base)
else:
#set to where xmlf is located
base = os.path.dirname(xmlf)
tag = options.tag
attrib = options.attrib
value = options.attrib_val
no_attrib = options.no_attrib
simulate = options.simulate
from_attrib = options.from_attrib
xmldoc = minidom.parse(xmlf)
print 'Searching nodes: <%s %s="%s">' % (tag, attrib, value)
filenames = get_nodes(xmldoc, base, tag, attrib, value
, no_attrib, from_attrib)
if simulate:
for x in filenames:
print x
if not os.path.exists(dst):
print "%(dst)s doesn't exist. Creating %(dst)s" % {'dst':dst}
if not simulate:
os.mkdir(dst)
elif not os.path.isdir(dst): #dst exists but not directory.
print """%(dst)s exists. And it's not a directory.
Make sure %(dst)s is a directory.""" % {'dst':dst}
sys.exit(1)
if options.flip:
for x in os.listdir(base):
src = os.path.join(base, x)
if os.path.isfile(src)\
and (src not in filenames)\
and (not src == xmlf):
print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
domv(src, dst, simulate)
else:
for x in filenames:
print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
domv(x, dst, simulate)
if __name__ == "__main__":
main()