home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Shareware / Comunicatii / jyte / jyte.exe / pysynch.py < prev    next >
Text File  |  2000-03-08  |  8KB  |  248 lines

  1. # Simple CE synchronisation utility with Python features.
  2.  
  3. import wincerapi
  4. import win32api
  5. import win32file
  6. import getopt
  7. import sys
  8. import os
  9. import string
  10. import win32con
  11. import fnmatch
  12.  
  13. class InvalidUsage(Exception): pass
  14.  
  15. def print_error(api_exc, msg):
  16.     hr, fn, errmsg = api_exc
  17.     print "%s - %s(%d)" % (msg, errmsg, hr)
  18.  
  19. def GetFileAttributes(file, local=1):
  20.     if local: return win32api.GetFileAttributes(file)
  21.     else: return wincerapi.CeGetFileAttributes(file)
  22.  
  23. def FindFiles(spec, local=1):
  24.     if local: return win32api.FindFiles(spec)
  25.     else: return wincerapi.CeFindFiles(spec)
  26.  
  27. def isdir(name, local=1):
  28.     try:
  29.         attr = GetFileAttributes(name, local)
  30.         return attr & win32con.FILE_ATTRIBUTE_DIRECTORY
  31.     except win32api.error:
  32.         return 0
  33.  
  34. def CopyFileToCe(src_name, dest_name, progress = None):
  35.     sh = win32file.CreateFile(src_name, win32con.GENERIC_READ, 0, None, win32con.OPEN_EXISTING, 0, None)
  36.     bytes=0
  37.     try:
  38.         dh = wincerapi.CeCreateFile(dest_name, win32con.GENERIC_WRITE, 0, None, win32con.OPEN_ALWAYS, 0, None)
  39.         try:
  40.             while 1:
  41.                 hr, data = win32file.ReadFile(sh, 2048)
  42.                 if not data:
  43.                     break
  44.                 wincerapi.CeWriteFile(dh, data)
  45.                 bytes = bytes + len(data)
  46.                 if progress is not None: progress(bytes)
  47.         finally:
  48.             pass
  49.             dh.Close()
  50.     finally:
  51.         sh.Close()
  52.     return bytes
  53.  
  54. def BuildFileList(spec, local, recurse, filter, filter_args, recursed_path = ""):
  55.     files = []
  56.     if isdir(spec, local):
  57.         path = spec
  58.         raw_spec = "*"
  59.     else:
  60.         path, raw_spec = os.path.split(spec)
  61.     if recurse:
  62.         # Need full scan, to get sub-direcetories.
  63.         infos = FindFiles(os.path.join(path, "*"), local)
  64.     else:
  65.         infos = FindFiles(os.path.join(path, raw_spec), local)
  66.     for info in infos:
  67.         src_name = str(info[8])
  68.         full_src_name = os.path.join(path, src_name)
  69.         if local: # Can't do this for CE!
  70.             full_src_name = win32api.GetFullPathName(full_src_name)
  71.         if isdir(full_src_name, local) :
  72.             if recurse and src_name not in ['.','..']:
  73.                 new_spec = os.path.join(full_src_name, raw_spec)
  74.                 files = files + BuildFileList(new_spec, local, 1, filter, filter_args, os.path.join(recursed_path, src_name))
  75.         if fnmatch.fnmatch(src_name, raw_spec):
  76.             rel_name = os.path.join(recursed_path, src_name)
  77.             filter_data = filter( full_src_name, rel_name, info, local, filter_args )
  78.             if filter_data is not None:
  79.                 files.append( (full_src_name, info, filter_data) )
  80.     return files
  81.  
  82. def _copyfilter(full_name, rel_name, info, local, bMaintainDir):
  83.     if isdir(full_name, local): return
  84.     if bMaintainDir:
  85.         return rel_name
  86.     return os.path.split(rel_name)[1]
  87.  
  88. import pywin.dialogs.status, win32ui
  89. class FileCopyProgressDialog(pywin.dialogs.status.CStatusProgressDialog):
  90.     def CopyProgress(self, bytes):
  91.         self.Set(bytes/1024)
  92.  
  93. def copy( args ):
  94.     """copy src [src ...],  dest
  95.     Copy files to/from the CE device
  96.     """
  97.     bRecurse = bVerbose = 0
  98.     bMaintainDir = 1
  99.     try:
  100.         opts, args = getopt.getopt(args, "rv")
  101.     except getopt.error, details:
  102.         raise InvalidUsage(details)
  103.     for o, v in opts:
  104.         if o=="-r":
  105.             bRecuse=1
  106.         elif o=='-v':
  107.             bVerbose=1
  108.  
  109.     if len(args)<2:
  110.         raise InvalidUsage("Must specify a source and destination")
  111.  
  112.     src = args[:-1]
  113.     dest = args[-1]
  114.     # See if WCE: leading anywhere indicates a direction.
  115.     if string.find(src[0], "WCE:")==0:
  116.         bToDevice = 0
  117.     elif string.find(dest, "WCE:")==0:
  118.         bToDevice = 1
  119.     else:
  120.         # Assume copy to device.
  121.         bToDevice = 1
  122.  
  123.     if not isdir(dest, not bToDevice):
  124.         print "%s does not indicate a directory"
  125.  
  126.     files = [] # List of FQ (from_name, to_name)
  127.     num_files = 0
  128.     num_bytes = 0
  129.     dialog = FileCopyProgressDialog("Copying files")
  130.     dialog.CreateWindow(win32ui.GetMainFrame())
  131.     if bToDevice:
  132.         for spec in src:
  133.             new = BuildFileList(spec, 1, bRecurse, _copyfilter, bMaintainDir)
  134.             if not new:
  135.                 print "Warning: '%s' did not match any files" % (spec)
  136.             files = files + new
  137.  
  138.         for full_src, src_info, dest_info in files:
  139.             dest_name = os.path.join(dest, dest_info)
  140.             size = src_info[5]
  141.             print "Size=", size
  142.             if bVerbose:
  143.                 print full_src, "->", dest_name,"- ",
  144.             dialog.SetText(dest_name)
  145.             dialog.Set(0, size/1024)
  146.             bytes = CopyFileToCe(full_src, dest_name, dialog.CopyProgress)
  147.             num_bytes = num_bytes + bytes
  148.             if bVerbose:
  149.                 print bytes, "bytes"
  150.             num_files = num_files + 1
  151.     dialog.Close()
  152.     print "%d files copied (%d bytes)" % (num_files, num_bytes)
  153.  
  154. def _dirfilter(*args):
  155.     return args[1]
  156.  
  157. def dir(args):
  158.     """dir directory_name ...
  159.     Perform a directory listing on the remote device
  160.     """
  161.     bRecurse = 0
  162.     try:
  163.         opts, args = getopt.getopt(args, "r")
  164.     except getopt.error, details:
  165.         raise InvalidUsage(details)
  166.     for o, v in opts:
  167.         if o=="-r":
  168.             bRecurse=1
  169.     for arg in args:
  170.         print "Directory of WCE:%s" % arg
  171.         files = BuildFileList(arg, 0, bRecurse, _dirfilter, None)
  172.         total_size=0
  173.         for full_name, info, rel_name in files:
  174.             date_str = info[3].Format("%d-%b-%Y %H:%M")
  175.             attr_string = "     "
  176.             if info[0] & win32con.FILE_ATTRIBUTE_DIRECTORY: attr_string = "<DIR>"
  177.             print "%s  %s %10d %s" % (date_str, attr_string, info[5], rel_name)
  178.             total_size = total_size + info[5]
  179.         print " " * 14 + "%3d files, %10d bytes" % (len(files), total_size)
  180.  
  181. def run(args):
  182.     """run program [args]
  183.     Starts the specified program on the remote device.
  184.     """
  185.     prog_args = []
  186.     for arg in args:
  187.         if " " in arg:
  188.             prog_args.append('"' + arg + '"')
  189.         else:
  190.             prog_args.append(arg)
  191.     prog_args = string.join(prog_args, " ")
  192.     wincerapi.CeCreateProcess(prog_args, "", None, None, 0, 0, None, "", None)
  193.  
  194. def delete(args):
  195.     """delete file, ...
  196.     Delete one or more remote files
  197.     """
  198.     for arg in args:
  199.         try:
  200.             wincerapi.CeDeleteFile(arg)
  201.             print "Deleted: %s" % arg
  202.         except win32api.error, details:
  203.             print_error(details, "Error deleting '%s'" % arg)
  204.  
  205. def DumpCommands():
  206.     print "%-10s - %s" % ("Command", "Description")
  207.     print "%-10s - %s" % ("-------", "-----------")
  208.     for name, item in globals().items():
  209.         if type(item)==type(DumpCommands):
  210.             doc = getattr(item, "__doc__", "")
  211.             if doc:
  212.                 lines = string.split(doc, "\n")
  213.                 print "%-10s - %s" % (name, lines[0])
  214.                 for line in lines[1:]:
  215.                     if line:
  216.                         print " " * 8, line
  217.  
  218. def main():
  219.     if len(sys.argv)<2:
  220.         print "You must specify a command!"
  221.         DumpCommands()
  222.         return
  223.     command = sys.argv[1]
  224.     fn = globals().get(command)
  225.     if fn is None:
  226.         print "Unknown command:", command
  227.         DumpCommands()
  228.         return
  229.  
  230.     wincerapi.CeRapiInit()
  231.     try:
  232.         verinfo = wincerapi.CeGetVersionEx()
  233.         print "Connected to device, CE version %d.%d %s" % (verinfo[0], verinfo[1], verinfo[4])
  234.         try:
  235.             fn(sys.argv[2:])
  236.         except InvalidUsage, msg:
  237.             print "Invalid syntax -", msg
  238.             print fn.__doc__
  239.  
  240.     finally:
  241.         try:
  242.             wincerapi.CeRapiUninit()
  243.         except win32api.error, details:
  244.             print_error(details, "Error disconnecting")
  245.  
  246. if __name__=='__main__':
  247.     main()
  248.