Browse Source

Merge pull request #6 from marcoskirsch/master

Add support for having a different destination filename than the original filename.
Peter Magnusson 9 years ago
parent
commit
dcbc4062d6
2 changed files with 52 additions and 29 deletions
  1. 13 6
      README.md
  2. 39 23
      nodemcu-uploader.py

+ 13 - 6
README.md

@@ -3,9 +3,9 @@ nodemcu-uploader.py
 
 
 A simple tool for uploading files to the filesystem of an
-ESP8266 running nodeMcu as well as some other usefull commands.
+ESP8266 running NodeMCU as well as some other usefull commands.
 
-It should work on linux and windows and with any type of file 
+It should work on Linux, Windows, and OS X; and with any type of file
 that fits the filesystem, binary or text.
 
 
@@ -14,9 +14,16 @@ Usage
 --port and --baud are set to default /dev/ttyUSB0 and 9600 respectively.
 
 ###Upload
-Uploading a number of files
+Uploading a number of files.
+
 ```
-./nodemcu-uploader.py upload init.lua README.md nodemcu-uploader.py
+./nodemcu-uploader.py upload -f init.lua -f README.md -f nodemcu-uploader.py
+```
+
+Uploading a number of files, but saving with a different file name.
+
+```
+./nodemcu-uploader.py upload -f init.lua -d new_init.lua -f README.md -d new_README.md
 ```
 
 ###List files
@@ -33,7 +40,7 @@ Todo
 ----
 * Speed up the initial step of uploading the script to NodeMCU
 * Implement a change of baudrate for the actual transfer and go back when done
- 
+
 Details
 -------
 This is *almost* an implementation of xmodem protocol for the upload part.
@@ -46,7 +53,7 @@ This is *almost* an implementation of xmodem protocol for the upload part.
 6. Client sends ACK
 7. Step 5 and 6 are repeated until NodeMCU receives a block with 0 as size.
 8. NodeMCU enables normal terminal again with echo
- 
+
 
 
 ### Data Block Definition

+ 39 - 23
nodemcu-uploader.py

@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # Copyright (C) 2015 Peter Magnusson
 
-# For NodeMcu version 0.9.4 build 2014-12-30 and newer.
+# For NodeMCU version 0.9.4 build 2014-12-30 and newer.
 
 import os
 import serial
@@ -92,7 +92,7 @@ class Uploader:
         while n != '':
             data += n
             n = self._port.read()
-    
+
         self._port.timeout = t
         return data
 
@@ -101,16 +101,18 @@ class Uploader:
         log.info('Preparing esp for transfer.')
         self.write_lines(save_lua.replace('9600', '%d' % self._port.baudrate))
         self._port.write('\r\n')
-        
+
         d = self.dump(0.1)
         if 'unexpected' in d or len(d) > len(save_lua)+10:
             log.error('error in save_lua "%s"' % d)
             return
 
 
-    def write(self, path):
+    def write_file(self, path, destination = ''):
         filename = os.path.basename(path)
-        log.info('Transfering %s' % filename)
+        if not destination:
+            destination = filename
+        log.info('Transfering %s as %s' %(filename, destination))
         self.dump()
         self._port.write(r"recv()" + '\n')
 
@@ -122,11 +124,10 @@ class Uploader:
                 log.error('Error waiting for esp "%s"' % self.dump())
                 return
         self.dump(0.5)
-        log.debug('sending filename "%s"', filename)
-        self._port.write(filename + '\x00')
-
+        log.debug('sending destination filename "%s"', destination)
+        self._port.write(destination + '\x00')
         if not self.got_ack():
-            log.error('did not ack filename: "%s"' % self.dump())
+            log.error('did not ack destination filename: "%s"' % self.dump())
             return
 
         f = open( path, 'rt' ); content = f.read(); f.close()
@@ -145,7 +146,7 @@ class Uploader:
             pos += chunk_size
             if pos + chunk_size > len(content):
                 chunk_size = len(content) - pos
-            
+
         log.debug('sending zero block')
         if not error:
             #zero size block
@@ -179,7 +180,7 @@ class Uploader:
         self._port.write(data)
 
         return self.got_ack()
-        
+
 
     def file_list(self):
         log.info('Listing files')
@@ -208,10 +209,10 @@ def arg_auto_int(x):
 
 
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser(description = 'nodeMCU Lua uploader', prog = 'uploader')
+    parser = argparse.ArgumentParser(description = 'NodeMCU Lua file uploader', prog = 'nodemcu-uploader')
     parser.add_argument(
             '--verbose', '-v',
-            help = 'verbouse output',
+            help = 'verbose output',
             action = 'store_true',
             default = False)
 
@@ -232,35 +233,50 @@ if __name__ == '__main__':
 
     upload_parser = subparsers.add_parser(
             'upload',
-            help = 'Upload file(s)')
+            help = 'Path to one or more files to be uploaded. Destination name will be the same as the file name.')
+
+    upload_parser.add_argument(
+            '--filename', '-f',
+            help = 'File to upload. You can specify this option multiple times.',
+            action='append')
 
-    upload_parser.add_argument('filename',  nargs='+', help = 'Lua file to upload')
+    upload_parser.add_argument(
+            '--destination', '-d',
+            help = 'Name to be used when saving in NodeMCU. You should specify one per file.',
+            action='append')
 
     file_parser = subparsers.add_parser(
-        'file', 
+        'file',
         help = 'File functions')
 
     file_parser.add_argument('cmd', choices=('list', 'format'))
 
     args = parser.parse_args()
-    
+
     formatter = logging.Formatter('%(message)s')
     logging.basicConfig(level=logging.INFO, format='%(message)s')
-    
+
     uploader = Uploader(args.port, args.baud)
     if args.verbose:
         log.setLevel(logging.DEBUG)
 
     if args.operation == 'upload':
-        uploader.prepare()    
-        for f in args.filename:
-            uploader.write(f) 
+        if not args.destination:
+            uploader.prepare()
+            for f in args.filename:
+                uploader.write_file(f)
+        elif len(args.destination) == len(args.filename):
+            uploader.prepare()
+            for f, d in zip(args.filename, args.destination):
+                uploader.write_file(f, d)
+        else:
+            raise Exception('You must specify a destination filename for each file you want to upload.')
         print 'All done!'
 
     elif args.operation == 'file':
-        if args.cmd == 'list': 
+        if args.cmd == 'list':
             uploader.file_list()
-        elif args.cmd == 'format': 
+        elif args.cmd == 'format':
             uploader.file_format()
 
     uploader.close()