openmedialibrary_platform_w.../Lib/site-packages/win32/scripts/ce/pysynch.py

248 lines
8 KiB
Python
Raw Normal View History

2016-04-14 19:54:42 +00:00
# Simple CE synchronisation utility with Python features.
import wincerapi
import win32api
import win32file
import getopt
import sys
import os
import string
import win32con
import fnmatch
class InvalidUsage(Exception): pass
def print_error(api_exc, msg):
hr, fn, errmsg = api_exc
print("%s - %s(%d)" % (msg, errmsg, hr))
def GetFileAttributes(file, local=1):
if local: return win32api.GetFileAttributes(file)
else: return wincerapi.CeGetFileAttributes(file)
def FindFiles(spec, local=1):
if local: return win32api.FindFiles(spec)
else: return wincerapi.CeFindFiles(spec)
def isdir(name, local=1):
try:
attr = GetFileAttributes(name, local)
return attr & win32con.FILE_ATTRIBUTE_DIRECTORY
except win32api.error:
return 0
def CopyFileToCe(src_name, dest_name, progress = None):
sh = win32file.CreateFile(src_name, win32con.GENERIC_READ, 0, None, win32con.OPEN_EXISTING, 0, None)
bytes=0
try:
dh = wincerapi.CeCreateFile(dest_name, win32con.GENERIC_WRITE, 0, None, win32con.OPEN_ALWAYS, 0, None)
try:
while 1:
hr, data = win32file.ReadFile(sh, 2048)
if not data:
break
wincerapi.CeWriteFile(dh, data)
bytes = bytes + len(data)
if progress is not None: progress(bytes)
finally:
pass
dh.Close()
finally:
sh.Close()
return bytes
def BuildFileList(spec, local, recurse, filter, filter_args, recursed_path = ""):
files = []
if isdir(spec, local):
path = spec
raw_spec = "*"
else:
path, raw_spec = os.path.split(spec)
if recurse:
# Need full scan, to get sub-direcetories.
infos = FindFiles(os.path.join(path, "*"), local)
else:
infos = FindFiles(os.path.join(path, raw_spec), local)
for info in infos:
src_name = str(info[8])
full_src_name = os.path.join(path, src_name)
if local: # Can't do this for CE!
full_src_name = win32api.GetFullPathName(full_src_name)
if isdir(full_src_name, local) :
if recurse and src_name not in ['.','..']:
new_spec = os.path.join(full_src_name, raw_spec)
files = files + BuildFileList(new_spec, local, 1, filter, filter_args, os.path.join(recursed_path, src_name))
if fnmatch.fnmatch(src_name, raw_spec):
rel_name = os.path.join(recursed_path, src_name)
filter_data = filter( full_src_name, rel_name, info, local, filter_args )
if filter_data is not None:
files.append( (full_src_name, info, filter_data) )
return files
def _copyfilter(full_name, rel_name, info, local, bMaintainDir):
if isdir(full_name, local): return
if bMaintainDir:
return rel_name
return os.path.split(rel_name)[1]
import pywin.dialogs.status, win32ui
class FileCopyProgressDialog(pywin.dialogs.status.CStatusProgressDialog):
def CopyProgress(self, bytes):
self.Set(bytes/1024)
def copy( args ):
"""copy src [src ...], dest
Copy files to/from the CE device
"""
bRecurse = bVerbose = 0
bMaintainDir = 1
try:
opts, args = getopt.getopt(args, "rv")
except getopt.error as details:
raise InvalidUsage(details)
for o, v in opts:
if o=="-r":
bRecuse=1
elif o=='-v':
bVerbose=1
if len(args)<2:
raise InvalidUsage("Must specify a source and destination")
src = args[:-1]
dest = args[-1]
# See if WCE: leading anywhere indicates a direction.
if string.find(src[0], "WCE:")==0:
bToDevice = 0
elif string.find(dest, "WCE:")==0:
bToDevice = 1
else:
# Assume copy to device.
bToDevice = 1
if not isdir(dest, not bToDevice):
print("%s does not indicate a directory")
files = [] # List of FQ (from_name, to_name)
num_files = 0
num_bytes = 0
dialog = FileCopyProgressDialog("Copying files")
dialog.CreateWindow(win32ui.GetMainFrame())
if bToDevice:
for spec in src:
new = BuildFileList(spec, 1, bRecurse, _copyfilter, bMaintainDir)
if not new:
print("Warning: '%s' did not match any files" % (spec))
files = files + new
for full_src, src_info, dest_info in files:
dest_name = os.path.join(dest, dest_info)
size = src_info[5]
print("Size=", size)
if bVerbose:
print(full_src, "->", dest_name,"- ", end=' ')
dialog.SetText(dest_name)
dialog.Set(0, size/1024)
bytes = CopyFileToCe(full_src, dest_name, dialog.CopyProgress)
num_bytes = num_bytes + bytes
if bVerbose:
print(bytes, "bytes")
num_files = num_files + 1
dialog.Close()
print("%d files copied (%d bytes)" % (num_files, num_bytes))
def _dirfilter(*args):
return args[1]
def dir(args):
"""dir directory_name ...
Perform a directory listing on the remote device
"""
bRecurse = 0
try:
opts, args = getopt.getopt(args, "r")
except getopt.error as details:
raise InvalidUsage(details)
for o, v in opts:
if o=="-r":
bRecurse=1
for arg in args:
print("Directory of WCE:%s" % arg)
files = BuildFileList(arg, 0, bRecurse, _dirfilter, None)
total_size=0
for full_name, info, rel_name in files:
date_str = info[3].Format("%d-%b-%Y %H:%M")
attr_string = " "
if info[0] & win32con.FILE_ATTRIBUTE_DIRECTORY: attr_string = "<DIR>"
print("%s %s %10d %s" % (date_str, attr_string, info[5], rel_name))
total_size = total_size + info[5]
print(" " * 14 + "%3d files, %10d bytes" % (len(files), total_size))
def run(args):
"""run program [args]
Starts the specified program on the remote device.
"""
prog_args = []
for arg in args:
if " " in arg:
prog_args.append('"' + arg + '"')
else:
prog_args.append(arg)
prog_args = string.join(prog_args, " ")
wincerapi.CeCreateProcess(prog_args, "", None, None, 0, 0, None, "", None)
def delete(args):
"""delete file, ...
Delete one or more remote files
"""
for arg in args:
try:
wincerapi.CeDeleteFile(arg)
print("Deleted: %s" % arg)
except win32api.error as details:
print_error(details, "Error deleting '%s'" % arg)
def DumpCommands():
print("%-10s - %s" % ("Command", "Description"))
print("%-10s - %s" % ("-------", "-----------"))
for name, item in list(globals().items()):
if type(item)==type(DumpCommands):
doc = getattr(item, "__doc__", "")
if doc:
lines = string.split(doc, "\n")
print("%-10s - %s" % (name, lines[0]))
for line in lines[1:]:
if line:
print(" " * 8, line)
def main():
if len(sys.argv)<2:
print("You must specify a command!")
DumpCommands()
return
command = sys.argv[1]
fn = globals().get(command)
if fn is None:
print("Unknown command:", command)
DumpCommands()
return
wincerapi.CeRapiInit()
try:
verinfo = wincerapi.CeGetVersionEx()
print("Connected to device, CE version %d.%d %s" % (verinfo[0], verinfo[1], verinfo[4]))
try:
fn(sys.argv[2:])
except InvalidUsage as msg:
print("Invalid syntax -", msg)
print(fn.__doc__)
finally:
try:
wincerapi.CeRapiUninit()
except win32api.error as details:
print_error(details, "Error disconnecting")
if __name__=='__main__':
main()