Package PyMata :: Module ino_uploader
[hide private]
[frames] | no frames]

Source Code for Module PyMata.ino_uploader

  1  __author__ = 'Copyright (c) 2014 Dawn Robotics Ltd All rights reserved.' 
  2   
  3  """ 
  4  Copyright (c) 2014 Dawn Robotics Ltd All rights reserved. 
  5   
  6  This program is free software; you can redistribute it and/or 
  7  modify it under the terms of the GNU  General Public 
  8  License as published by the Free Software Foundation; either 
  9  version 3 of the License, or (at your option) any later version. 
 10   
 11  This library is distributed in the hope that it will be useful, 
 12  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  Lesser General Public License for more details. 
 15   
 16  You should have received a copy of the GNU Lesser General Public 
 17  License along with this library; if not, write to the Free Software 
 18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 19  """ 
 20   
 21  import os 
 22  import shutil 
 23  import filecmp 
 24  import subprocess 
 25  import logging 
 26   
 27  INO_PATH = "/usr/local/bin/ino" 
 28  DEFAULT_SERIAL_PORT_NAME = "/dev/ttyUSB0" 
 29  DEFAULT_BOARD_MODEL = "uno" 
 30   
31 -class LibraryInfo:
32 """Holds information (src directory, target directory etc) about a library needed for a sketch""" 33
34 - def __init__( self, src_dir, dst_dir, lib_files ):
35 36 self.src_dir = src_dir 37 self.dst_dir = dst_dir 38 self.lib_files = lib_files
39
40 -def get_ino_uploader_user_dir():
41 """Gets the name of the directory used by ino to build the sketches in""" 42 43 home_dir = os.environ[ "HOME" ] 44 return home_dir + "/.ino_uploader"
45
46 -def is_ino_available():
47 """Tests to see if Ino is available on this system""" 48 49 return os.path.exists( INO_PATH )
50
51 -def build_lib_info_list( lib_dirs, ino_uploader_lib_dir ):
52 53 lib_info_list = [] 54 55 for lib_dir in lib_dirs: 56 57 lib_dir_basename = os.path.basename( lib_dir ) 58 if len( lib_dir_basename ) == 0: 59 raise Exception( "Invalid library directory - " + lib_dir ) 60 61 dst_dir = ino_uploader_lib_dir + "/" + lib_dir_basename 62 lib_files = os.listdir( lib_dir ) 63 64 lib_info_list.append( LibraryInfo( lib_dir, dst_dir, lib_files ) ) 65 66 return lib_info_list
67
68 -def upload( sketch_dir, serial_port_name=DEFAULT_SERIAL_PORT_NAME, 69 board_model=DEFAULT_BOARD_MODEL, lib_dirs=[], force_rebuild=False ):
70 71 upload_succeeded = False 72 73 if is_ino_available(): 74 75 # Build up directory names 76 ino_uploader_user_dir = get_ino_uploader_user_dir() 77 78 sketch_dir_basename = os.path.basename( sketch_dir ) 79 if len( sketch_dir_basename ) == 0: 80 raise Exception( "Invalid sketch directory - " + sketch_dir ) 81 82 ino_uploader_sketch_dir = ino_uploader_user_dir + "/" + sketch_dir_basename 83 ino_uploader_src_dir = ino_uploader_sketch_dir + "/src" 84 ino_uploader_lib_dir = ino_uploader_sketch_dir + "/lib" 85 86 sketch_files = os.listdir( sketch_dir ) 87 lib_info_list = build_lib_info_list( lib_dirs, ino_uploader_lib_dir ) 88 89 # Check to see if we need to copy files over 90 file_copy_needed = False 91 if force_rebuild: 92 93 if os.path.exists( ino_uploader_sketch_dir ): 94 shutil.rmtree( ino_uploader_sketch_dir ) 95 96 file_copy_needed = True 97 98 else: 99 100 # Check the sketch source files first 101 if not os.path.exists( ino_uploader_src_dir ): 102 103 file_copy_needed = True 104 105 else: 106 107 match, mismatch, errors = filecmp.cmpfiles( 108 sketch_dir, ino_uploader_src_dir, sketch_files ) 109 if len( mismatch ) > 0 or len( errors ) > 0: 110 111 file_copy_needed = True 112 113 # Now check each of the libraries in turn 114 for lib_info in lib_info_list: 115 116 if file_copy_needed: 117 break # No need to keep checking 118 119 if not os.path.exists( lib_info.dst_dir ): 120 121 file_copy_needed = True 122 123 else: 124 125 match, mismatch, errors = filecmp.cmpfiles( 126 lib_info.src_dir, lib_info.dst_dir, lib_info.lib_files ) 127 if len( mismatch ) > 0 or len( errors ) > 0: 128 129 file_copy_needed = True 130 131 # Copy files over if needed 132 if file_copy_needed: 133 134 logging.info( "Copying sketch src files" ) 135 if os.path.exists( ino_uploader_src_dir ): 136 shutil.rmtree( ino_uploader_src_dir ) 137 138 shutil.copytree( sketch_dir, ino_uploader_src_dir ) 139 140 if len( lib_info_list ) > 0: 141 logging.info( "Copying sketch src files" ) 142 143 if os.path.exists( ino_uploader_lib_dir ): 144 shutil.rmtree( ino_uploader_lib_dir ) 145 146 for lib_info in lib_info_list: 147 shutil.copytree( lib_info.src_dir, lib_info.dst_dir ) 148 149 else: 150 151 logging.info( "No file copy needed" ) 152 153 # Now try to build the sketch 154 logging.debug( "Building sketch in dir " + ino_uploader_sketch_dir ) 155 156 build_result = subprocess.call( 157 [ INO_PATH, "build", "-m", board_model ], cwd=ino_uploader_sketch_dir ) 158 159 # Upload if the build was successful 160 if build_result == 0: 161 162 logging.debug( "Trying to upload sketch..." ) 163 164 upload_result = subprocess.call( 165 [ INO_PATH, "upload", "-p", serial_port_name, "-m", board_model ], 166 cwd=ino_uploader_sketch_dir ) 167 168 logging.debug( "uploadResult = " + str( upload_result ) ) 169 170 if upload_result == 0: 171 upload_succeeded = True 172 173 else: 174 175 logging.warning( "Building of sketch was unsuccessful" ) 176 177 else: 178 179 logging.warning( "Unable to upload sketch as Ino is not installed" ) 180 181 return upload_succeeded
182