def gcode(self, params): if not self.plugin.get_printer().is_operational(): return None, error_embed(author=self.plugin.get_printer_name(), title="Printer not connected", description="Connect to printer first.") allowed_gcodes = self.plugin.get_settings().get(["allowed_gcode"]) allowed_gcodes = re.split('[^0-9a-zA-Z]+', allowed_gcodes.upper()) script = "".join(params[1:]).upper() lines = script.split(';') for line in lines: first = line.strip().replace(' ', '').replace('\t', '') first = re.findall('^[a-zA-Z]+[0-9]+', first) if first is None or \ len(first) == 0 or \ first[0] not in allowed_gcodes: return None, error_embed( author=self.plugin.get_printer_name(), title="Invalid GCODE", description= "If you want to use \"%s\", add it to the allowed GCODEs" % line) try: self.plugin.get_printer().commands(lines) except Exception as e: return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to execute gcode", description="Error: %s" % e) return None, success_embed(author=self.plugin.get_printer_name(), title="Sent script")
def on(self, params): if len(params) > 2: return None, error_embed( author=self.plugin.get_printer_name(), title='Too many parameters', description='Should be: %soutputon {ID}' % self.plugin.get_settings().get(["prefix"])) elif len(params) < 2: return None, error_embed( author=self.plugin.get_printer_name(), title='Missing parameters', description='Should be: %soutputon {ID}' % self.plugin.get_settings().get(["prefix"])) result = self.api_command("on", params[1]) data = result.json() if data['success']: return None, success_embed(author=self.plugin.get_printer_name(), title="Turned ID %i on." % int(params[1])) return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to turn ID %i on." % int(params[1]), description=unicode(result.content))
def start_print(self, params): if len(params) != 2: return None, error_embed( author=self.plugin.get_printer_name(), title='Wrong number of arguments', description='try "%sprint [filename]"' % self.plugin.get_settings().get(["prefix"])) if not self.plugin.get_printer().is_ready(): return None, error_embed(author=self.plugin.get_printer_name(), title='Printer is not ready') file = self.find_file(params[1]) if file is None: return None, error_embed(author=self.plugin.get_printer_name(), title='Failed to find the file') is_sdcard = (file['location'] == 'sdcard') try: file_path = self.plugin.get_file_manager().path_on_disk( file['location'], file['path']) self.plugin.get_printer().select_file(file_path, is_sdcard, printAfterSelect=True) except InvalidFileType: return None, error_embed(author=self.plugin.get_printer_name(), title='Invalid file type selected') except InvalidFileLocation: return None, error_embed(author=self.plugin.get_printer_name(), title='Invalid file location?') return None, success_embed(author=self.plugin.get_printer_name(), title='Successfully started print', description=file['path'])
def disconnect(self): if not self.plugin.get_printer().is_operational(): return None, error_embed(author=self.plugin.get_printer_name(), title='Printer is not connected') self.plugin.get_printer().disconnect() # Sleep a while before checking if disconnected time.sleep(10) if self.plugin.get_printer().is_operational(): return None, error_embed(author=self.plugin.get_printer_name(), title='Failed to disconnect') return None, success_embed(author=self.plugin.get_printer_name(), title='Disconnected from printer')
def list_system_commands(self): api_key = self.plugin.get_settings().global_get(['api', 'key']) port = self.plugin.get_settings().global_get(['server', 'port']) header = {'X-Api-Key': api_key, 'Content-Type': 'application/json'} response = requests.get('http://127.0.0.1:%s/api/system/commands' % port, headers=header) if response.status_code != 200: return None, error_embed(author=self.plugin.get_printer_name(), title="Error code: %i" % response.status_code, description=response.content) builder = EmbedBuilder() builder.set_title('List of system commands') builder.set_author(name=self.plugin.get_printer_name()) builder.set_description( 'To execute a system command, use /systemcommand {command}. ' 'Where command is similar to "core/restart"') data = json.loads(response.content) for source in data: for comm in data[source]: if 'name' not in comm: continue comm_name = comm['name'] comm_description = "%s/%s" % (source, comm['action']) if 'command' in comm: comm_description = "%s - %s" % (comm_description, comm['command']) builder.add_field(title=comm_name, text=comm_description) return None, builder.get_embeds()
def poweroff(self): result = self.api_command("turnPSUOff") if result: return None, success_embed(author=self.plugin.get_printer_name(), title="Turned PSU off") return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to turn PSU off", description=unicode(result.content))
def poweron(self): result = self.api_command("turnPSUOn") if result: return success_embed(author=self.plugin.get_printer_name(), title="Turned PSU on") return error_embed(author=self.plugin.get_printer_name(), title="Failed to turn PSU on", description=result.content)
def getfile(self, params): filename = " ".join(params[1:]) foundfile = self.find_file(filename) if foundfile is None: return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to find file matching the name given") file_path = self.plugin.get_file_manager().path_on_disk(foundfile['location'], foundfile['path']) return upload_file(file_path)
def system_command(self, command): if len(command) != 2: return None, error_embed( author=self.plugin.get_printer_name(), title='Wrong number of args', description='/systemcommand {source/command}') api_key = self.plugin.get_settings().global_get(['api', 'key']) port = self.plugin.get_settings().global_get(['server', 'port']) header = {'X-Api-Key': api_key, 'Content-Type': 'application/json'} if requests.post('http://127.0.0.1:%s/api/system/commands/%s' % (port, command[1]), headers=header): return None, success_embed(author=self.plugin.get_printer_name(), title='Successfully ran command', description=command[1]) else: return None, error_embed(author=self.plugin.get_printer_name(), title='Failed to run command', description=command[1])
def powerstatus(self): result = self.api_command("getPSUState") if result: message = "PSU is OFF" if json.loads(result.content)['isPSUOn']: message = "PSU is ON" return None, info_embed(author=self.plugin.get_printer_name(), title=message) return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to get PSU status", description=unicode(result.content))
def test_error_embed(self): messages = error_embed(author="OctoPrint", title="title", description="description") self.assertEqual(1, len(messages)) embed, snapshot = messages[0] self.assertBasicEmbed(embed, author="OctoPrint", title="title", description="description", color=COLOR_ERROR) if "NET_TEST" in os.environ: self.discord.send(messages=(embed, snapshot))
def gettimelapse(self, params): filename = " ".join(params[1:]).upper() path = os.path.join(os.getcwd(), self.plugin._data_folder, '..', '..', 'timelapse') path = os.path.abspath(path) for root, dirs, files in os.walk(path): for name in files: file_path = os.path.join(root, name) if filename in file_path.upper(): return upload_file(file_path) return None, error_embed(author=self.plugin.get_printer_name(), title="Failed to find file matching the name given")
def connect(self, params): if len(params) > 3: return None, error_embed( author=self.plugin.get_printer_name(), title='Too many parameters', description='Should be: %sconnect [port] [baudrate]' % self.plugin.get_settings().get(["prefix"])) if self.plugin.get_printer().is_operational(): return None, error_embed(author=self.plugin.get_printer_name(), title='Printer already connected', description='Disconnect first') port = None baudrate = None if len(params) >= 2: port = params[1] if len(params) == 3: try: baudrate = int(params[2]) except ValueError: return None, error_embed(author=self.plugin.get_printer_name(), title='Wrong format for baudrate', description='should be a number') self.plugin.get_printer().connect(port=port, baudrate=baudrate, profile=None) # Check every second for 30 seconds, to see if it has connected. for i in range(30): time.sleep(1) if self.plugin.get_printer().is_operational(): return None, success_embed('Connected to printer') return None, error_embed( author=self.plugin.get_printer_name(), title='Failed to connect', description='try: "%sconnect [port] [baudrate]"' % self.plugin.get_settings().get(["prefix"]))
def removejob(self, params): if len(params) < 4: return error_embed(author=self.plugin.get_printer_name(), title='Wrong number of args', description='%sremovejob {YYYY-MM-DD} {HH:MM} {path}' % self.plugin.get_settings().get(["prefix"])) try: files = list(self.plugin.get_settings().global_get(["plugins", "printscheduler", "scheduled_jobs"])) params.pop(0) # remove the command from params file_start_at = "%s %s" % (params.pop(0), params.pop(0)) file_path = " ".join(params) for file in files: if file["path"] == file_path and file["start_at"] == file_start_at: files.remove(file) self.plugin.get_settings().global_set(["plugins", "printscheduler", "scheduled_jobs"], files) self.plugin.get_settings().save(trigger_event=True) return success_embed(author=self.plugin.get_printer_name(), title="%s unscheduled for %s" % (file_path, file_start_at)) except Exception as e: return error_embed(author=self.plugin.get_printer_name(), title='Error', description='%s' % e)
def test_error_embed(self): embeds = error_embed(author="OctoPrint", title="title", description="description") self.assertBasicEmbed(embeds, author="OctoPrint", title="title", description="description", color=COLOR_ERROR) if "NET_TEST" in os.environ: self.assertTrue(self.discord.send(embeds=embeds))
def download_file(self, filename, url, user): if user and not self.check_perms('upload', user): return None, error_embed(author=self.plugin.get_printer_name(), title="Permission Denied") upload_file_path = self.plugin.get_file_manager().path_on_disk('local', filename) r = requests.get(url, stream=True) with open(upload_file_path, 'wb') as f: for chunk in r.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunks f.write(chunk) return None, success_embed(author=self.plugin.get_printer_name(), title='File Received', description=filename)
def parse_command(self, string, user=None): prefix_str = self.plugin.get_settings().get(["prefix"]) prefix_len = len(prefix_str) parts = re.split(r'\s+', string) if len(parts[0]) < prefix_len or prefix_str != parts[0][:prefix_len]: return None, None command_string = parts[0][prefix_len:] command = self.command_dict.get(command_string, {'cmd': self.help}) if user and not self.check_perms(command_string, user): return None, error_embed(author=self.plugin.get_printer_name(), title="Permission Denied") if command.get('params'): return command['cmd'](parts) else: return command['cmd']()
def cancel_print(self): self.plugin.get_printer().cancel_print() return None, error_embed(author=self.plugin.get_printer_name(), title='Print aborted')
def unzip(self, params): if len(params) != 2: return None, error_embed(author=self.plugin.get_printer_name(), title='Wrong number of arguments', description='try "%sunzip [filename]"' % self.plugin.get_settings().get( ["prefix"])) file_name = params[1] flat_filelist = self.get_flat_file_list() unzippable = None if file_name.endswith('.zip'): for file in flat_filelist: if file_name.upper() in file.get('path').upper(): unzippable = self.plugin.get_file_manager().path_on_disk(file.get('location'), file_name) break elif file_name.endswith('.zip.001'): files = [] truncated = file_name[:-3] current = 1 found = True while found: found = False fn = truncated + str(current).zfill(3) for file in flat_filelist: if fn.upper() in file.get('path').upper(): files.append(fn) current += 1 found = True break upload_file_path = self.plugin.get_file_manager().path_on_disk('local', truncated[:-1]) if self.plugin.get_file_manager().file_exists('local', upload_file_path.rpartition('/')[2]): self.plugin.get_file_manager().remove_file('local', upload_file_path.rpartition('/')[2]) with open(upload_file_path, 'ab') as combined: for f in files: path = self.plugin.get_file_manager().path_on_disk('local', f) with open(path, 'rb') as temp: combined.write(temp.read()) self.plugin.get_file_manager().remove_file('local', f.rpartition('/')[2]) unzippable = upload_file_path else: return None, error_embed(author=self.plugin.get_printer_name(), title="Not a valid Zip file.", description='try "%sunzip [filename].zip or %sunzip [filename].zip.001 for multi-volume files."' % (self.plugin.get_settings().get( ["prefix"]), self.plugin.get_settings().get( ["prefix"]))) if unzippable == None: return None, error_embed(author=self.plugin.get_printer_name(), title="File %s not found." % file_name) try: with zipfile.ZipFile(unzippable) as zip: fileOK = zip.testzip() if fileOK is not None: return None, error_embed(author=self.plugin.get_printer_name(), title="Bad zip file.", description='In case of multi-volume files, one could be missing.') availablefiles = zip.namelist() filestounpack = [] for f in availablefiles: if f.endswith('.gcode'): filestounpack.append(f) path = unzippable.rpartition('/')[0] + '/' for f in filestounpack: with open(path + f, 'wb') as file: with zip.open(f) as source: file.write(source.read()) self.plugin.get_file_manager().remove_file('local', unzippable.rpartition('/')[2]) except: return None, error_embed(author=self.plugin.get_printer_name(), title="Bad zip file.", description='In case of multi-volume files, one could be missing.') return None, success_embed(author=self.plugin.get_printer_name(), title='File(s) unzipped. ', description=str(filestounpack))