Beispiel #1
0
class BEConnection( object ):
    """
    This is the basic backend connection object.
    You probably don't want to use this directly.
    """
    logmodule = 'Python Backend Connection'

    def __init__(self, backend, port, localname=None,
                    blockshutdown=False, timeout=10.0):
        self.connected = False
        self.log = MythLog(self.logmodule)
        self._socklock = allocate_lock()

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = timeout
        self.blockshutdown = blockshutdown

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend [%s]:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
        except:
Beispiel #2
0
class BEConnection( object ):
    """
    This is the basic backend connection object.
    You probably don't want to use this directly.
    """
    logmodule = 'Python Backend Connection'

    def __init__(self, backend, port, localname=None,
                    blockshutdown=False, timeout=10.0):
        self.connected = False
        self.log = MythLog(self.logmodule)
        self._socklock = allocate_lock()

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = timeout
        self.blockshutdown = blockshutdown

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET)
            self.connected = False
            self.log(MythLog.GENERAL, MythLog.CRIT,
                    "Couldn't connect to backend [%s]:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
        except:
Beispiel #3
0
    def __init__(self, backend, port, localname=None,
                    blockshutdown=False, timeout=10.0):
        self.connected = False
        self.log = MythLog(self.logmodule)
        self._socklock = allocate_lock()

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = timeout
        self.blockshutdown = blockshutdown

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET)
            self.connected = False
            self.log(MythLog.GENERAL, MythLog.CRIT,
                    "Couldn't connect to backend [%s]:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
Beispiel #4
0
    def formatJob(self, cmd):
        """
        Program.formatPath(cmd) -> formatted command string
                'cmd' string is formatted as per MythJobQueue syntax
        """
        for tag in ('chanid', 'title', 'subtitle', 'description', 'hostname',
                    'category', 'recgroup', 'playgroup', 'parentid', 'findid',
                    'recstatus', 'rectype'):
            cmd = cmd.replace('%%%s%%' % tag.upper(), str(self[tag]))
        cmd = cmd.replace('%ORIGINALAIRDATE%', self.airdate.isoformat())
        for (tag,
             data) in (('STARTTIME', 'recstartts'), ('ENDTIME', 'recendts'),
                       ('PROGSTART', 'starttime'), ('PROGEND', 'endtime')):
            t = self[data]
            cmd = cmd.replace('%%%s%%' % tag, t.mythformat())
            cmd = cmd.replace('%%%sISO%%' % tag, t.isoformat())
            cmd = cmd.replace('%%%sISOUTC%%' % tag, \
                        (t+timedelta(0,altzone)).isoformat())
        cmd = cmd.replace('%VERBOSELEVEL%', MythLog._parsemask())
        cmd = cmd.replace('%RECID%', str(self.recordid))

        path = FileOps(self.hostname, db=self._db).fileExists(\
                        self.filename.rsplit('/',1)[1], self.storagegroup)
        cmd = cmd.replace('%DIR%', path.rsplit('/', 1)[0])
        cmd = cmd.replace('%FILE%', path.rsplit('/', 1)[1])
        cmd = cmd.replace('%REACTIVATE%', str(OldRecorded(\
                    (self.chanid, self.recstartts),db=self._db).reactivate))
        return cmd
Beispiel #5
0
    def __init__(self, path=None, setting=None, db=None, useshell=True):
        DBCache.__init__(self, db=db)
        self.log = MythLog(self.logmodule, db=self)
        self.path = None

        if setting is not None:
            # pull setting from database, substitute from argument if needed
            host = self.gethostname()
            self.path = self.settings[host][setting]
            if (self.path is None) and (path is None):
                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

        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
Beispiel #6
0
    def __init__(self, backend=None, port=None, db=None):
        if backend and port:
            XMLConnection.__init__(self, backend, port)
            self.db = db
            return

        self.db = DBCache(db)
        self.log = MythLog('Python XML Connection')
        if backend is None:
            # use master backend
            backend = self.db.settings.NULL.MasterServerIP
        if re.match('(?:\d{1,3}\.){3}\d{1,3}',backend):
            # process ip address
            with self.db.cursor(self.log) as cursor:
                if cursor.execute("""SELECT hostname FROM settings
                                     WHERE value='BackendServerIP'
                                     AND data=%s""", backend) == 0:
                    raise MythDBError(MythError.DB_SETTING, 
                                        backend+': BackendServerIP')
                self.host = cursor.fetchone()[0]
            self.port = int(self.db.settings[self.host].BackendStatusPort)
        else:
            # assume given a hostname
            self.host = backend
            self.port = int(self.db.settings[self.host].BackendStatusPort)
            if not self.port:
                # try a truncated hostname
                self.host = backend.split('.')[0]
                self.port = int(self.db.setting[self.host].BackendStatusPort)
                if not self.port:
                    raise MythDBError(MythError.DB_SETTING, 
                                        backend+': BackendStatusPort')
Beispiel #7
0
    def __init__(self, backend, port, localname=None,
                    blockshutdown=False, timeout=10.0):
        self.connected = False
        self.log = MythLog(self.logmodule)
        self._socklock = allocate_lock()

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = timeout
        self.blockshutdown = blockshutdown

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend [%s]:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
Beispiel #8
0
 def __init__(self, host, port, deadline=10.0, test=True):
     self.isConnected = False
     self.host = host
     self.port = int(port)
     self.log = MythLog('Python Frontend Connection')
     self._deadline = deadline
     self.connect(test)
Beispiel #9
0
    def formatJob(self, cmd):
        """
        Program.formatPath(cmd) -> formatted command string
                'cmd' string is formatted as per MythJobQueue syntax
        """
        for tag in ('chanid','title','subtitle','description','hostname',
                    'category','recgroup','playgroup','parentid','findid',
                    'recstatus','rectype'):
            cmd = cmd.replace('%%%s%%' % tag.upper(), str(self[tag]))
        cmd = cmd.replace('%ORIGINALAIRDATE%', self.airdate.isoformat())
        for (tag, data) in (('STARTTIME','recstartts'),('ENDTIME','recendts'),
                            ('PROGSTART','starttime'),('PROGEND','endtime')):
            t = self[data]
            cmd = cmd.replace('%%%s%%' % tag, t.mythformat())
            cmd = cmd.replace('%%%sISO%%' % tag, t.isoformat())
            cmd = cmd.replace('%%%sISOUTC%%' % tag, \
                        (t+timedelta(0,altzone)).isoformat())
        cmd = cmd.replace('%VERBOSELEVEL%', MythLog._parsemask())
        cmd = cmd.replace('%RECID%', str(self.recordid))

        path = FileOps(self.hostname, db=self._db).fileExists(\
                        self.filename.rsplit('/',1)[1], self.storagegroup)
        cmd = cmd.replace('%DIR%', path.rsplit('/',1)[0])
        cmd = cmd.replace('%FILE%',path.rsplit('/',1)[1])
        cmd = cmd.replace('%REACTIVATE%', str(OldRecorded(\
                    (self.chanid, self.recstartts),db=self._db).reactivate))
        return cmd
Beispiel #10
0
    def __init__(self, backend=None, noshutdown=False, db=None, opts=None):
        self.db = DBCache(db)
        self.log = MythLog(self.logmodule, db=self.db)
        self.hostname = None

        if opts is None:
            self.opts = BEConnection.BEConnOpts(noshutdown)
        else:
            self.opts = opts

        if backend is None:
            # no backend given, use master
            self.host = self.db.settings.NULL.MasterServerIP

        else:
            if self._reip.match(backend):
                # given backend is IP address
                self.host = backend
            else:
                # given backend is hostname, pull address from database
                self.hostname = backend
                self.host = self.db.settings[backend].BackendServerIP
                if not self.host:
                    raise MythDBError(MythError.DB_SETTING, 'BackendServerIP',
                                      backend)

        if self.hostname is None:
            # reverse lookup hostname from address
            with self.db.cursor(self.log) as cursor:
                if cursor.execute(
                        """SELECT hostname FROM settings
                                     WHERE value='BackendServerIP'
                                     AND data=?""", [self.host]) == 0:
                    # no match found
                    raise MythDBError(MythError.DB_SETTING, 'BackendServerIP',
                                      self.host)
                self.hostname = cursor.fetchone()[0]

        # lookup port from database
        self.port = int(self.db.settings[self.hostname].BackendServerPort)
        if not self.port:
            raise MythDBError(MythError.DB_SETTING, 'BackendServerPort',
                              self.port)

        self._uuid = uuid4()
        self._ident = '%s:%d' % (self.host, self.port)
        if self._ident in self._shared:
            # existing connection found
            # register and reconnect if necessary
            self.be = self._shared[self._ident]
            self.be.registeruser(self._uuid, self.opts)
            self.be.reconnect()
        else:
            # no existing connection, create new
            self.be = BEConnection(self.host, self.port, \
                                    self.db.gethostname(), self.opts)
            self.be.registeruser(self._uuid, self.opts)
            self._shared[self._ident] = self.be
Beispiel #11
0
    def __init__(self, dbconn):
        self.log = MythLog('Python Database Connection')
        self.tablefields = None
        self.settings = None
        self.dbconn = dbconn
        self._refs = {}

        self.log(MythLog.DATABASE, "Attempting connection",
                 '\n'.join(["'%s': '%s'" % (k, v) for k, v in dbconn.items()]))
        try:
            _Connection_Pool.__init__(self)
        except:
            raise MythDBError(MythError.DB_CONNECTION, dbconn)
Beispiel #12
0
    def __init__(self, backend, port, localname=None, \
                            opts=None, deadline=10.0):
        """
        BEConnection(backend, type, db=None) -> backend socket connection

        'backend' can be either a hostname or IP address, or will default
            to the master backend if None.
        """
        self._regusers = weakref.WeakValueDictionary()
        self._regevents = weakref.WeakValueDictionary()
        self._socklock = allocate_lock()

        self.connected = False
        self.threadrunning = False
        self.log = MythLog(self.logmodule)

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = deadline

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        self.opts = opts
        if self.opts is None:
            self.opts = self.BEConnOpts()
        self.eventqueue = Queue.Queue()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend %s:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
Beispiel #13
0
    def __init__(self, dbconn):
        self.log = MythLog('Python Database Connection')
        self.tablefields = None
        self.settings = None
        self._pool = []
        self._inuse = {}
        self._stack = {}
        self._refs = {}
        self._poolsize = self._defpoolsize
        self.dbconn = dbconn

        try:
            self.log(MythLog.DATABASE, "Attempting connection", 
                '\n'.join(["'%s': '%s'" % (k,v) for k,v in dbconn.items()]))
            for i in range(self._poolsize):
                self._pool.append(self.connect())
        except:
            raise MythDBError(MythError.DB_CONNECTION, dbconn)
Beispiel #14
0
 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)
