예제 #1
0
파일: logging.py 프로젝트: rcrdnalor/mythtv
    def _setsyslog(cls, facility=LOGFACILITY.USER):
        cls._initlogger()
        try:
            facility = int(facility)
            for fac in dir(LOGFACILITY):
                if '_' in fac:
                    continue
                if getattr(LOGFACILITY, fac) == facility:
                    facility = 'LOG_' + fac
                    break
            else:
                raise MythError("Invalid syslog facility")

        except ValueError:
            if not facility.startswith('LOG_'):
                facility = 'LOG_' + facility.upper()
            if not hasattr(LOGFACILITY, facility[4:]):
                raise MythError("Invalid syslog facility")

        cls._SYSLOG = facility
        application = argv[0]
        if '/' in application:
            application = application.rsplit('/', 1)[1]
        syslog.openlog(application, syslog.LOG_NDELAY | syslog.LOG_PID,
                       getattr(syslog, facility))
        cls._logwrite = cls._logsyslog
        # clear other logging options:
        if cls._LOGFILE:
            if cls._LOGFILE.fileno() != 1:
                cls._LOGFILE.close()
            cls._LOGFILE = None
        if cls._JOURNALLOG:
            cls._JOURNALLOG = False
예제 #2
0
파일: other.py 프로젝트: rcrdnalor/mythtv
    def dlrecv(self, bufsize, flags=0, deadline=None):
        # pull default timeout
        if deadline is None:
            deadline = self._deadline
        if deadline < 1000:
            deadline += time()

        buff = BytesIO()
        # loop until necessary data has been received
        while bufsize > buff.tell():
            # wait for data on the socket
            t = time()
            timeout = (deadline-t) if (deadline-t>0) else 0.0
            if len(select([self],[],[], timeout)[0]) == 0:
                # deadline reached, terminate
                return b''

            # append response to buffer
            p = buff.tell()
            try:
                buff.write(self.recv(bufsize-buff.tell(), flags))
            except socket.error as e:
                raise MythError(MythError.SOCKET, e.args)
            if buff.tell() == p:
               # no data read from a 'ready' socket, connection terminated
                raise MythError(MythError.SOCKET, (54, 'Connection reset by peer'))

            if timeout == 0:
                break
        return buff.getvalue()
예제 #3
0
파일: other.py 프로젝트: rcrdnalor/mythtv
    def dlexpect(self, pattern, flags=0, deadline=None):
        """Loop recv listening for a provided regular expression."""
        # pull default timeout
        if deadline is None:
            deadline = self._deadline
        if deadline < 1000:
            deadline += time()

        buff = BytesIO()
        # loop until pattern has been found
        while not pattern.search(buff.getvalue()):
            # wait for data on the socket
            t = time()
            timeout = (deadline-t) if (deadline-t>0) else 0.0
            if len(select([self],[],[], timeout)[0]) == 0:
                # deadline reached, terminate
                return b''

            # append response to buffer
            p = buff.tell()
            try:
                buff.write(self.recv(100, flags))
            except socket.error as e:
                raise MythError(MythError.SOCKET, e.args)
            if buff.tell() == p:
                # no data read from a 'ready' socket, connection terminated
                raise MythError(MythError.SOCKET, (54, 'Connection reset by peer'))

            if timeout == 0:
                break
        return buff.getvalue()
예제 #4
0
 def __call__(self, *args, **kwargs):
     if self.func is None:
         if len(args) == 1:
             self.func = args[0]
         elif 'func' in kwargs:
             self.func = kwargs['func']
         if not callable(self.func):
             raise MythError('_ProgramQuery must receive a callable '+\
                             'before it is functional')
         self.__doc__ = self.func.__doc__
         self.__name__ = self.func.__name__
         self.__module__ = self.func.__module__
         return self
     elif self.inst is None:
         raise MythError('Call to uninitialized _ProgramQuery instance')
     if self.sorted:
         return self.sortedrun(*args, **kwargs)
     return self.run(*args, **kwargs)
예제 #5
0
 def sendheader(self, data, flags=0):
     """Send data, prepending the length in the first 8 bytes."""
     try:
         self.log(MythLog.SOCKET|MythLog.NETWORK, MythLog.DEBUG, \
                             'write --> %d' % len(data), data)
         data = '%-8d%s' % (len(data), data)
         self.send(data, flags)
     except socket.error, e:
         raise MythError(MythError.SOCKET, e.args)
예제 #6
0
    def _runcmd(self, cmd):
        p = self.Process(cmd, self.useshell, self.log)
        p.wait()

        self.returncode = p.poll()
        self.stderr = p.stderr.read()
        if self.returncode:
            raise MythError(MythError.SYSTEM,self.returncode,cmd,self.stderr)

        return p.stdout.read()
