コード例 #1
0
def daemon():
    global status
    while True:
        try:
            status = 'disconnected'

            dev = getDevice()

            printer.info('USB Connected')
            status = 'connected'

            dev.reset()
            dev.set_configuration()
            cfg = dev.get_active_configuration()

            def is_out_ep(ep):
                return usb.util.endpoint_direction(ep.bEndpointAddress) == \
                    usb.util.ENDPOINT_OUT

            def is_in_ep(ep):
                return usb.util.endpoint_direction(ep.bEndpointAddress) == \
                    usb.util.ENDPOINT_IN

            out_ep = usb.util.find_descriptor(cfg[(0, 0)],
                                              custom_match=is_out_ep)
            in_ep = usb.util.find_descriptor(cfg[(0, 0)],
                                             custom_match=is_in_ep)

            assert out_ep is not None
            assert in_ep is not None

            poll_commands(in_ep, out_ep)
        except BaseException as e:
            printer.error('usb exception: ' + str(e))
        time.sleep(1)
コード例 #2
0
def load(path='conf/users.conf'):
    global users

    if not os.path.isfile(path):
        id = 'guest'
        users[id] = User()
        users[id].setPassword('guest')
        users[id].setId('guest')
        return

    firstLine = True
    map = ['id', 'password']
    with open(path, encoding="utf-8-sig") as f:
        for line in f.readlines():
            if firstLine:
                firstLine = False
                continue

            line = line.strip()

            if len(line) == 0 or line[0] == '#':
                continue

            if re.match(r'[A-Za-z\|\s]+', line, re.I):
                map = line.split('|')

            t = User()
            t.setPassword(map[1])
            t.setId(map[0])

            users[t.id] = t

            printer.info('loaded user ' + str(t.id))
コード例 #3
0
ファイル: nsps.py プロジェクト: angelwarwick/nut
def load(fileName='conf/files.json'):
    global hasLoaded

    if hasLoaded:
        return

    hasLoaded = True

    try:
        timestamp = time.process_time()

        if os.path.isfile(fileName):
            with open(fileName, encoding="utf-8-sig") as f:
                for k in json.loads(f.read()):
                    t = Nsp(None, None)

                    t.path = k['path']
                    t.titleId = k['titleId']
                    t.version = k['version']

                    if 'fileSize' in k:
                        t.fileSize = k['fileSize']

                    if not t.path:
                        continue

                    path = os.path.abspath(t.path)
                    if os.path.isfile(path) and os.path.exists(
                            path) and not __is_file_hidden(path):
                        files[path] = t  # Fs.Nsp(path, None)

    except:
        raise
    printer.info(f'loaded file list in {time.process_time() - timestamp} ' +
                 'seconds')
コード例 #4
0
ファイル: __init__.py プロジェクト: angelwarwick/nut
def initFiles():
    global isInitFiles
    if isInitFiles:
        return

    isInitFiles = True

    printer.info('Loading NSPs from the configuration file')
    nsps.load()
コード例 #5
0
 def send(self, timeout=60000):
     printer.info('sending %d bytes' % len(self.payload))
     self.o.write(b'\x12\x12\x12\x12', timeout=timeout)
     self.o.write(struct.pack('<I', self.command), timeout=timeout)
     self.o.write(struct.pack('<Q', len(self.payload)),
                  timeout=timeout)  # size
     self.o.write(struct.pack('<I', 0), timeout=timeout)  # threadId
     self.o.write(struct.pack('<H', 0), timeout=timeout)  # packetIndex
     self.o.write(struct.pack('<H', 0), timeout=timeout)  # packetCount
     self.o.write(struct.pack('<Q', 0), timeout=timeout)  # timestamp
     self.o.write(self.payload, timeout=timeout)
コード例 #6
0
    def _write(self, data):
        printer.info('usbresponse write')
        if self.bytesSent == 0 and not self.headersSent:
            self.sendHeader()

        if type(data) == str:
            data = data.encode('utf-8')

        if not len(data):
            return

        self.bytesSent += len(data)
        self.packet.payload = data
        self.packet.send(10 * 60 * 1000)
コード例 #7
0
ファイル: __init__.py プロジェクト: angelwarwick/nut
def scan():
    global hasScanned

    hasScanned = True

    initFiles()

    r = 0

    printer.info('Scanning NSPs on the filesystem')
    for path in config.paths.scan:
        r += nsps.scan(path)
    printer.info('Saving NSPs to the configuration file')
    nsps.save()
    return r