Beispiel #15
0
    def __init__(self, backend, port, localname=None, \
                            opts=None, deadline=10.0):
        """
        BEConnection(backend, type, db=None) -> backend socket connection

        'backend' can be either a hostname or IP address, or will default
            to the master backend if None.
        """
        self._regusers = weakref.WeakValueDictionary()
        self._regevents = weakref.WeakValueDictionary()
        self._socklock = allocate_lock()

        self.connected = False
        self.threadrunning = False
        self.log = MythLog(self.logmodule)

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = deadline

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        self.opts = opts
        if self.opts is None:
            self.opts = self.BEConnOpts()
        self.eventqueue = Queue.Queue()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend %s:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
Beispiel #16
0
    def formatJob(self, cmd):
        """
        Program.formatPath(cmd) -> formatted command string
                'cmd' string is formatted as per MythJobQueue syntax
        """
        for tag in (
            "chanid",
            "title",
            "subtitle",
            "description",
            "hostname",
            "category",
            "recgroup",
            "playgroup",
            "parentid",
            "findid",
            "recstatus",
            "rectype",
        ):
            cmd = cmd.replace("%%%s%%" % tag.upper(), str(self[tag]))
        cmd = cmd.replace("%ORIGINALAIRDATE%", self.airdate.isoformat())
        for (tag, data) in (
            ("STARTTIME", "recstartts"),
            ("ENDTIME", "recendts"),
            ("PROGSTART", "starttime"),
            ("PROGEND", "endtime"),
        ):
            t = self[data]
            cmd = cmd.replace("%%%s%%" % tag, t.mythformat())
            cmd = cmd.replace("%%%sISO%%" % tag, t.isoformat())
            cmd = cmd.replace("%%%sISOUTC%%" % tag, (t + timedelta(0, altzone)).isoformat())
        cmd = cmd.replace("%VERBOSELEVEL%", MythLog._parselevel())
        cmd = cmd.replace("%RECID%", str(self.recordid))

        path = FileOps(self.hostname, db=self._db).fileExists(self.filename.rsplit("/", 1)[1], self.storagegroup)
        cmd = cmd.replace("%DIR%", path.rsplit("/", 1)[0])
        cmd = cmd.replace("%FILE%", path.rsplit("/", 1)[1])
        cmd = cmd.replace("%REACTIVATE%", str(OldRecorded((self.chanid, self.recstartts), db=self._db).reactivate))
        return cmd
