예제 #1
0
    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))
예제 #3
0
    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'])
예제 #4
0
    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')
예제 #5
0
    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()
예제 #6
0
 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)
예제 #9
0
 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])
예제 #10
0
 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))
예제 #11
0
    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))
예제 #12
0
    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")
예제 #13
0
    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"]))
예제 #14
0
    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))
예제 #16
0
    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)
예제 #17
0
    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']()
예제 #18
0
 def cancel_print(self):
     self.plugin.get_printer().cancel_print()
     return None, error_embed(author=self.plugin.get_printer_name(),
                              title='Print aborted')
예제 #19
0
    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))