コード例 #8
0
ファイル: nsp.py プロジェクト: angelwarwick/nut
    def setPath(self, path):
        self.path = path
        self.version = '0'

        z = re.search(r'.*\[([a-fA-F0-9]{16})\].*', path, re.I)
        if z:
            self.titleId = z.groups()[0].upper()
        else:
            printer.info('could not get title id from filename, name needs ' +
                         'to contain [titleId] : ' + path)
            self.titleId = None

        z = re.match(r'.*\[v([0-9]+)\].*', path, re.I)
        if z:
            self.version = z.groups()[0]
コード例 #9
0
ファイル: __init__.py プロジェクト: angelwarwick/nut
def route(request, response, verb='get'):
    try:
        if len(request.bits) > 0 and request.bits[0] in mappings:
            i = request.bits[1]
            methodName = verb + i[0].capitalize() + i[1:]
            printer.info('routing to ' + methodName)
            method = getattr(
                mappings[request.bits[0]],
                methodName,
                Response404,
            )
            method(request, response, **request.query)
            return True
    except BaseException as e:
        printer.error('route exception: ' + str(e))
        return None
    return False
コード例 #10
0
ファイル: nsps.py プロジェクト: angelwarwick/nut
def removeEmptyDir(path, removeRoot=True):
    if not os.path.isdir(path):
        return

    # remove empty subfolders
    _files = os.listdir(path)
    if len(_files):
        for f in _files:
            if not f.startswith('.') and not f.startswith('_'):
                fullpath = os.path.join(path, f)
                if os.path.isdir(fullpath):
                    removeEmptyDir(fullpath)

    # if folder empty, delete it
    _files = os.listdir(path)
    if len(_files) == 0 and removeRoot:
        printer.info("Removing empty folder:" + path)
        os.rmdir(path)
コード例 #11
0
    def __init__(self, url):
        self.headers = {}
        self.path = url
        self.head = False
        self.url = urlparse(self.path)

        printer.info('url ' + self.path)

        self.bits = [x for x in self.url.path.split('/') if x]
        self.query = parse_qs(self.url.query)

        try:
            for k, v in self.query.items():
                self.query[k] = v[0]
        except:
            pass

        self.user = None
コード例 #12
0
ファイル: nsps.py プロジェクト: angelwarwick/nut
def scan(base, force=False):
    global hasScanned

    hasScanned = True
    i = 0

    fileList = {}

    printer.info(base)
    for root, _, _files in os.walk(base, topdown=False, followlinks=True):
        for name in _files:
            if __is_file_hidden(name):
                continue
            suffix = pathlib.Path(name).suffix

            if suffix in ['.nsp', '.nsz', '.nsz', '.xci', '.xcz']:
                path = os.path.abspath(root + '/' + name)
                fileList[path] = name

    if len(fileList) == 0:
        save()
        return 0

    progress = status.create(len(fileList), desc='Scanning files...')

    try:
        for path, name in fileList.items():
            try:
                progress.add(1)

                if path not in files:
                    printer.info('scanning ' + name)
                    nsp = Nsp(path, None)
                    nsp.getFileSize()

                    files[nsp.path] = nsp

                    i = i + 1
                    if i % 20 == 0:
                        save()
            except KeyboardInterrupt:
                progress.close()
                raise
            except BaseException as e:
                printer.info('An error occurred processing file: ' + str(e))
                raise

        save()
        progress.close()
    except BaseException as e:
        printer.info('An error occurred scanning files: ' + str(e))
        raise
    return i
コード例 #13
0
ファイル: __init__.py プロジェクト: angelwarwick/nut
def run():
    global httpd
    global sock
    global addr

    printer.info(
        f'{time.asctime()} Server Starts - {config.server.hostname}:' +
        f'{config.server.port}')
    try:
        addr = (config.server.hostname, config.server.port)
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind(addr)
        sock.listen(5)

        [Thread(i) for i in range(16)]
        for thread in threads:
            thread.join()
    except KeyboardInterrupt:
        pass

    printer.info(f'{time.asctime()} Server Stops - {config.server.hostname}:' +
                 f'{config.server.port}')
コード例 #14
0
    def recv(self, timeout=60000):
        printer.info('begin recv')
        header = bytes(self.i.read(32, timeout=timeout))
        printer.info('read complete')
        magic = header[:4]
        self.command = int.from_bytes(header[4:8], byteorder='little')
        self.size = int.from_bytes(header[8:16], byteorder='little')
        self.threadId = int.from_bytes(header[16:20], byteorder='little')
        self.packetIndex = int.from_bytes(header[20:22], byteorder='little')
        self.packetCount = int.from_bytes(header[22:24], byteorder='little')
        self.timestamp = int.from_bytes(header[24:32], byteorder='little')

        if magic != b'\x12\x12\x12\x12':
            printer.error('invalid magic! ' + str(magic))
            return False

        printer.info('receiving %d bytes' % self.size)
        self.payload = bytes(self.i.read(self.size, timeout=0))
        return True