Beispiel #17
0
class BEConnection( object ):
    """
    This is the basic backend connection object.
    You probably dont want to use this directly.
    """
    logmodule = 'Python Backend Connection'

    class BEConnOpts( OrdDict ):
        def __init__(self, noshutdown=False, systemevents=False,
                           generalevents=False):
            OrdDict.__init__(self, (('noshutdown',noshutdown),
                                    ('systemevents',systemevents),
                                    ('generalevents',generalevents)))
        def __and__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] & other[key]:
                    res[key] = True
            return res
        def __or__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] | other[key]:
                    res[key] = True
            return res
        def __xor__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] ^ other[key]:
                    res[key] = True
            return res

    def __init__(self, backend, port, localname=None, \
                            opts=None, deadline=10.0):
        """
        BEConnection(backend, type, db=None) -> backend socket connection

        'backend' can be either a hostname or IP address, or will default
            to the master backend if None.
        """
        self._regusers = weakref.WeakValueDictionary()
        self._regevents = weakref.WeakValueDictionary()
        self._socklock = allocate_lock()

        self.connected = False
        self.threadrunning = False
        self.log = MythLog(self.logmodule)

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = deadline

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        self.opts = opts
        if self.opts is None:
            self.opts = self.BEConnOpts()
        self.eventqueue = Queue.Queue()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend %s:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
        except:
