def resetFactorySettings(): from octoprint_WBCustom.astroprint.cloud import astroprintCloud from shutil import copy logger = logging.getLogger(__name__) logger.warning("Executing a Restore Factory Settings operation") #We log out first astroprintCloud().signout() s = settings() emptyFolder(s.get(['folder', 'uploads']) or s.getBaseFolder('uploads')) emptyFolder(s.get(['folder', 'timelapse']) or s.getBaseFolder('timelapse')) emptyFolder( s.get(['folder', 'timelapse_tmp']) or s.getBaseFolder('timelapse_tmp')) emptyFolder(s.get(['folder', 'virtualSd']) or s.getBaseFolder('virtualSd')) networkManager().forgetWifiNetworks() configFolder = s.getConfigFolder() #replace config.yaml with config.factory config_file = s._configfile config_factory = os.path.join(configFolder, "config.factory") if config_file and os.path.exists(config_file): if os.path.exists(config_factory): copy(config_factory, config_file) else: os.unlink(config_file) #replace printer-profile.yaml with printer-profile.factory p_profile_file = os.path.join(configFolder, "printer-profile.yaml") p_profile_factory = os.path.join(configFolder, "printer-profile.factory") if os.path.exists(p_profile_file): if os.path.exists(p_profile_factory): copy(p_profile_factory, p_profile_file) else: os.unlink(p_profile_file) #remove info about users user_file = s.get(["accessControl", "userfile"]) or os.path.join( configFolder, "users.yaml") if user_file and os.path.exists(user_file): os.unlink(user_file) logger.info("Restore completed, rebooting...") #We should reboot the whole device if softwareManager.restartServer(): return jsonify() else: return ("There was an error rebooting.", 500)
def networkName(self, newName, sendMessage): nm = networkManager() if newName : nm.setHostname(newName) sendMessage({'name':nm.getHostname()})
def wifiNetworks(self, data, sendMessage): networks = networkManager().getWifiNetworks() if networks: sendMessage(networks) else: sendMessage("unable_get_wifi_networks",True)
def _ssdp_register(self): """ Registers the AstroPrint instance as basic service with a presentation URL pointing to the web interface """ if self._ssdp_monitor_active: return time_since_last_unregister = time.time() - self._ssdp_last_unregister if time_since_last_unregister < (self._ssdp_notify_timeout + 1): wait_seconds = (self._ssdp_notify_timeout + 1) - time_since_last_unregister self.logger.info( "Waiting %s seconds before starting SSDP Service..." % wait_seconds) time.sleep(wait_seconds) #Make sure that the network is still after the wait if not networkManager().isOnline(): return self._ssdp_monitor_active = True self._ssdp_monitor_thread = threading.Thread( target=self._ssdp_monitor, kwargs=dict(timeout=self._ssdp_notify_timeout)) self._ssdp_monitor_thread.daemon = True self._ssdp_monitor_thread.start()
def getWifiNetworks(): networks = networkManager().getWifiNetworks() if networks: return jsonify(networks=networks) else: return jsonify({'message': "Unable to get WiFi networks"})
def deleteStoredWiFiNetwork(networkId): nm = networkManager() if nm.deleteStoredWifiNetwork(networkId): return jsonify() else: return ("Network Not Found", 404)
def _doRetry(self, silent=True): if self._retries < len(self.RETRY_SCHEDULE): def retry(): self._retries += 1 self._logger.info('Retrying boxrouter connection. Retry #%d' % self._retries) self._silentReconnect = silent self._retryTimer = None self.boxrouter_connect() if not self._retryTimer: self._logger.info('Waiting %d secs before retrying...' % self.RETRY_SCHEDULE[self._retries]) self._retryTimer = threading.Timer(self.RETRY_SCHEDULE[self._retries] , retry ) self._retryTimer.start() else: self._logger.info('No more retries. Giving up...') self.status = self.STATUS_DISCONNECTED self._eventManager.fire(Events.ASTROPRINT_STATUS, self.status) self._retries = 0 self._retryTimer = None #Are we offline? nm = networkManager() if not nm.checkOnline() and nm.isHotspotActive() is False: #isHotspotActive will return None if not possible #get the box hotspot up self._logger.info('AstroBox is offline. Starting hotspot...') result = nm.startHotspot() if result is True: self._logger.info('Hostspot started.') else: self._logger.error('Failed to start hostspot: %s' % result)
def processAuthenticate(self, data): if data: self._silentReconnect = False if 'error' in data: self._logger.warn(data['message'] if 'message' in data else 'Unkonwn authentication error') self.status = self.STATUS_ERROR self._eventManager.fire(Events.ASTROPRINT_STATUS, self.status) self.close() if data.get('should_retry'): self._doRetry() elif data.get('type') == 'unable_to_authenticate': self._logger.info("Unuable to authenticate user in fleet box. Logout") astroprintCloud().remove_logged_user() elif 'success' in data: self._logger.info("Connected to astroprint service") self.authenticated = True if 'groupId' in data: astroprintCloud().updateFleetInfo(data['orgId'], data['groupId']) self._eventManager.fire(Events.FLEET_STATUS, data) self._retries = 0 self._retryTimer = None self.status = self.STATUS_CONNECTED self._eventManager.fire(Events.ASTROPRINT_STATUS, self.status) return None else: from octoprint.server import VERSION from octoprint_WBCustom.astroprint.printerprofile import printerProfileManager nm = networkManager() sm = softwareManager() ppm = printerProfileManager() authData = { 'silentReconnect': self._silentReconnect, 'boxId': self.boxId, 'variantId': sm.variant['id'], 'boxName': nm.getHostname(), 'swVersion': VERSION, 'platform': sm.platform, 'localIpAddress': nm.activeIpAddress, 'publicKey': self._publicKey, 'privateKey': self._privateKey, 'printerModel': ppm.data['printer_model'] if ppm.data['printer_model']['id'] else None } pkgId = sm.mfPackageId if pkgId: authData['mfPackageId'] = pkgId return { 'type': 'auth', 'data': authData }
def deleteStoredWiFiNetwork(self, data, sendMessage): nm = networkManager() if nm.deleteStoredWifiNetwork(data['id']): sendMessage({'success': 'no_error'}) else: sendMessage("network_not_found",True)
def getStatus(self): printer = printerManager() cm = cameraManager() ppm = printerProfileManager() cloudInstance = astroprintCloud() fileName = None if printer.isPrinting(): currentJob = printer.getCurrentJob() fileName = currentJob["file"]["name"] return { 'id': boxrouterManager().boxId, 'name': networkManager().getHostname(), 'orgId' : cloudInstance.orgId, 'groupId' : cloudInstance.groupId, 'printing': printer.isPrinting(), 'fileName': fileName, 'printerModel': ppm.data['printer_model'] if ppm.data['printer_model']['id'] else None, 'filament' : ppm.data['filament'], 'material': None, 'operational': printer.isOperational(), 'paused': printer.isPaused(), 'camera': cm.isCameraConnected(), #'printCapture': cm.timelapseInfo, 'remotePrint': True, 'capabilities': ['remotePrint'] + cm.capabilities }
def getNetworkSettings(): nm = networkManager() return jsonify({ 'networks': nm.getActiveConnections(), 'networkDeviceInfo': nm.networkDeviceInfo, 'hasWifi': nm.hasWifi(), 'storedWifiNetworks': nm.storedWifiNetworks() })
def networkSettings(self, data, sendMessage): nm = networkManager() sendMessage({ 'networks': nm.getActiveConnections(), 'hasWifi': nm.hasWifi(), 'networkDeviceInfo': nm.networkDeviceInfo, 'storedWifiNetworks': nm.storedWifiNetworks() })
def getWifiNetworkInfo(self): nm = networkManager() return jsonify({ 'networks': nm.getWifiNetworks(), 'activeConnections': nm.getActiveConnections(), 'networkDeviceInfo': nm.networkDeviceInfo, })
def handleWifiHotspot(): nm = networkManager() if request.method == "GET": return jsonify({ 'hotspot': { 'active': nm.isHotspotActive(), 'name': nm.getHostname(), 'hotspotOnlyOffline': settings().getBoolean(['wifi', 'hotspotOnlyOffline']) } if nm.isHotspotable() else False }) elif request.method == "PUT": if "application/json" in request.headers["Content-Type"]: data = request.json if "hotspotOnlyOffline" in data: s = settings() s.setBoolean(['wifi', 'hotspotOnlyOffline'], data["hotspotOnlyOffline"]) s.save() return jsonify() return ("Invalid Request", 400) elif request.method == "DELETE": result = networkManager().stopHotspot() if result is True: return jsonify() else: return (result, 500) else: #POST result = nm.startHotspot() if result is True: return jsonify() else: return (result, 500)
def signinWithKey(self, email, private_key, hasSessionContext=True): from octoprint.server import userManager user = None userLoggedIn = False online = networkManager().isOnline() if online: public_key = self.get_public_key(email, private_key) if public_key: #Let's protect the box now: user = userManager.findUser(email) if user and user.has_password(): userManager.changeCloudAccessKeys(email, public_key, private_key) else: self._logger.info( "New user signing requires password method") return False userLoggedIn = True else: user = userManager.findUser(email) userLoggedIn = user and user.check_privateKey(private_key) if userLoggedIn: if hasSessionContext: login_user(user, remember=True) userId = user.get_id() self.settings.set(["cloudSlicer", "loggedUser"], userId) self.settings.save() boxrouterManager().boxrouter_connect() if hasSessionContext: identity_changed.send(current_app._get_current_object(), identity=Identity(userId)) #let the singleton be recreated again, so new credentials are taken into use global _instance _instance = None eventManager().fire(Events.LOCK_STATUS_CHANGED, userId) return True elif not online: raise AstroPrintCloudNoConnectionException() return False
def validatePassword(self, email, password): from octoprint.server import userManager user = None userValidated = False online = networkManager().isOnline() if online: try: data_private_key = self.get_private_key(email, password) if data_private_key: private_key = data_private_key['private_key'] public_key = self.get_public_key(email, private_key) orgId = data_private_key['organization_id'] groupId = data_private_key['group_id'] if public_key: #Let's update the box now: user = userManager.findUser(email) if user: userManager.changeUserPassword(email, password) userManager.changeCloudAccessKeys( email, public_key, private_key, orgId, groupId) else: user = userManager.addUser(email, password, public_key, private_key, orgId, groupId, True) userValidated = True else: return False else: return False except ConnectionError as e: self._logger.error( 'Connection error when trying to validate password: %s' % e) # was offline or couldn't reach astroprint.com if not userValidated: user = userManager.findUser(email) userValidated = user and user.check_password( userManager.createPasswordHash(password)) if userValidated: userId = user.get_id() self.settings.set(["cloudSlicer", "loggedUser"], userId) self.settings.save() return userValidated
def check_internet(): nm = networkManager() if nm.isAstroprintReachable(): return jsonify(connected=True) else: networks = nm.getWifiNetworks() if networks: return jsonify(networks=networks, connected=False) else: return make_response("Unable to get WiFi networks", 500)
def sslSettings(): nm = networkManager() sslm = nm.sslManager s = settings() if request.method == 'POST': if "application/json" in request.headers["Content-Type"]: data = request.json action = data.get('action') if action == 'toggle': if sslm.isSslActive(): sslm.disable() else: sslm.enable() if not s.get(['network', 'ssl', 'domain']): ips = [ v.get('ip') for _, v in nm.getActiveConnections().items() if v is not None ] if len(ips) > 0: s.set(['network', 'ssl', 'domain'], "%s.xip.astroprint.com" % ips[0].split(':')[0].replace('.', '-')) s.save() return jsonify(True) elif action == 'save': values = data.get('values') if values: domain = values.get('domain') s.set(['network', 'ssl', 'domain'], domain) s.save() return jsonify(True) return ("Invalid Request", 400) else: ips = [ v.get('ip') for _, v in nm.getActiveConnections().items() if v is not None ] domains = set([ '%s.xip.astroprint.com' % (i.split(':')[0].replace('.', '-')) for i in ips if i is not None ] + ['%s.ssl.local' % nm.getHostname()]) return jsonify(enabled=sslm.isSslActive(), active_domain=sslm.getDomain(), domains=list(domains))
def getAccessKeys(self, data, sendResponse): publicKey = email = accessKey = None if 'email' in data: email = data['email'] if 'accessKey' in data: accessKey = data['accessKey'] userLogged = settings().get(["cloudSlicer", "loggedUser"]) #### # - nobody logged: None # - any log: email if email and accessKey: #somebody is logged in the remote client if userLogged: #Somebody logged in Astrobox if userLogged == email: #I am the user logged online = networkManager().isOnline() if online: publicKey = astroprintCloud().get_public_key( email, accessKey) if not publicKey: self._logger.error('error getting public key', exc_info=True) sendResponse('error_getting_public_key', True) return else: user = userManager.findUser(email) if user.get_private_key() != accessKey: self._logger.error('incorrect logged user', exc_info=True) sendResponse('incorrect_logged_user', True) return else: #I am NOT the logged user self._logger.error('incorrect logged user', exc_info=True) sendResponse('incorrect_logged_user', True) return else: #nodody is logged in the remote client if userLogged: self._logger.error('any user logged', exc_info=True) sendResponse('no_user_logged', True) return sendResponse({ 'api_key': UI_API_KEY, 'ws_token': create_ws_token(publicKey) })
def connect_internet(): if "application/json" in request.headers["Content-Type"]: data = request.json if 'id' in data and 'password' in data: result = networkManager().setWifiNetwork(data['id'], data['password']) if result: return jsonify(result) else: return make_response("Network %s not found" % data['id'], 404) return make_response("Invalid Request", 400)
def handleNetworkName(): nm = networkManager() if request.method == "POST": if "application/json" in request.headers["Content-Type"]: data = request.json nm.setHostname(data['name']) else: return ("Invalid Request", 400) return jsonify(name=nm.getHostname())
def setWifiNetwork(self): if "application/json" in request.headers["Content-Type"]: data = request.json if 'id' in data and 'password' in data: result = networkManager().setWifiNetwork2(data['id'], data['password']) if result: return jsonify(result = result) #return jsonify(result) else: logger.info('SET-WIFI problem: %s' % result) return jsonify({'message': "Network %s not found" % data['id']}) return jsonify({'message': "Invalid Request"})
def save_name(): name = request.values.get('name', None) if not name or not re.search(r"^[a-zA-Z0-9\-_]+$", name): return make_response('Invalid Name', 400) else: if platform == "linux" or platform == "linux2": if networkManager().setHostname(name): return jsonify() else: return make_response("There was an error saving the hostname", 500) else: return NO_CONTENT
def boxrouter_connect(self): if not networkManager().isOnline(): return False if not self.connected: from octoprint.server import userManager loggedUser = self._settings.get(['cloudSlicer', 'loggedUser']) if loggedUser and userManager: user = userManager.findUser(loggedUser) if user and user.is_authenticated: self._publicKey = user.publicKey self._privateKey = user.privateKey if self._publicKey and self._privateKey: self.status = self.STATUS_CONNECTING self._eventManager.fire(Events.ASTROPRINT_STATUS, self.status) try: if self._retryTimer: #This is in case the user tried to connect and there was a pending retry self._retryTimer.cancel() self._retryTimer = None #If it fails, the retry sequence should restart self._retries = 0 if self._ws and not self._ws.terminated: self._ws.terminate() self._ws = AstroprintBoxRouterClient(self._address, self) self._ws.connect() self.connected = True except Exception as e: self._logger.error("Error connecting to boxrouter [%s]: %s" % (self._address, e)) self.connected = False self.status = self.STATUS_ERROR self._eventManager.fire(Events.ASTROPRINT_STATUS, self.status) if self._ws: self._ws.terminate() self._ws = None self._doRetry(False) #This one should not be silent return True return False
def setWifiNetwork(self, data, sendMessage): if 'id' in data and 'password' in data: result = networkManager().setWifiNetwork(data['id'], data['password']) if result: if 'err_code' in result: sendMessage(result['err_code'], True) else: sendMessage(result) else: sendMessage('network_not_found',True) return sendMessage('incorrect_data',True)
def checkInternet(self, data, sendResponse): nm = networkManager() if nm.isAstroprintReachable(): #if False: return sendResponse({'connected':True}) else: networks = nm.getWifiNetworks() if networks: return sendResponse( { 'networks':networks, 'connected':False } ) else: return sendResponse("unable_get_wifi",True)
def __init__(self): self._eventManager = eventManager() self.logger = logging.getLogger(__name__) self.mfDefinition = manufacturerPkgManager() self.softwareMgr = softwareManager() # upnp/ssdp self._ssdp_monitor_active = False self._ssdp_monitor_thread = None self._ssdp_notify_timeout = 10 self._ssdp_last_notify = 0 self._ssdp_last_unregister = 0 # SSDP if networkManager().isOnline(): self._ssdp_register() self._eventManager.subscribe(Events.NETWORK_STATUS, self._onNetworkStateChanged)
def callFleetInfo(self): if networkManager().isOnline(): self.getFleetInfo() else: self._eventManager.subscribe(Events.NETWORK_STATUS, self.getFleetInfo)
def get_name(): return jsonify(name=networkManager().getHostname())
def resetFactorySettings(self, data, sendMessage): from octoprint_WBCustom.astroprint.cloud import astroprintCloud from shutil import copy try: #astroprintCloud().signout() astroprintCloud().remove_logged_user() logger = logging.getLogger(__name__) logger.warning("Executing a Restore Factory Settings operation") s = settings() #empty all folders def emptyFolder(folder): if folder and os.path.exists(folder): for f in os.listdir(folder): p = os.path.join(folder, f) try: if os.path.isfile(p): os.unlink(p) except Exception: pass emptyFolder( s.get(['folder', 'uploads']) or s.getBaseFolder('uploads')) emptyFolder( s.get(['folder', 'timelapse']) or s.getBaseFolder('timelapse')) emptyFolder( s.get(['folder', 'timelapse_tmp']) or s.getBaseFolder('timelapse_tmp')) emptyFolder( s.get(['folder', 'virtualSd']) or s.getBaseFolder('virtualSd')) networkManager().forgetWifiNetworks() configFolder = s.getConfigFolder() #replace config.yaml with config.factory config_file = s._configfile config_factory = os.path.join(configFolder, "config.factory") if config_file and os.path.exists(config_file): if os.path.exists(config_factory): copy(config_factory, config_file) else: os.unlink(config_file) #replace printer-profile.yaml with printer-profile.factory p_profile_file = os.path.join(configFolder, "printer-profile.yaml") p_profile_factory = os.path.join(configFolder, "printer-profile.factory") if os.path.exists(p_profile_file): if os.path.exists(p_profile_factory): copy(p_profile_factory, p_profile_file) else: os.unlink(p_profile_file) #remove info about users user_file = s.get(["accessControl", "userfile"]) or os.path.join( configFolder, "users.yaml") if user_file and os.path.exists(user_file): os.unlink(user_file) logger.info("Restore completed, rebooting...") #We should reboot the whole device if softwareManager.restartServer(): sendMessage({'success': 'no_error'}) else: sendMessage("error_rebooting", True) except Exception: self._logger.error('unsuccessfully factory settings restored', exc_info=True) sendMessage("error_restoring_factory_settings", True)