コード例 #15
0
ファイル: nut.py プロジェクト: angelwarwick/nut
        args = parser.parse_args()

        if args.silent:
            printer.silent = True

        if args.hostname:
            args.server = True
            config.server.hostname = args.hostname

        if args.port:
            args.server = True
            config.server.port = int(args.port)

        status.start()

        printer.info('                        ,;:;;,')
        printer.info('                       ;;;;;')
        printer.info('               .=\',    ;:;;:,')
        printer.info('              /_\', "=. \';:;:;')
        printer.info('              @=:__,  \\,;:;:\'')
        printer.info('                _(\\.=  ;:;;\'')
        printer.info('               `"_(  _/="`')
        printer.info('                `"\'')

        if args.usb:
            try:
                from nut_impl import usb
            except BaseException as e:
                printer.error('pip3 install pyusb, required for USB coms: ' +
                              f'{str(e)}')
            nut_impl.scan()
コード例 #16
0
def serveFile(response, path, filename=None, start=None, end=None):
    try:
        if start is not None:
            start = int(start)

        if end is not None:
            end = int(end)

        if not filename:
            filename = os.path.basename(path)

        response.attachFile(filename)

        chunkSize = 0x400000

        with open(path, "rb") as f:
            f.seek(0, 2)
            size = f.tell()
            if start and end:
                if end is None:
                    end = size - 1
                else:
                    end = int(end)

                if start is None:
                    start = size - end
                else:
                    start = int(start)

                if start >= size or start < 0 or end <= 0:
                    return server.Response400(
                        None, response,
                        'Invalid range request %d - %d' % (start, end))

                response.setStatus(206)

            else:
                if start is None:
                    start = 0
                if end is None:
                    end = size

            if end >= size:
                end = size

                if end <= start:
                    response.write(b'')
                    return

            printer.info('ranged request for %d - %d' % (start, end))
            f.seek(start, 0)

            response.setMime(path)
            response.setHeader('Accept-Ranges', 'bytes')
            response.setHeader('Content-Range',
                               f'bytes {start}-{end-1}/{size}')
            response.setHeader('Content-Length', str(end - start))
            response.sendHeader()

            if not response.head:
                size = end - start

                i = 0
                progress = status.create(
                    size, 'Downloading ' + os.path.basename(path))

                while i < size:
                    chunk = f.read(min(size - i, chunkSize))
                    i += len(chunk)

                    progress.add(len(chunk))

                    if chunk:
                        pass
                        response.write(chunk)
                    else:
                        break
                progress.close()
    except BaseException as e:
        printer.error('File download exception: ' + str(e))
        traceback.print_exc(file=sys.stdout)

    if response.bytesSent == 0:
        response.write(b'')
コード例 #17
0
def getDownload(request, response, start=None, end=None):
    try:
        nsp = nsps.getByTitleId(request.bits[2])
        response.attachFile(nsp.titleId + '.nsp')

        if len(request.bits) >= 5:
            start = int(request.bits[-2])
            end = int(request.bits[-1])

        chunkSize = 0x400000

        with open(nsp.path, "rb") as f:
            f.seek(0, 2)
            size = f.tell()
            if 'Range' in request.headers:
                _range = request.headers.get('Range').strip()
                start, end = _range.strip('bytes=').split('-')

                if end == '':
                    end = size - 1
                else:
                    end = int(end) + 1

                if start == '':
                    start = size - end
                else:
                    start = int(start)

                if start >= size or start < 0 or end <= 0:
                    return server.Response400(
                        request, response,
                        f'Invalid range request {start} - {end}')

                response.setStatus(206)

            else:
                if start is None:
                    start = 0
                if end is None:
                    end = size

            if end >= size:
                end = size

                if end <= start:
                    response.write(b'')
                    return

            printer.info('ranged request for %d - %d' % (start, end))
            f.seek(start, 0)

            response.setMime(nsp.path)
            response.setHeader('Accept-Ranges', 'bytes')
            response.setHeader('Content-Range',
                               f'bytes {start}-{end-1}/{size}')
            response.setHeader('Content-Length', str(end - start))
            response.sendHeader()

            if not response.head:
                size = end - start

                i = 0
                progress = status.create(
                    size, 'Downloading ' + os.path.basename(nsp.path))

                while i < size:
                    chunk = f.read(min(size - i, chunkSize))
                    i += len(chunk)

                    progress.add(len(chunk))

                    if chunk:
                        pass
                        response.write(chunk)
                    else:
                        break
                progress.close()
    except BaseException as e:
        printer.error('NSP download exception: ' + str(e))
        traceback.print_exc(file=sys.stdout)
    if response.bytesSent == 0:
        response.write(b'')