Beispiel #18
0
 def __init__(self, *args, **kwargs):
     socket.socket.__init__(self, *args, **kwargs)
     self.log = MythLog('Python Socket')
     self.setdeadline(10.0)
Beispiel #19
0
 def __init__(self, db):
     self.db = db
     self.log = MythLog('Schema Update (%s)' % self._schema_name)
Beispiel #20
0
    def __init__(self,
                 backend=None,
                 blockshutdown=False,
                 events=False,
                 db=None):
        self.db = DBCache(db)
        self.log = MythLog(self.logmodule, db=self.db)
        self.hostname = None

        self.sendcommands = True
        self.blockshutdown = blockshutdown
        self.receiveevents = events

        if backend is None:
            # no backend given, use master
            self.host = self.db.settings.NULL.MasterServerIP

        else:
            backend = backend.strip('[]')
            if self._reip.match(backend):
                # given backend is IP address
                self.host = backend
            elif check_ipv6(backend):
                # given backend is IPv6 address
                self.host = backend
            else:
                # given backend is hostname, pull address from database
                self.hostname = backend
                self.host = self.db.settings[backend].BackendServerIP
                if not self.host:
                    raise MythDBError(MythError.DB_SETTING, 'BackendServerIP',
                                      backend)

        if self.hostname is None:
            # reverse lookup hostname from address
            with self.db.cursor(self.log) as cursor:
                if cursor.execute(
                        """SELECT hostname FROM settings
                                     WHERE value='BackendServerIP'
                                     AND data=?""", [self.host]) == 0:
                    # no match found
                    raise MythDBError(MythError.DB_SETTING, 'BackendServerIP',
                                      self.host)
                self.hostname = cursor.fetchone()[0]

        # lookup port from database
        self.port = int(self.db.settings[self.hostname].BackendServerPort)
        if not self.port:
            raise MythDBError(MythError.DB_SETTING, 'BackendServerPort',
                              self.port)

        self._ident = '%s:%d' % (self.host, self.port)
        if self._ident in self._shared:
            # existing connection found
            self._conn = self._shared[self._ident]
            if self.sendcommands:
                if self._conn.command is None:
                    self._conn.command = self._newcmdconn()
                elif self.blockshutdown:
                    # upref block of shutdown
                    # issue command to backend if needed
                    self._conn.blockshutdown += 1
                    if self._conn.blockshutdown == 1:
                        self._conn.command.blockShutdown()
            if self.receiveevents:
                if self._conn.event is None:
                    self._conn.event = self._neweventconn()
        else:
            # no existing connection, create new
            self._conn = self._ConnHolder()

            if self.sendcommands:
                self._conn.command = self._newcmdconn()
                if self.blockshutdown:
                    self._conn.blockshutdown = 1
            if self.receiveevents:
                self._conn.event = self._neweventconn()

            self._shared[self._ident] = self._conn

        self._events = self._listhandlers()
        for func in self._events:
            self.registerevent(func)
