123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- # 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()
|