Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pysynch.py 8.1KB

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