예제 #7
0
파일: other.py 프로젝트: rcrdnalor/mythtv
 def sendheader(self, data, flags=0):
     """Send data, prepending the length in the first 8 bytes."""
     try:
         self.log(MythLog.SOCKET|MythLog.NETWORK, MythLog.DEBUG, \
                         'write --> %d' % len(data), py3_str(data, True))
         # build the byte array:
         length = b'%-8d' % len(data)
         data = b"".join([length, data])
         self.send(data, flags)
     except socket.error as e:
         raise MythError(MythError.SOCKET, e.args)
예제 #8
0
    def __init__(self,
                 path=None,
                 setting=None,
                 db=None,
                 useshell=True,
                 prefix=''):
        DBCache.__init__(self, db=db)
        self.log = MythLog(self.logmodule, db=self)
        self.path = None

        if setting is not None:
            # pull local setting from database
            host = self.gethostname()
            self.path = self.settings[host][setting]
            if self.path is None:
                # see if that setting is applied globally
                self.path = self.settings['NULL'][setting]
            if self.path is None:
                # not set globally either, use supplied default
                self.path = path
            if self.path is None:
                # no default supplied, just error out
                raise MythDBError(MythError.DB_SETTING, setting, host)

        if self.path is None:
            # setting not given, use path from argument
            if path is None:
                raise MythError('Invalid input to System()')
            self.path = path

        if prefix:
            self.path = os.path.join(prefix, self.path)

        cmd = self.path.split()[0]
        if self.path.startswith('/'):
            # test full given path
            if not os.access(cmd, os.F_OK):
                raise MythFileError('Defined executable path does not exist.')
        else:
            # search command from PATH
            for folder in os.environ['PATH'].split(':'):
                if os.access(os.path.join(folder, cmd), os.F_OK):
                    self.path = os.path.join(folder, self.path)
                    break
            else:
                raise MythFileError('Defined executable path does not exist.')

        self.returncode = 0
        self.stderr = ''
        self.useshell = useshell
예제 #9
0
 def _process(self, data):
     """
     Accepts a list of data, processes according to specified types,
         and returns a dictionary
     """
     if self._field_type != 'Pass':
         if len(data) != len(self._field_type):
             raise MythError('Incorrect raw input length to DictData()')
         data = list(data)
         for i, v in enumerate(data):
             if v == '':
                 data[i] = None
             else:
                 data[i] = self._trans[self._field_type[i]](v)
     return dict(zip(self._field_order, data))
예제 #10
0
파일: logging.py 프로젝트: rcrdnalor/mythtv
 def _setjournallog(cls):
     cls._initlogger()
     if journal:
         cls._JOURNALLOG = True
         cls._logwrite = cls._logjournallog
         # clear other logging options:
         if cls._LOGFILE:
             if cls._LOGFILE.fileno() != 1:
                 cls._LOGFILE.close()
             cls._LOGFILE = None
         if cls._SYSLOG:
             cls._SYSLOG = None
             syslog.closelog()
     else:
         raise MythError("Error: Python module 'systemd.journal' not available! " + \
                         "Please install 'python-systemd' module.")
예제 #11
0
파일: other.py 프로젝트: rcrdnalor/mythtv
    def __init__(self, func):
        # set function and update strings
        self.func = func
        self.__doc__ = self.func.__doc__
        self.__name__ = self.func.__name__
        self.__module__ = self.func.__module__

        # set defaults
        self.table = None
        self.handler = None
        self.require = ()
        self.joins = ()

        # pull in properties
        self.func(self, self)

        # sanity check
        if (self.table is None) or (self.handler is None):
            raise MythError('Improperly configured databaseSearch class')
예제 #12
0
파일: msearch.py 프로젝트: yvlf/mythtv
 def __init__(self):
     self.log = MythLog('Python M-Search')
     port = 1900
     addr = '239.255.255.250'
     self.dest = (addr, port)
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                               socket.IPPROTO_UDP)
     self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     listening = False
     while listening == False:
         try:
             self.sock.bind(('', port))
             self.addr = (addr, port)
             listening = True
         except socket.error, e:
             if port < 1910:
                 port += 1
             else:
                 raise MythError(MythError.SOCKET, e)
예제 #13
0
파일: logging.py 프로젝트: rcrdnalor/mythtv
 def _parseinput(cls):
     args = iter(argv)
     next(args)
     n = 0
     try:
         while True:
             arg = next(args)
             if arg == '--quiet':
                 cls._QUIET += 1
             elif arg == '--nodblog':
                 cls._DBLOG = False
             elif arg == '--enable-dblog':
                 cls._DBLOG = True
             elif arg == '--loglevel':
                 cls._setlevel(next(args))
             elif arg == '--verbose':
                 cls._setmask(next(args))
             elif arg == '--logfile':
                 cls._setfile(next(args))
                 n += 1
             elif arg == '--logpath':
                 cls._setpath(next(args))
                 n += 1
             elif arg == '--syslog':
                 cls._setsyslog(next(args))
                 n += 1
             elif arg == '--systemd-journal':
                 cls._setjournallog()
                 n += 1
             elif arg == '--':
                 break
     except StopIteration:
         pass
     # only allow one logging method
     if (n > 1):
         raise MythError("Error:  These logging options are mutually exclusive: " + \
                         "'logfile', 'logpath', 'syslog' or 'systemd-journal'!")
