Skip to content

Commit dc34b1d

Browse files
committed
Server: Fix issue setting compiler path in macOS
The Arduino application path in macOS has to be expanded inside the app bundle, so when the server tries to set a new compiler path in macOS and sees a different path in the settings than what was originally set by the request it thinks that it failed to set the new path correctly. This commit fixes that.
1 parent d5322ab commit dc34b1d

File tree

3 files changed

+56
-58
lines changed

3 files changed

+56
-58
lines changed

ardublockly/ardublocklyserver_ajax.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ ArdublocklyServer.jsonToIdeModal = function(jsonObj) {
141141
}
142142
errStr.push('\nError id ' + jsonObj.errors[i].id + ': ' + errorContext);
143143
}
144-
elErrOp.innerHTML += errStr.join('<br />');
144+
elErrOp.innerHTML += '<br />' + errStr.join('<br />');
145145
} else if (jsonObj.success && jsonObj.ide_mode) {
146146
// Format a successful response
147147
if (jsonObj.ide_mode == 'upload') {

ardublocklyserver/compilersettings.py

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
Licensed under the Apache License, Version 2.0 (the "License"):
66
http://www.apache.org/licenses/LICENSE-2.0
77
8-
The ServerCompilerSettings is a singleton class maintains in memory, and writes
9-
the Arduino IDE settings into a file.
8+
The ServerCompilerSettings is a singleton class maintained in memory, and
9+
the the Ardublockly and Arduino IDE settings into a file.
1010
On first invocation of the singleton it reads the settings from the file.
1111
"""
1212
from __future__ import unicode_literals, absolute_import, print_function
@@ -21,12 +21,11 @@
2121

2222

2323
class ServerCompilerSettings(object):
24-
"""
25-
Singleton class that retrieves and saves the settings for the server side
26-
compilation.
24+
"""Singleton class to store and save the Ardublockly settings.
25+
2726
The class on first invocation tries to read the settings from the file, it
28-
keeps them in memory, and every time they are modified the changes are also
29-
written into the file.
27+
keeps them in memory, and every time they are modified the changes are
28+
written to the file again.
3029
No compiler is part of the Python code, instead settings that
3130
point to the local Arduino IDE and sketch are stored here.
3231
The public settings to set and get are:
@@ -79,16 +78,17 @@ class ServerCompilerSettings(object):
7978
# Singleton creator and destructor
8079
#
8180
def __new__(cls, settings_dir=None, *args, **kwargs):
82-
"""
83-
Creating or returning the singleton instance.
81+
"""Create or returning the singleton instance.
82+
8483
The argument settings_file_dir is only processed on first
8584
initialisation, and any future calls to the constructor will returned
8685
the already initialised instance with a set settings_file_dir.
8786
"""
8887
if not cls.__singleton_instance:
8988
# Create the singleton instance
9089
cls.__singleton_instance =\
91-
super(ServerCompilerSettings, cls).__new__(cls, *args, **kwargs)
90+
super(ServerCompilerSettings, cls).__new__(
91+
cls, *args, **kwargs)
9292
# Initialise the instance, defaults if file not found
9393
cls.__singleton_instance.__initialise(settings_dir)
9494
return cls.__singleton_instance
@@ -117,7 +117,7 @@ def __initialise(self, settings_dir=None):
117117

118118
@classmethod
119119
def _drop(cls):
120-
""" Drop the instance. """
120+
"""Drop the instance."""
121121
cls.__singleton_instance = None
122122

123123
#
@@ -127,29 +127,19 @@ def get_compiler_dir(self):
127127
return self.__compiler_dir
128128

129129
def set_compiler_dir(self, new_compiler_dir):
130-
""" The compiler dir must a valid file or directory """
130+
"""Set the compiler dir, must a valid file or directory."""
131131
# Mac only check, as apps are packaged directories
132132
if sys.platform == 'darwin':
133133
# Arduino version >1.6.0 has changed the binary name, so check both
134-
if os.path.isfile(os.path.join(
135-
new_compiler_dir, 'Contents', 'MacOS',
136-
'JavaApplicationStub')):
137-
new_compiler_dir = os.path.join(new_compiler_dir, 'Contents',
138-
'MacOS', 'JavaApplicationStub')
134+
bundle = os.path.join(new_compiler_dir, 'Contents', 'MacOS')
135+
if os.path.isfile(os.path.join(bundle, 'JavaApplicationStub')):
136+
new_compiler_dir = os.path.join(bundle, 'JavaApplicationStub')
139137
print('Compiler file in OS X located within the app bundle.')
140-
elif os.path.isfile(os.path.join(
141-
new_compiler_dir, 'Contents', 'MacOS', 'Arduino')):
142-
new_compiler_dir = os.path.join(
143-
new_compiler_dir, 'Contents', 'MacOS', 'Arduino')
138+
elif os.path.isfile(os.path.join(bundle, 'Arduino')):
139+
new_compiler_dir = os.path.join(bundle, 'Arduino')
144140
print('Compiler file in OS X located within the app bundle.')
145141
else:
146-
print('Could not locate the Arduino executable within the OS '
147-
'X app bundle. These are the available files:')
148-
try:
149-
print('%s' % os.listdir(
150-
'%s/Contents/MacOS/' % new_compiler_dir))
151-
except OSError as e:
152-
print(e)
142+
print('Could not find Arduino executable in OS X app bundle.')
153143

154144
# Check directory
155145
if os.path.isfile(new_compiler_dir):
@@ -174,7 +164,7 @@ def set_compiler_dir_default(self):
174164
self.__compiler_dir = None
175165

176166
def set_compiler_dir_from_file(self, new_compiler_dir):
177-
""" The compiler dir must be full path to an existing file. """
167+
"""Set the compiler location, must be full path to an existing file."""
178168
if os.path.exists(new_compiler_dir):
179169
self.__compiler_dir = new_compiler_dir
180170
else:
@@ -191,7 +181,10 @@ def get_sketch_name(self):
191181
return self.__sketch_name
192182

193183
def set_sketch_name(self, new_sketch_name):
194-
""" Only accept letters, numbers, underscores and dashes. """
184+
"""Set the Sketch name.
185+
186+
It only accepts letters, numbers, underscores and dashes.
187+
"""
195188
if re.match("^[\w\d_-]*$", new_sketch_name):
196189
self.__sketch_name = new_sketch_name
197190
print('Sketch name set to:\n\t%s' % self.__sketch_name)
@@ -214,7 +207,10 @@ def set_sketch_name_default(self):
214207
self.__sketch_name = 'ArdublocklySketch'
215208

216209
def set_sketch_name_from_file(self, new_sketch_name):
217-
""" Only accept letters, numbers, underscores and dashes. """
210+
"""Set the Sketch name from a file read.
211+
212+
It only accepts letters, numbers, underscores and dashes.
213+
"""
218214
if re.match("^[\w\d_-]*$", new_sketch_name):
219215
self.__sketch_name = new_sketch_name
220216
else:
@@ -230,7 +226,7 @@ def get_sketch_dir(self):
230226
return self.__sketch_dir
231227

232228
def set_sketch_dir(self, new_sketch_dir):
233-
""" The sketch directory must be a folder """
229+
"""Set the sketch directory, which must be a folder."""
234230
if os.path.isdir(new_sketch_dir):
235231
self.__sketch_dir = new_sketch_dir
236232
print('Sketch directory set to:\n\t%s' % self.__sketch_dir)
@@ -250,11 +246,11 @@ def set_sketch_dir(self, new_sketch_dir):
250246
sketch_dir = property(get_sketch_dir, set_sketch_dir)
251247

252248
def set_sketch_dir_default(self):
253-
""" Sketch default location the same as the settings file location. """
249+
"""Sketch default location the same as the settings file location."""
254250
self.__sketch_dir = os.path.dirname(self.__settings_path)
255251

256252
def set_sketch_dir_from_file(self, new_sketch_dir):
257-
""" The sketch directory must be a folder """
253+
"""Set the sketch directory from settings file, must be a folder."""
258254
if os.path.isdir(new_sketch_dir):
259255
self.__sketch_dir = new_sketch_dir
260256
else:
@@ -316,8 +312,8 @@ def get_arduino_board_types(self):
316312
# Extra checks of the available Ports are required as states can change
317313
#
318314
def get_serial_port(self):
319-
"""
320-
Checks available Serial Ports and populates the serial port dictionary.
315+
"""Check available Serial Ports and populates the port dictionary.
316+
321317
Returns currently selected Serial Port key if available.
322318
Returns None if selected Serial Port is not available anymore.
323319
:return: Serial Port dictionary key
@@ -344,10 +340,11 @@ def get_serial_port(self):
344340
return self.__serial_port_key
345341

346342
def set_serial_port(self, new_port):
347-
"""
348-
Checks available Serial Ports and populates the serial port dictionary.
343+
"""Check available Serial Ports and populates the port dictionary.
344+
349345
If the new serial port is not in the dictionary or the dictionary is
350346
empty it prints an error in the console.
347+
351348
:param new_port: the new port to set
352349
"""
353350
if new_port in self.__serial_ports:
@@ -380,8 +377,8 @@ def set_serial_port(self, new_port):
380377
serial_port = property(get_serial_port, set_serial_port)
381378

382379
def set_serial_port_default(self):
383-
"""
384-
Checks available Serial Ports and populates the serial port dictionary.
380+
"""Check available Serial Ports and populate the port dictionary.
381+
385382
If there are no available serial ports is resets the variables.
386383
"""
387384
self.populate_serial_port_list()
@@ -394,10 +391,11 @@ def set_serial_port_default(self):
394391
self.__serial_ports[self.__serial_port_key]
395392

396393
def set_serial_port_from_file(self, new_port_value):
397-
"""
398-
Checks available Serial Ports and populates the serial port dictionary.
394+
"""Check available Serial Ports and populate the port dictionary.
395+
399396
If the new serial port is not in the dictionary or the dictionary is
400397
empty it prints an error in the console.
398+
401399
:param new_port_value: the new port to set
402400
"""
403401
# Check if the settings file value is present in available ports list
@@ -416,10 +414,11 @@ def set_serial_port_from_file(self, new_port_value):
416414
print('Default Serial Port set:\n\t%s' % self.__serial_port_value)
417415

418416
def get_serial_port_flag(self):
419-
"""
420-
Checks available Serial Ports and populates the serial port dictionary.
417+
"""Check available Serial Ports and populates the port dictionary.
418+
421419
Returns currently selected Serial Port value if available.
422420
Returns None if selected Serial Port is not available anymore.
421+
423422
:return: Serial Port dictionary value
424423
"""
425424
self.populate_serial_port_list()
@@ -449,10 +448,7 @@ def get_serial_ports(self):
449448
return self.__serial_ports
450449

451450
def populate_serial_port_list(self):
452-
"""
453-
Populates the __serial_ports__ dictionary with the Serial Ports
454-
available.
455-
"""
451+
"""Populate the serial ports dictionary with the available ports."""
456452
port_list = ardublocklyserver.serialport.get_port_list()
457453
self.__serial_ports = {}
458454
if port_list:
@@ -520,7 +516,7 @@ def set_default_settings(self):
520516
# Settings file
521517
#
522518
def save_settings(self):
523-
""" Saves all the settings into a configuration file """
519+
"""Save all the settings into a configuration file."""
524520
settings_parser = configparser.ConfigParser()
525521
# IDE Section
526522
settings_parser.add_section('Arduino_IDE')
@@ -556,16 +552,17 @@ def save_settings(self):
556552
sys.stdout.flush()
557553

558554
def read_settings(self):
559-
"""
560-
Attempts to read the settings from a file and saves them to the
561-
member variables. If it cannot read the file it sets the variables
555+
"""Read the settings from a file and load them into the instance.
556+
557+
If it cannot read the file it sets the variables
562558
to the default value.
563559
"""
564560
settings_dict = self.get_settings_file_data()
565561
if settings_dict:
566562
self.set_compiler_dir_from_file(settings_dict['arduino_exec_path'])
567563
self.set_arduino_board_from_file(settings_dict['arduino_board'])
568-
self.set_serial_port_from_file(settings_dict['arduino_serial_port'])
564+
self.set_serial_port_from_file(
565+
settings_dict['arduino_serial_port'])
569566
self.set_sketch_name_from_file(settings_dict['sketch_name'])
570567
self.set_sketch_dir_from_file(settings_dict['sketch_directory'])
571568
self.set_load_ide_from_file(settings_dict['ide_load'])
@@ -588,8 +585,8 @@ def read_settings(self):
588585
self.save_settings()
589586

590587
def get_settings_file_data(self):
591-
"""
592-
Creates a dictionary from the settings stored in a file.
588+
"""Create a dictionary from the settings stored in a file.
589+
593590
:return: A dictionary with all the options and values from the settings
594591
file (sections are ignored during parsing).
595592
"""
@@ -611,7 +608,7 @@ def get_settings_file_data(self):
611608
settings_dict['ide_load'] =\
612609
settings_parser.get('Ardublockly', 'ide_load')
613610
print('Settings loaded from:\n\t%s' % self.__settings_path)
614-
except Exception as e:
611+
except Exception:
615612
print('Settings file corrupted or not found in:\n\t%s'
616613
% self.__settings_path)
617614
settings_dict = None

ardublocklyserver/server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ def handler_settings_update_individual(name):
333333
'id': 63,
334334
'description': 'Unexpected setting type to update.'
335335
})
336-
if set_value == new_value:
336+
# Check if sent value was set, might have been expanded in Settings
337+
if set_value in new_value:
337338
response_dict.update({
338339
'success': True,
339340
'selected': set_value

0 commit comments

Comments
 (0)