Beispiel #21
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):
        with db.cursor(log) as cursor:
            if cursor.execute(
                    """SELECT hostname FROM settings
                                 WHERE value='BackendServerIP'
                                 AND data=%s""", host) == 0:
                raise MythDBError(MythError.DB_SETTING, \
                                  'BackendServerIP', backend)
            host = cursor.fetchone()[0]

    # 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)
Beispiel #22
0
class BEConnection( object ):
    """
    This is the basic backend connection object.
    You probably dont want to use this directly.
    """
    logmodule = 'Python Backend Connection'

    class BEConnOpts( OrdDict ):
        def __init__(self, noshutdown=False, systemevents=False,
                           generalevents=False):
            OrdDict.__init__(self, (('noshutdown',noshutdown),
                                    ('systemevents',systemevents),
                                    ('generalevents',generalevents)))
        def __and__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] & other[key]:
                    res[key] = True
            return res
        def __or__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] | other[key]:
                    res[key] = True
            return res
        def __xor__(self, other):
            res = self.__class__()
            for key in self._field_order:
                if self[key] ^ other[key]:
                    res[key] = True
            return res

    def __init__(self, backend, port, localname=None, \
                            opts=None, deadline=10.0):
        """
        BEConnection(backend, type, db=None) -> backend socket connection

        'backend' can be either a hostname or IP address, or will default
            to the master backend if None.
        """
        self._regusers = weakref.WeakValueDictionary()
        self._regevents = weakref.WeakValueDictionary()
        self._socklock = allocate_lock()

        self.connected = False
        self.threadrunning = False
        self.log = MythLog(self.logmodule)

        self.host = backend
        self.port = port
        self.hostname = None
        self.deadline = deadline

        self.localname = localname
        if self.localname is None:
            self.localname = socket.gethostname()

        self.opts = opts
        if self.opts is None:
            self.opts = self.BEConnOpts()
        self.eventqueue = Queue.Queue()

        try:
            self.connect()
        except socket.error, e:
            self.log.logTB(MythLog.SOCKET|MythLog.EXTRA)
            self.connected = False
            self.log(MythLog.IMPORTANT|MythLog.SOCKET,
                    "Couldn't connect to backend %s:%d" \
                    % (self.host, self.port))
            raise MythBEError(MythError.PROTO_CONNECTION, self.host, self.port)
Beispiel #23
0
 def __init__(self, host, port):
     self.host, self.port = host, int(port)
     self.log = MythLog('Python XML Connection')