예제 #14
0
def ftopen(file, mode, forceremote=False, nooverwrite=False, db=None, \
                       chanid=None, starttime=None, download=False):
    """
    ftopen(file, mode, forceremote=False, nooverwrite=False, db=None)
                                        -> FileTransfer object
                                        -> file object
    Method will attempt to open file locally, falling back to remote access
            over mythprotocol if necessary.
    'forceremote' will force a FileTransfer object if possible.
    'file' takes a standard MythURI:
                myth://<group>@<host>:<port>/<path>
    'mode' takes a 'r' or 'w'
    'nooverwrite' will refuse to open a file writable,
                if a local file is found.
    """
    db = DBCache(db)
    log = MythLog('Python File Transfer', db=db)
    reuri = re.compile(\
        'myth://((?P<group>.*)@)?(?P<host>[\[\]a-zA-Z0-9_\-\.]*)(:[0-9]*)?/(?P<file>.*)')
    reip = re.compile('(?:\d{1,3}\.){3}\d{1,3}')

    if mode not in ('r', 'w'):
        raise TypeError("File I/O must be of type 'r' or 'w'")

    if chanid and starttime:
        protoopen = lambda host, file, storagegroup: \
                      RecordFileTransfer(host, file, storagegroup,\
                                         mode, chanid, starttime, db)
    elif download:
        protoopen = lambda host, lfile, storagegroup: \
                      DownloadFileTransfer(host, lfile, storagegroup, \
                                           mode, file, db)
    else:
        protoopen = lambda host, file, storagegroup: \
                      FileTransfer(host, file, storagegroup, mode, db)

    # process URI (myth://<group>@<host>[:<port>]/<path/to/file>)
    match = reuri.match(file)
    if match is None:
        raise MythError('Invalid FileTransfer input string: ' + file)
    host = match.group('host')
    filename = match.group('file')
    sgroup = match.group('group')
    if sgroup is None:
        sgroup = 'Default'

    # get full system name
    host = host.strip('[]')
    if reip.match(host) or check_ipv6(host):
        host = db._gethostfromaddr(host)

    # user forced to remote access
    if forceremote:
        if (mode == 'w') and (filename.find('/') != -1):
            raise MythFileError(MythError.FILE_FAILED_WRITE, file,
                                'attempting remote write outside base path')
        if nooverwrite and FileOps(host, db=db).fileExists(filename, sgroup):
            raise MythFileError(MythError.FILE_FAILED_WRITE, file,
                                'refusing to overwrite existing file')
        return protoopen(host, filename, sgroup)

    if mode == 'w':
        # check for pre-existing file
        path = FileOps(host, db=db).fileExists(filename, sgroup)
        sgs = list(db.getStorageGroup(groupname=sgroup))
        if path is not None:
            if nooverwrite:
                raise MythFileError(MythError.FILE_FAILED_WRITE, file,
                                    'refusing to overwrite existing file')
            for sg in sgs:
                if sg.dirname in path:
                    if sg.local:
                        return open(sg.dirname + filename, mode)
                    else:
                        return protoopen(host, filename, sgroup)

        # prefer local storage for new files
        for i, v in reversed(list(enumerate(sgs))):
            if not v.local:
                sgs.pop(i)
            else:
                st = os.statvfs(v.dirname)
                v.free = st[0] * st[3]
        if len(sgs) > 0:
            # choose path with most free space
            sg = sorted(sgs, key=lambda sg: sg.free, reverse=True)[0]
            # create folder if it does not exist
            if filename.find('/') != -1:
                path = sg.dirname + filename.rsplit('/', 1)[0]
                if not os.access(path, os.F_OK):
                    os.makedirs(path)
            log(log.FILE, log.INFO, 'Opening local file (w)',
                sg.dirname + filename)
            return open(sg.dirname + filename, mode)

        # fallback to remote write
        else:
            if filename.find('/') != -1:
                raise MythFileError(
                    MythError.FILE_FAILED_WRITE, file,
                    'attempting remote write outside base path')
            return protoopen(host, filename, sgroup)
    else:
        # search for file in local directories
        sg = findfile(filename, sgroup, db)
        if sg is not None:
            # file found, open local
            log(log.FILE, log.INFO, 'Opening local file (r)',
                sg.dirname + filename)
            return open(sg.dirname + filename, mode)
        else:
            # file not found, open remote
            return protoopen(host, filename, sgroup)