Exemple #1
0
 def _new_connection(self, client_sock):
     """
     Callback when a new client connects.
     """
     log.debug("New connection %s", client_sock)
     client_sock.buffer_size = self._socket.buffer_size
     client = Channel(sock=client_sock, auth_secret=self._auth_secret)
     for obj in self.objects:
         client.register(obj)
     client._send_auth_challenge()
     kaa.inprogress(client).connect(self.signals['client-connected'].emit)
Exemple #2
0
 def _new_connection(self, client_sock):
     """
     Callback when a new client connects.
     """
     log.debug("New connection %s", client_sock)
     client_sock.buffer_size = self._socket.buffer_size
     client = Channel(sock = client_sock, auth_secret = self._auth_secret)
     for obj in self.objects:
         client.register(obj)
     client._send_auth_challenge()
     kaa.inprogress(client).connect(self.signals['client-connected'].emit)
Exemple #3
0
 def _monitor(self, address, buffer_size, retry):
     while True:
         try:
             self.status = CONNECTING
             yield kaa.inprogress(self)
             # Python 2.4 code
             # TODO: remove all python 2.4 supporting code
             self._connect_inprogress.result
             self.status = CONNECTED
             # wait until the socket is closed
             yield self.signals.subset('closed').any()
         except Exception, e:
             # connection failed
             pass
         self._connect_inprogress = kaa.InProgress()
         self.status = DISCONNECTED
         # wait some time until we retry
         yield kaa.delay(retry)
         # reset variables
         self._authenticated = False
         self._pending_challenge = None
         self._read_buffer = []
         self.status = CONNECTING
         self._socket = kaa.Socket(buffer_size)
         self._socket.chunk_size = 1024
         self._socket.signals['read'].connect(self._handle_read)
         self._socket.signals['closed'].connect(self._handle_close)
         self._socket.connect(address).exception.connect(self._handle_refused)
Exemple #4
0
 def provide_image(self, path, **attributes):
     """
     HTTP callback for images
     """
     filename = ''
     path = urllib.unquote(path)
     if path.startswith('beacon'):
         filename = os.path.join(utils.imagedir, path[7:])
     if path.startswith('cache'):
         filename = os.path.join(utils.cachedir, path[6:])
     if path.startswith('thumbnail'):
         item = yield kaa.beacon.query(id=int(path.split('/')[2]), type=path.split('/')[1])
         if len(item) != 1:
             log.error('beacon returned wrong results')
             yield None
         thumbnail = item[0].get('thumbnail')
         if thumbnail.needs_update or 1:
             yield kaa.inprogress(thumbnail.create(priority=kaa.beacon.Thumbnail.PRIORITY_HIGH))
         filename = thumbnail.large
     if filename:
         if os.path.isfile(filename):
             yield open(filename).read(), None, None
         log.error('no file: %s' % filename)
         yield None
     else:
         yield None
Exemple #5
0
 def provide_image(self, path, **attributes):
     """
     HTTP callback for images
     """
     filename = ''
     path = urllib.unquote(path)
     if path.startswith('beacon'):
         filename = os.path.join(utils.imagedir, path[7:])
     if path.startswith('cache'):
         filename = os.path.join(utils.cachedir, path[6:])
     if path.startswith('thumbnail'):
         item = yield kaa.beacon.query(id=int(path.split('/')[2]), type=path.split('/')[1])
         if len(item) != 1:
             log.error('beacon returned wrong results')
             yield None
         thumbnail = item[0].get('thumbnail')
         if thumbnail.needs_update or 1:
             yield kaa.inprogress(thumbnail.create(priority=kaa.beacon.Thumbnail.PRIORITY_HIGH))
         filename = thumbnail.large
     if filename:
         if os.path.isfile(filename):
             yield open(filename).read(), None, None
         log.error('no file: %s' % filename)
         yield None
     else:
         yield None
Exemple #6
0
 def delete_item(self, item):
     """
     Delete an item.
     Called by Item objects
     """
     yield kaa.inprogress(self._db.read_lock)
     self._db.delete_object(item._beacon_id)
Exemple #7
0
 def _monitor(self, address, buffer_size, retry):
     while True:
         try:
             self.status = CONNECTING
             yield kaa.inprogress(self)
             # Python 2.4 code
             # TODO: remove all python 2.4 supporting code
             self._connect_inprogress.result
             self.status = CONNECTED
             # wait until the socket is closed
             yield self.signals.subset('closed').any()
         except Exception, e:
             # connection failed
             pass
         self._connect_inprogress = kaa.InProgress()
         self.status = DISCONNECTED
         # wait some time until we retry
         yield kaa.delay(retry)
         # reset variables
         self._authenticated = False
         self._pending_challenge = None
         self._read_buffer = []
         self.status = CONNECTING
         self._socket = kaa.Socket(buffer_size)
         self._socket.chunk_size = 1024
         self._socket.signals['read'].connect(self._handle_read)
         self._socket.signals['closed'].connect(self._handle_close)
         self._socket.connect(address).exception.connect(
             self._handle_refused)
Exemple #8
0
 def delete_item(self, item):
     """
     Delete an item.
     Called by Item objects
     """
     yield kaa.inprogress(self._db.read_lock)
     self._db.delete_object(item._beacon_id)
Exemple #9
0
 def newfunc(*args, **kwargs):
     global _client
     global signals
     if not _client:
         _client = Client()
         signals = _client.signals
     if not _client.connected:
         try:
             # wait for next connect
             if _client.channel.status != kaa.rpc.CONNECTED:
                 # this may raise an exception
                 yield kaa.inprogress(_client.channel)
             if not _client.connected:
                 yield kaa.inprogress(signals['connect'])
             log.info('beacon connected')
         except Exception, e:
             raise ConnectError(e)
Exemple #10
0
 def query(self, **query):
     """
     Query the database.
     """
     result = Query(self, **query)
     self._queries.append(weakref(result))
     yield kaa.inprogress(result)
     yield result
Exemple #11
0
 def query(self, **kwargs):
     """
     Query the database.
     """
     query = Query(self, **kwargs)
     # _queries is a WeakValueDictionary, so query will be weakly referenced.
     self._queries[query.id] = query
     yield kaa.inprogress(query)
     yield query
Exemple #12
0
 def query(self, **kwargs):
     """
     Query the database.
     """
     query = Query(self, **kwargs)
     # _queries is a WeakValueDictionary, so query will be weakly referenced.
     self._queries[query.id] = query
     yield kaa.inprogress(query)
     yield query
Exemple #13
0
 def newfunc(*args, **kwargs):
     global _client
     global signals
     if not _client:
         _client = Client()
         signals = _client.signals
     if not _client.connected:
         try:
             # wait for next connect
             if _client.channel.status != kaa.rpc.CONNECTED:
                 # this may raise an exception
                 yield kaa.inprogress(_client.channel)
             if not _client.connected:
                 yield kaa.inprogress(signals['connect'])
             log.info('beacon connected')
             for name, interface in plugins.load(_client).items():
                 globals()[name] = interface
         except Exception, e:
             raise ConnectError(e)
Exemple #14
0
 def newfunc(*args, **kwargs):
     global _client
     global signals
     if not _client:
         _client = Client()
         signals = _client.signals
     if not _client.connected:
         try:
             # wait for next connect
             if _client.channel.status != kaa.rpc.CONNECTED:
                 # this may raise an exception
                 yield kaa.inprogress(_client.channel)
             if not _client.connected:
                 yield kaa.inprogress(signals["connect"])
             log.info("beacon connected")
             for name, interface in plugins.load(_client).items():
                 globals()[name] = interface
         except Exception, e:
             raise ConnectError(e)
Exemple #15
0
 def get(self, filename):
     """
     Return an object for the given filename.
     """
     filename = os.path.realpath(filename)
     if not os.path.exists(filename):
         raise OSError('no such file or directory %s' % filename)
     q = Query(self, filename=filename)
     yield kaa.inprogress(q)
     yield q.get()
Exemple #16
0
 def get(self, filename):
     """
     Return an object for the given filename.
     """
     filename = os.path.realpath(filename)
     if not os.path.exists(filename):
         raise OSError('no such file or directory %s' % filename)
     q = Query(self, filename=filename)
     yield kaa.inprogress(q)
     yield q.get()
Exemple #17
0
 def _beacon_update_all(self):
     """
     Timed callback to write all changes to the db.
     Called by Item objects
     """
     yield kaa.inprogress(self._db.read_lock)
     changes = self._changed
     self._changed = []
     for item in changes:
         self._db.update_object(item._beacon_id, item._beacon_changes)
         item._beacon_changes = {}
     # commit to update monitors
     self._db.commit()
Exemple #18
0
 def _beacon_update_all(self):
     """
     Timed callback to write all changes to the db.
     Called by Item objects
     """
     yield kaa.inprogress(self._db.read_lock)
     changes = self._changed
     self._changed = []
     for item in changes:
         self._db.update_object(item._beacon_id, item._beacon_changes)
         item._beacon_changes = {}
     # commit to update monitors
     self._db.commit()
Exemple #19
0
 def images(self, path, **attributes):
     if path in self.image_cache_hashes:
         image = self.image_cache_hashes[path]
         if isinstance(image, kaa.beacon.Thumbnail):
             if image.needs_update or 1:
                 yield kaa.inprogress(image.create(priority=kaa.beacon.Thumbnail.PRIORITY_HIGH))
             if attributes.get('size', '') == 'small':
                 image = image.normal
             elif attributes.get('size', '') == 'normal':
                 image = image.large
             else:
                 image = image.name
         if image:
             yield open(image).read(), None, None
Exemple #20
0
 def __call__(self, widget, context):
     if self.condition:
         if not eval(self.condition, context):
             return kaa.InProgressAll()
     async = []
     for animation in self.animations:
         if animation.behaviour == 'move':
             x1 = x2 = widget.x
             if animation.x1 is not None:
                 x1 = animation.get_scaled('x1', 0, int)
             if animation.x2 is not None:
                 x2 = animation.get_scaled('x2', 0, int)
             y1 = y2 = widget.y
             if animation.y1 is not None:
                 y1 = animation.get_scaled('y1', 1, int)
             if animation.y2 is not None:
                 y2 = animation.get_scaled('y2', 1, int)
             start = x1, y1
             end = x2, y2
             widget.x = x1
             widget.y = y1
         elif animation.behaviour in ('xrotation', 'yrotation', 'zrotation'):
             start = end = getattr(widget, animation.behaviour)
             if animation.start is not None:
                 start = int(animation.start)
                 setattr(widget, animation.behaviour, start)
             if animation.end is not None:
                 end = int(animation.end)
             widget.rotation = start
         elif animation.behaviour == 'opacity':
             start = end = widget.opacity
             if animation.start is not None:
                 start = int(animation.start)
             if animation.end is not None:
                 end = int(animation.end)
             widget.opacity = start
         else:
             log.error('unsupported behaviour %s', animation.behaviour)
             continue
         a = widget.animate(float(animation.secs or 1),
               delay=float(animation.delay or 0))
         a.behave(animation.behaviour, start, end)
         async.append(kaa.inprogress(a))
     if self.process_children:
         for child in widget.children:
             eventhandler = child.eventhandler.get(self.event)
             if eventhandler is not None:
                 async.extend([ x(child, context) for x in eventhandler])
     return kaa.InProgressAll(*async)
Exemple #21
0
 def _call(self, cmd):
     self._busy = True
     log.debug('cmd %s', cmd)
     if self.dvbstreamer.stopping:
         log.info('waiting for dvbstreamer to be stopped')
         yield kaa.inprogress(self.dvbstreamer)
     if not self.dvbstreamer.running:
         # FIXME: this only works up to dvb9 but that should be enough
         log.info('starting dvbstreamer')
         self.dvbstreamer.start(['-a', self.config.adapter[-1]])
     async = kaa.InProgress()
     if self._ready:
         self._ready = False
         self._callback = async
         self.dvbstreamer.write(cmd + '\n')
Exemple #22
0
 def _call(self, cmd):
     self._busy = True
     log.debug('cmd %s', cmd)
     if self.dvbstreamer.stopping:
         log.info('waiting for dvbstreamer to be stopped')
         yield kaa.inprogress(self.dvbstreamer)
     if not self.dvbstreamer.running:
         # FIXME: this only works up to dvb9 but that should be enough
         log.info('starting dvbstreamer')
         self.dvbstreamer.start(['-a', self.config.adapter[-1]])
     async = kaa.InProgress()
     if self._ready:
         self._ready = False
         self._callback = async
         self.dvbstreamer.write(cmd + '\n')
Exemple #23
0
 def images(self, path, **attributes):
     if path in self.image_cache_hashes:
         image = self.image_cache_hashes[path]
         if isinstance(image, kaa.beacon.Thumbnail):
             if image.needs_update or 1:
                 yield kaa.inprogress(
                     image.create(
                         priority=kaa.beacon.Thumbnail.PRIORITY_HIGH))
             if attributes.get('size', '') == 'small':
                 image = image.normal
             elif attributes.get('size', '') == 'normal':
                 image = image.large
             else:
                 image = image.name
         if image:
             yield open(image).read(), None, None
Exemple #24
0
 def view(self, path, known=None, **attributes):
     result = self.application.get_json(self)
     result['type'] = self.application.name
     if str(result) != self.last_view[1]:
         self.last_view = self.last_view[0] + 1, str(result)
     while True:
         if not known or known != str(self.last_view[0]):
             result = self.application.get_json(self)
             result['type'] = self.application.name
             result['status'] = self.last_view[0]
             yield result
         # we need to wait for an update
         yield kaa.inprogress(self.signals['update'])
         result = self.application.get_json(self)
         result['type'] = self.application.name
         if str(result) != self.last_view[1]:
             self.last_view = self.last_view[0] + 1, str(result)
Exemple #25
0
    def __init__(self, mountpoint, query, *args, **kw):
        self._query = query
        self._filename_map = {}
        self._query_update_time = 0
        query.signals["changed"].connect_weak(self._query_changed)
        query.monitor()
        if kaa.inprogress(query).finished:
            # Query is already finished, so explicitly call _query_changed()
            # now to update the filename map.
            self._query_changed()

        fuse.Fuse.__init__(self, *args, **kw)

        self.multithreaded = 1
        # make it a real path because we will chdir to /
        self.mountpoint = os.path.realpath(mountpoint)
        self.parse(args=[self.mountpoint, "-f"])
Exemple #26
0
 def view(self, path, known=None, **attributes):
     result = self.application.get_json(self)
     result['type'] = self.application.name
     if str(result) != self.last_view[1]:
         self.last_view = self.last_view[0] + 1, str(result)
     while True:
         if not known or known != str(self.last_view[0]):
             result = self.application.get_json(self)
             result['type'] = self.application.name
             result['status'] = self.last_view[0]
             yield result
         # we need to wait for an update
         yield kaa.inprogress(self.signals['update'])
         result = self.application.get_json(self)
         result['type'] = self.application.name
         if str(result) != self.last_view[1]:
             self.last_view = self.last_view[0] + 1, str(result)
Exemple #27
0
 def _create(self, sid, blocksize, stream):
     """
     Create the FIFO and return the kaa.Socket and the IBBSocket object.
     """
     # Make a kaa.Socket to kaa.Socket connection. One socket will be
     # given to the outside, the other one will be used to communicate
     # with the IBBSocket.
     filename = kaa.tempfile('ibb', unique=True)
     socket1 = kaa.net.tls.TLSSocket()
     wait = kaa.inprogress(socket1.signals['new-client'])
     socket2 = kaa.Socket()
     socket1.listen(filename)
     yield socket2.connect(filename)
     socket1 = yield wait
     socket1.sid = sid
     socket2.signals['closed'].connect(self._app_close, sid)
     yield socket1, IBBSocket(socket2, self.remote.iqset, sid, blocksize, stream)
Exemple #28
0
    def animate(self, secs, alpha='inc', delay=0, callback=None, unparent=False):
        """
        Animate the object with the given animation. This returns an
        Animation object to add the behaviours. The animation is already
        started when this function returns.

        :param secs: number of seconds to run
        :param alpha: alpha function for this animation
        :param unparent: if set to True the widget will be unparented after the
            animation is finished.
        """
        a = animation.Animation(secs, alpha, callback)
        a.apply(self)
        a.start(delay)
        if unparent:
            kaa.inprogress(a).connect(self.unparent).ignore_caller_args = True
        return a
Exemple #29
0
 def _start_backend(self):
     # spawn the backend process
     args = [ 'python', os.path.dirname(__file__) + '/backend/main.py', self.name, self.logfile ]
     self._candy_dirty = True
     self.server = subprocess.Popen(args, stdout=sys.stdout, stderr=sys.stderr)
     retry = 50
     if os.path.exists(kaa.tempfile(self.name)):
         os.unlink(kaa.tempfile(self.name))
     while True:
         try:
             self.ipc = kaa.rpc.connect(self.name)
             yield kaa.inprogress(self.ipc)
             break
         except Exception, e:
             retry -= 1
             if retry == 0:
                 raise e
             time.sleep(0.1)
Exemple #30
0
 def connect(self):
     start = time.time()
     while True:
         try:
             channel = kaa.rpc.connect('thumb/socket')
             channel.register(self)
             self.rpc = channel.rpc
             yield kaa.inprogress(channel)
             yield None
         except Exception, e:
             # FIXME: rather than this kludge, catch only the exceptions likely to happen
             # if connection to thumbnail server fails.
             if isinstance(e, GeneratorExit):
                 raise
             if start + 3 < time.time():
                 # start time is up, something is wrong here
                 raise RuntimeError('unable to connect to thumbnail server')
             yield kaa.delay(0.01)
Exemple #31
0
 def _beacon_start_query(self, query):
     """
     Start the database query.
     """
     if not self._client.connected:
         # wait until the client is connected
         # FIXME: maybe the server is not running
         yield kaa.inprogress(self._client.signals['connect'])
     if 'parent' in query and isinstance(query['parent'], Item) and \
            not query['parent']._beacon_id:
         # The parent we want to use has no database id. This can happen for
         # new items while the scanning is still in progress. We need to
         # request the real database id and do the query when done.
         parent = query['parent']
         log.info('force data for %s', parent)
         async = parent.scan()
         if isinstance(async, kaa.InProgress):
             # Not an InProgress object if it is not file.
             yield async
Exemple #32
0
 def _beacon_start_query(self, query):
     """
     Start the database query.
     """
     if not self._client.connected:
         # wait until the client is connected
         # FIXME: maybe the server is not running
         yield kaa.inprogress(self._client.signals['connect'])
     if 'parent' in query and isinstance(query['parent'], Item) and \
            not query['parent']._beacon_id:
         # The parent we want to use has no database id. This can happen for
         # new items while the scanning is still in progress. We need to
         # request the real database id and do the query when done.
         parent = query['parent']
         log.info('force data for %s', parent)
         async = parent.scan()
         if isinstance(async, kaa.InProgress):
             # Not an InProgress object if it is not file.
             yield async
Exemple #33
0
 def connect(self):
     """
     Connect to the thumbnail server
     """
     start = time.time()
     while True:
         try:
             channel = kaa.rpc.connect('thumb/socket')
             channel.register(self)
             self.rpc = channel.rpc
             yield kaa.inprogress(channel)
             yield None
         except Exception, e:
             # FIXME: rather than this kludge, catch only the exceptions likely to happen
             # if connection to thumbnail server fails.
             if isinstance(e, GeneratorExit):
                 raise
             if start + 3 < time.time():
                 # start time is up, something is wrong here
                 raise RuntimeError('unable to connect to thumbnail server')
             yield kaa.delay(0.01)
Exemple #34
0
 def _device_add_to_database(self, metadata, devdict):
     """
     Add the device to the database
     """
     yield kaa.inprogress(self._db.read_lock)
     id = devdict.get('beacon.id')
     if devdict.get('volume.is_disc') == True and metadata and \
            metadata.get('mime') in ('video/vcd', 'video/dvd'):
         # pass rom drive
         type = metadata['mime'][6:]
         log.info('detect %s as %s' % (devdict.get('beacon.id'), type))
         mid = self._db.add_object("media", name=devdict.get('beacon.id'), content=type)['id']
         vid = self._db.add_object("video", name="", parent=('media', mid),
             title=unicode(get_title(metadata['label'])), media = mid)['id']
         for track in metadata.tracks:
             self._db.add_object('track_%s' % type, name='%02d' % track.trackno,
                 parent=('video', vid), media=mid, chapters=track.chapters,
                 length=track.length, audio=[ x.convert() for x in track.audio ],
                 subtitles=[ x.convert() for x in track.subtitles ])
         yield True
     if devdict.get('volume.disc.has_audio') and metadata:
         # Audio CD
         log.info('detect %s as audio cd' % devdict.get('beacon.id'))
         mid = self._db.add_object("media", name=devdict.get('beacon.id'), content='cdda')['id']
         aid = self._db.add_object("audio", name='', title = metadata.get('title'),
             artist = metadata.get('artist'),
             parent=('media', mid), media = mid)['id']
         for track in metadata.tracks:
             self._db.add_object('track_cdda', name=str(track.trackno),
                 title=track.get('title'), artist=track.get('artist'),
                 parent=('audio', aid), media=mid)
         yield True
     # filesystem
     log.info('detect %s as filesystem' % devdict.get('beacon.id'))
     mid = self._db.add_object("media", name=devdict.get('beacon.id'), content='file')['id']
     mtime = 0
     if devdict.get('block.device'):
         mtime = os.stat(devdict.get('block.device'))[stat.ST_MTIME]
     self._db.add_object("dir", name="", parent=('media', mid), media=mid, mtime=mtime)
     yield True
Exemple #35
0
 def play(self, item, resources):
     """
     play an item
     """
     if not self.status in (freevo.STATUS_IDLE, freevo.STATUS_STOPPED):
         # Already running, stop the current player by sending a STOP
         # event. The event will also get to the playlist behind the
         # current item and the whole list will be stopped.
         freevo.Event(freevo.STOP, handler=self.eventhandler).post()
         # Now connect to our own 'stop' signal once to repeat this current
         # function call without the player playing
         yield kaa.inprogress(self.signals['stop'])
         if not self.status in (freevo.STATUS_IDLE, freevo.STATUS_STOPPED):
             log.error('unable to stop current audio playback')
             yield False
     if not kaa.main.is_running():
         # Freevo is in shutdown mode, do not start a new player, the old
         # only stopped because of the shutdown.
         yield False
     if (yield self.get_resources(*resources, force=True)) == False:
         log.error("Can't get resource %s", str(resources))
         yield False
     # Store item and playlist. We need to keep the playlist object
     # here to make sure it is not deleted when player is running in
     # the background.
     self.item = item
     self.playlist = self.item.playlist
     if self.playlist:
         self.playlist.select(self.item)
     # Set the current item to the gui engine
     self.context.item = self.item.properties
     self.context.playlist = self.playlist
     self.item.elapsed_secs = 0
     self.status = freevo.STATUS_RUNNING
     # update GUI
     yield kaa.NotFinished
     yield True
Exemple #36
0
 def play(self, item, resources):
     """
     play an item
     """
     if not self.status in (freevo.STATUS_IDLE, freevo.STATUS_STOPPED):
         # Already running, stop the current player by sending a STOP
         # event. The event will also get to the playlist behind the
         # current item and the whole list will be stopped.
         freevo.Event(freevo.STOP, handler=self.eventhandler).post()
         # Now connect to our own 'stop' signal once to repeat this current
         # function call without the player playing
         yield kaa.inprogress(self.signals['stop'])
         if not self.status in (freevo.STATUS_IDLE, freevo.STATUS_STOPPED):
             log.error('unable to stop current audio playback')
             yield False
     if not kaa.main.is_running():
         # Freevo is in shutdown mode, do not start a new player, the old
         # only stopped because of the shutdown.
         yield False
     if (yield self.get_resources(*resources, force=True)) == False:
         log.error("Can't get resource %s", str(resources))
         yield False
     # Store item and playlist. We need to keep the playlist object
     # here to make sure it is not deleted when player is running in
     # the background.
     self.item = item
     self.playlist = self.item.playlist
     if self.playlist:
         self.playlist.select(self.item)
     # Set the current item to the gui engine
     self.context.item = self.item.properties
     self.context.playlist = self.playlist
     self.item.elapsed_secs = 0
     self.status = freevo.STATUS_RUNNING
     # update GUI
     yield kaa.NotFinished
     yield True
Exemple #37
0
 def _start_backend(self):
     # spawn the backend process
     args = [
         'python',
         os.path.dirname(__file__) + '/backend/main.py', self.name,
         self.logfile
     ]
     self._candy_dirty = True
     self.server = subprocess.Popen(args,
                                    stdout=sys.stdout,
                                    stderr=sys.stderr)
     retry = 50
     if os.path.exists(kaa.tempfile(self.name)):
         os.unlink(kaa.tempfile(self.name))
     while True:
         try:
             self.ipc = kaa.rpc.connect(self.name)
             yield kaa.inprogress(self.ipc)
             break
         except Exception, e:
             retry -= 1
             if retry == 0:
                 raise e
             time.sleep(0.1)
Exemple #38
0
 def _add_device_to_db(self, metadata, dev):
     """
     Add the device to the database
     """
     yield kaa.inprogress(self._db.read_lock)
     # FIXME: check if the device is still valid
     # FIXME: handle failed dvd detection
     id = dev.get('beacon.id')
     if dev.get('volume.is_disc') == True and metadata and \
            metadata.get('mime') in ('video/vcd', 'video/dvd'):
         # pass rom drive
         type = metadata['mime'][6:]
         log.info('detect %s as %s' % (id, type))
         mid = self._db.add_object("media", name=id, content=type)['id']
         vid = self._db.add_object("video", name="", parent=('media', mid), title=unicode(get_title(metadata['label'])), media = mid)['id']
         for track in metadata.tracks:
             self._db.add_object('track_%s' % type, name='%02d' % track.trackno, parent=('video', vid), media=mid, chapters=track.chapters,
                 length=track.length, audio=[ x.convert() for x in track.audio ], subtitles=[ x.convert() for x in track.subtitles ])
         return
     if dev.get('volume.disc.has_audio') and metadata:
         # Audio CD
         log.info('detect %s as audio cd' % id)
         mid = self._db.add_object("media", name=id, content='cdda')['id']
         aid = self._db.add_object("audio", name='', title = metadata.get('title'), artist = metadata.get('artist'),
             parent=('media', mid), media = mid)['id']
         for track in metadata.tracks:
             self._db.add_object('track_cdda', name=str(track.trackno), title=track.get('title'), artist=track.get('artist'),
                 parent=('audio', aid), media=mid)
         return
     # filesystem
     log.info('detect %s as %s' % (id, dev.get('volume.fstype', '<unknown filesystem>')))
     mid = self._db.add_object("media", name=id, content='file')['id']
     mtime = 0                   # FIXME: wrong for /
     if dev.get('block.device'):
         mtime = os.stat(dev.get('block.device'))[stat.ST_MTIME]
     self._db.add_object("dir", name="", parent=('media', mid), media=mid, mtime=mtime)
Exemple #39
0
def foo():

    pid = os.fork()
    if not pid:

        s = Server()
        kaa.main.run()
        print 'server down'
        sys.exit(0)

    print 1
    for f in ('fast', 'subyield'):
        x = eval(f)()
        if isinstance(x, kaa.InProgress):
            # this should happen when calling subyield
            print f, 'needs more time'
            yield x  # waiting...
            # subyield is now done
            x = x.result
        else:
            # this should happen for fast
            print f, 'was a yield function but did not stop'
        print x
    print 6

    # just break here and return again in the next mainloop iteration
    yield kaa.NotFinished

    # call some async function with different types of
    # results (given as parameter)

    callback = kaa.InProgressCallable()
    async (callback, 7, 8)
    yield callback
    print callback.result  # (7, 8)

    callback = kaa.InProgressCallable()
    async (callback)
    yield callback
    print callback.result  # None

    callback = kaa.InProgressCallable()
    async (callback, 9)
    yield callback
    print callback.result  # 9

    callback = kaa.InProgressCallable()
    async (callback, foo=10)
    yield callback
    print callback.result  # 10

    callback = kaa.InProgressCallable()
    async (callback, foo=11, bar=12)
    yield callback
    print callback.result  # {'foo': 11, 'bar': 12}

    x = thread(13)
    # this is also an InProgress object
    yield x
    print x.result  # 13

    x = thread('crash')
    try:
        # the thread raised an exception, so x() will
        # raise it here
        yield x
        print x.result
        print 'crash test failed'
    except:
        print 'crash test ok'

    print 14

    print 'connect to server'
    c = kaa.rpc.connect('test')
    print 'server tests'

    yield kaa.inprogress(c)

    # normal rpc
    result = c.rpc('test1', 15)
    yield result
    print result.result

    # rpc in a thread
    result = c.rpc('test2', 16)
    yield result
    print result.result

    # rpc with yield direct
    result = c.rpc('test3', 17)
    yield result
    print result.result

    # rpc with yield indirect
    result = c.rpc('test4', 18)
    yield result
    print result.result

    # rpc with yield error
    result = c.rpc('crash')
    try:
        yield result
        result.result
        print 'bad rpc test failed'
    except:
        print 'bad rpc test ok'

    # rpc with remote exception
    result = c.rpc('test6', 18)
    try:
        yield result
        result.result
        print 'remote rpc exception test failed'
    except ValueError, e:
        print 'remote rpc exception test ok'
        print "========= A traceback (for rpc) is expected below:"
        print e
Exemple #40
0
 def acquire_read_lock(self):
     return kaa.inprogress(self.read_lock)
Exemple #41
0
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# -----------------------------------------------------------------------

import config
import kaa
from tv.record_client import RecordClient


def handler(result):
    if result:
        print _('Updated recording schedule')
    else:
        print _('Not updated recording schedule')
    raise SystemExit


rc = RecordClient()
try:
    kaa.inprogress(rc.channel).wait()
except Exception, why:
    print 'Cannot connect to record server'
    raise SystemExit

print _('Updating recording schedule')
if not rc.updateFavoritesSchedule(handler):
    print rc.recordserverdown
    raise SystemExit

kaa.main.run()
Exemple #42
0
def remote():
    g = kaa.epg.connect(('localhost', 10000))
    yield kaa.inprogress(g.signals['connected'])
Exemple #43
0
 def _device_add_to_database(self, metadata, devdict):
     """
     Add the device to the database
     """
     yield kaa.inprogress(self._db.read_lock)
     id = devdict.get('beacon.id')
     if devdict.get('volume.is_disc') == True and metadata and \
            metadata.get('mime') in ('video/vcd', 'video/dvd'):
         # pass rom drive
         type = metadata['mime'][6:]
         log.info('detect %s as %s' % (devdict.get('beacon.id'), type))
         mid = self._db.add_object("media",
                                   name=devdict.get('beacon.id'),
                                   content=type)['id']
         vid = self._db.add_object("video",
                                   name="",
                                   parent=('media', mid),
                                   title=unicode(
                                       get_title(metadata['label'])),
                                   media=mid)['id']
         for track in metadata.tracks:
             self._db.add_object(
                 'track_%s' % type,
                 name='%02d' % track.trackno,
                 parent=('video', vid),
                 media=mid,
                 chapters=track.chapters,
                 length=track.length,
                 audio=[x.convert() for x in track.audio],
                 subtitles=[x.convert() for x in track.subtitles])
         yield True
     if devdict.get('volume.disc.has_audio') and metadata:
         # Audio CD
         log.info('detect %s as audio cd' % devdict.get('beacon.id'))
         mid = self._db.add_object("media",
                                   name=devdict.get('beacon.id'),
                                   content='cdda')['id']
         aid = self._db.add_object("audio",
                                   name='',
                                   title=metadata.get('title'),
                                   artist=metadata.get('artist'),
                                   parent=('media', mid),
                                   media=mid)['id']
         for track in metadata.tracks:
             self._db.add_object('track_cdda',
                                 name=str(track.trackno),
                                 title=track.get('title'),
                                 artist=track.get('artist'),
                                 parent=('audio', aid),
                                 media=mid)
         yield True
     # filesystem
     log.info('detect %s as filesystem' % devdict.get('beacon.id'))
     mid = self._db.add_object("media",
                               name=devdict.get('beacon.id'),
                               content='file')['id']
     mtime = 0
     if devdict.get('block.device'):
         mtime = os.stat(devdict.get('block.device'))[stat.ST_MTIME]
     self._db.add_object("dir",
                         name="",
                         parent=('media', mid),
                         media=mid,
                         mtime=mtime)
     yield True
Exemple #44
0
    try:
        yield result
        result.result
        print 'remote rpc exception test failed'
    except ValueError, e:
        print 'remote rpc exception test ok'
        print "========= A traceback (for rpc) is expected below:"
        print e

    # call rpc in thread
    x = thread2(c, 19)
    yield x  # print 19
    print x.result  # 20

    # Test InProgressCallable destruction cleans up signal connection.
    ip = kaa.inprogress(sig['one'])
    assert (len(sig['one']) == 1)
    del ip
    gc.collect()
    assert (len(sig['one']) == 0)
    print 'InProgressCallable cleanup ok'

    # Test InProgressAny via Signals.any()
    kaa.OneShotTimer(sig['three'].emit, 'worked').start(0.5)
    print 'Testing InProgressAny, should return in 0.5s'
    n, args = yield sig.subset('one', 'three').any()
    print 'InProgressAny returned:', n, args
    # Force InProgressCallables implicitly created by any() to be deleted.
    gc.collect()
    # Verify that they _are_ deleted and detached from the signal.
    print sig['one']._callbacks
Exemple #45
0
def _parse(db, item, mtime):
    """
    Parse the item, this can take a while.
    """
    produced_load = 0
    try:
        #
        # Parent checking
        #
    
        parent = item._beacon_parent
        if not parent._beacon_id:
            # There is a parent without id, update the parent now.
            r = parse(db, parent)
            if isinstance(r, kaa.InProgress):
                yield r
            if not parent._beacon_id:
                # This should never happen
                raise AttributeError('parent for %s has no dbid' % item)
            # we had no parent id which we have now. Restart the whole
            # parsing process. maye this item was in the db already
            r = parse(db, parent)
            if isinstance(r, kaa.InProgress):
                r = yield r
            yield r
    
    
        #
        # Metadata parsing
        #
    
        t1 = time.time()
    
        # FIXME: add force parameter from config file:
        # - always force (slow but best result)
        # - never force (faster but maybe wrong)
        # - only force on media 1 (good default)
    
        # Parse metadata in an extra named thread
        metadata = yield parse_thread(item.filename)
        if not metadata:
            metadata = {}
    
        attributes = { 'mtime': mtime, 'image': metadata.get('image') }
    
        if metadata.get('media') == kaa.metadata.MEDIA_DISC and \
               metadata.get('subtype') in db.list_object_types():
            type = metadata['subtype']
            if metadata.get('type'):
                attributes['scheme'] = metadata.get('type').lower()
            item._beacon_isdir = False
        elif media_types.get(metadata.get('media')) in db.list_object_types():
            type = media_types.get(metadata['media'])
        elif item._beacon_isdir:
            type = 'dir'
        else:
            type = 'file'
    
        if item._beacon_id and type != item._beacon_id[0]:
            # The item changed its type. Adjust the db
            yield kaa.inprogress(db.read_lock)
            data = db.update_object_type(item._beacon_id, type)
            if not data:
                log.error('item to change not in the db anymore')
            log.info('change item %s to %s' % (item._beacon_id, type))
            item._beacon_database_update(data)
    
    
        #
        # Thumbnail / Cover / Image stuff.
        #
    
        produced_load = 1
    
        if type == 'dir':
            attributes['image_from_items'] = False
            if not attributes.get('image'):
                for cover in ('cover.jpg', 'cover.png'):
                    if os.path.isfile(item.filename + cover):
                        attributes['image'] = item.filename + cover
                        break
    
            # TODO: do some more stuff here:
            # Audio directories may have a different cover if there is only
            # one jpg in a dir of mp3 files or a files with 'front' in the name.
            # They need to be added here as special kind of cover
    
        elif type == 'image':
            attributes['image'] = item.filename
            if metadata.get('thumbnail'):
                t = thumbnail.Thumbnail(item.filename, item._beacon_media)
                if t.needs_update:
                    # only store the normal version
                    try:
                        produced_load = 2
                        t.normal = kaa.imlib2.open_from_memory(metadata.get('thumbnail'))
                    except (ValueError, IOError):
                        log.exception('image thumbnail')
        else:
            base = os.path.splitext(item.filename)[0]
            if type == 'video' and not attributes.get('image') and thumbnail.SUPPORT_VIDEO:
                attributes['image'] = item.filename
            if metadata.get('thumbnail') and not attributes.get('image'):
                attributes['image'] = item.filename
                t = thumbnail.Thumbnail(item.filename, item._beacon_media)
                try:
                    produced_load = 2
                    t.image = kaa.imlib2.open_from_memory(metadata['thumbnail'])
                except (ValueError, IOError):
                    log.exception('raw thumbnail')
            for ext in ('.jpg', '.png'):
                if os.path.isfile(base + ext):
                    attributes['image'] = base + ext
                    break
                if os.path.isfile(item.filename + ext):
                    attributes['image'] = item.filename + ext
                    break

        #
        # Type specific attributes
        #
        if type == 'video':
            # Normally db.add_object() will take care of assigning type
            # attributes from metadata, but some attributes for videos
            # aren't at the top-level attribute object.  For video
            # dimensions, take the dimensions of the first video track
            # (of the longest title, if applicable).
            video = None
            if metadata.get('video'):
                video = metadata.video[0]
            elif metadata.get('tracks'):
                # Find the longest title with a video track.
                for title in sorted(metadata.tracks, key=lambda t: -t.length):
                    if title.get('video'):
                        video = title.video[0]
                        break
            if video:
                attributes['width'] = video.get('width')
                attributes['height'] = video.get('height')
            attributes['series'] = metadata.series
            attributes['season'] = metadata.season
            attributes['episode'] = metadata.episode
            
        attributes['metadata'] = metadata
    
        # now call extention plugins
        ext = os.path.splitext(item.filename)[1]
        for function in extention_plugins.get(ext, []) + extention_plugins.get(None, []):
            function(item, attributes, type)

        yield kaa.inprogress(db.read_lock)
    
        if attributes.get('image'):
            # create thumbnail
            t = thumbnail.Thumbnail(attributes.get('image'), item._beacon_media)
            if t.needs_update and (not type == 'video' or not hasattr(item, 'filename') or
                    utils.do_thumbnail(item.filename)):
                t.create(t.PRIORITY_LOW)



        #
        # Database code
        #
        # add kaa.metadata results, the db module will add everything known
        # to the db. After that add or update the database.
        #
    
        if item._beacon_id:
            # Update old db entry
            db.update_object(item._beacon_id, **attributes)
            item._beacon_data.update(attributes)
        else:
            # Create new entry
            obj = db.add_object(type, name=item._beacon_data['name'], parent=parent, overlay=item._beacon_overlay, **attributes)
            item._beacon_database_update(obj)
    
        #
        # Additional track handling
        #
    
        if hasattr(metadata, 'tracks'):
            # The item has tracks, e.g. a dvd image on hd.
            if not metadata.get('type'):
                log.error('%s metadata has no type', item)
                yield produced_load
    
            # delete all known tracks before adding new
            result = yield db.query(parent=item)
            for track in result:
                db.delete_object(track)
    
            if not 'track_%s' % metadata.get('type').lower() in \
                   db.list_object_types():
                key = metadata.get('type').lower()
                log.error('track_%s not in database keys', key)
                yield produced_load
            type = 'track_%s' % metadata.get('type').lower()
            for track in metadata.tracks:
                db.add_object(type, name=str(track.trackno), parent=item, metadata=track)
    
        # parsing done
        log.info('scan %s (%0.3f)' % (item, time.time() - t1))

    except GeneratorExit:
        # Don't catch this, otherwise if the coroutine is aborted you get
        # "_parse() ignored GeneratorExit"
        raise
    except Exception, e:
        log.exception('parser error: %s', item)
Exemple #46
0
    def _generate(self, job):
        """
        Generates the thumbnail by spawning MPlayer.

        Yields True if generation was successful, and False otherwise.
        """
        mpargs = [job.filename]
        pos = 0
        try:
            length = job.metadata.length
            if job.metadata.type == u'DVD':
                # Find longest title.
                longest = sorted(job.metadata.tracks, key = lambda t: t.length)[-1]
                # Small heuristic: favor lowest title that's at least 80% of the longest title.
                track = min([t for t in job.metadata.tracks if t.length > longest.length * 0.8])
                length = track.length
                mpargs[0] = 'dvd://%d' % track.trackno
                mpargs.extend(['-dvd-device', job.filename])
            elif job.metadata.video[0].length:
                length = job.metadata.video[0].length

            # Pick a random position between 30-70%.  By randomizing, we give
            # the user the option to delete the original thumbnail and regenerate
            # a (likely) new one, in case the previous one wasn't very representative.
            pos = length * random.randrange(30, 70) / 100.0
            if hasattr(job.metadata, 'type'):
                # FIXME: dischi, this logic needs a comment.
                if job.metadata.type in ('MPEG-TS', 'MPEG-PES'):
                    pos = length / 20.0
        except (AttributeError, IndexError, TypeError):
            # else arbitrary consider that file is 1Mbps and grab position at 10%
            try:
                pos = os.stat(job.filename)[stat.ST_SIZE]/1024/1024/10.0
            except (OSError, IOError):
                yield False

            if pos < 10:
                # FIXME: needs another comment; is this because keyframes tend to be
                # every 10 seconds?  But if length < 10, won't we risk seeking to EOF and
                # not getting any thumbnail at all?"
                pos = 10

        try:
            # Give MPlayer 10 seconds to generate the thumbnail before we give
            # up and kill it.  Some video files cause mplayer to runaway.
            yield self.mplayer.start([str(pos)] + mpargs).timeout(10, abort=True)
        except kaa.TimeoutException:
            log.error('Thumbnailer timed out while trying to process %s', job.filename)
            if self.mplayer.stopping:
                # MPlayer was aborted due to timeout and is now stopping.  We
                # want to wait until it's fully terminated before proceeding,
                # so we yield again on its 'finished' signal which will be
                # emitted once the abort is complete.
                yield kaa.inprogress(self.mplayer.signals['finished'])
        
        # MPlayer is done, look for the screenshots it created.
        captures = glob.glob('000000??.png')
        if not captures:
            # No images, Mplayer crashed on this file?
            log.error('no images found')
            yield False

        # find the largest image (making assumption it's the best)
        current_capture = sorted(captures, key=lambda x: os.stat(x)[stat.ST_SIZE])[-1]
        try:
            # scale thumbnail
            for size, width, height in (('large', 256, 256), ('normal', 128, 128)):
                image = kaa.imlib2.open_without_cache(current_capture)
                try:
                    # FIXME: Thumb::Mimetype ends up being wrong.
                    libthumb.png(job.filename, job.imagefile % size, (width, height), image._image)
                except (IOError, ValueError):
                    self.create_failed(job)
                    break
            # remove old stuff
            os.rename(current_capture, os.path.basename(job.filename) + '.png')
            # remove old files.
            [ os.remove(fname) for fname in captures if os.path.isfile(fname) ]
        except Exception, e:
            log.exception('Thumbnailing of MPlayer screenshots failed')
            yield False
Exemple #47
0
def add_directory_attributes(db, directory):
    """
    Add some extra attributes for a directory recursive. This function
    checkes album, artist, image and length. When there are changes,
    go up to the parent and check it, too.
    """
    data = { 'length': 0, 'artist': u'', 'album': u'', 'image': '', 'series': '', 'season': '' }
    check_attr = data.keys()[:]
    check_attr.remove('length')

    if directory._beacon_data['image_from_parser'] and \
       directory._beacon_data['image']:
        # The directory had an image defined and found by the parser.
        # Delete image from data, we don't want to override it.
        del data['image']

    items = { 'video': [], 'audio': [], 'image': [], 'dir': [], 'other': [] }
    for item in (yield db.query(parent=directory)):
        t = item._beacon_data.get('type')
        if t in items:
            items[t].append(item)
        else:
            items['other'].append(item)
    relevant = []
    if (not items['video'] and not items['other'] and not items['dir']) and \
       ((len(items['audio']) > 2, len(items['image']) <= 1) or \
        (len(items['audio']) > 8, len(items['image']) <= 3)):
        # Could be music files. Only music files plus maybe
        # folder/cover images
        relevant = items['audio']
    if (not items['audio'] and not items['other'] and not items['dir']) and \
       (len(items['video']) > 2, len(items['image']) <= 1):
        # Could be video files. Only video files plus maybe one
        # folder/cover image
        relevant = items['video']
    if not items['audio'] and not items['video'] and not items['other'] and \
       items['dir'] and len(items['image']) <= 1:
        # only directories with maybe one folder/cover image
        relevant = items['dir']
    for item in relevant:
        data['length'] += item._beacon_data.get('length', 0) or 0
        for attr in check_attr:
            value = item._beacon_data.get(attr, data[attr])
            if data[attr] == '':
                data[attr] = value
            if data[attr] != value:
                data[attr] = None
                check_attr.remove(attr)

    if data['image'] and not (data['artist'] or data['album']):
        # We have neither artist nor album. So this seems to be a video
        # or an image directory and we don't want to set the image from
        # maybe one item in that directory as our directory image.
        data['image'] = None
    data = dict([ x for x in data.items() if x[1] is not None ])
    for attr in data.keys():
        if data[attr] != directory._beacon_data[attr]:
            break
    else:
        # no changes.
        yield True

    yield kaa.inprogress(db.read_lock)

    # update directory in database
    db.update_object(directory._beacon_id, **data)
    directory._beacon_data.update(data)

    # check parent
    if directory._beacon_parent:
        yield add_directory_attributes(db, directory._beacon_parent)
Exemple #48
0
Fichier : db.py Projet : clones/kaa
 def acquire_read_lock(self):
     return kaa.inprogress(self.read_lock)
Exemple #49
0
def add_directory_attributes(db, directory):
    """
    Add some extra attributes for a directory recursive. This function
    checkes album, artist, image and length. When there are changes,
    go up to the parent and check it, too.
    """
    data = {
        'length': 0,
        'artist': u'',
        'album': u'',
        'image': '',
        'series': '',
        'season': ''
    }
    check_attr = data.keys()[:]
    check_attr.remove('length')

    if directory._beacon_data['image_from_parser'] and \
       directory._beacon_data['image']:
        # The directory had an image defined and found by the parser.
        # Delete image from data, we don't want to override it.
        del data['image']

    items = {'video': [], 'audio': [], 'image': [], 'dir': [], 'other': []}
    for item in (yield db.query(parent=directory)):
        t = item._beacon_data.get('type')
        if t in items:
            items[t].append(item)
        else:
            items['other'].append(item)
    relevant = []
    if (not items['video'] and not items['other'] and not items['dir']) and \
       ((len(items['audio']) > 2, len(items['image']) <= 1) or \
        (len(items['audio']) > 8, len(items['image']) <= 3)):
        # Could be music files. Only music files plus maybe
        # folder/cover images
        relevant = items['audio']
    if (not items['audio'] and not items['other'] and not items['dir']) and \
       (len(items['video']) > 2, len(items['image']) <= 1):
        # Could be video files. Only video files plus maybe one
        # folder/cover image
        relevant = items['video']
    if not items['audio'] and not items['video'] and not items['other'] and \
       items['dir'] and len(items['image']) <= 1:
        # only directories with maybe one folder/cover image
        relevant = items['dir']
    for item in relevant:
        data['length'] += item._beacon_data.get('length', 0) or 0
        for attr in check_attr:
            value = item._beacon_data.get(attr, data[attr])
            if data[attr] == '':
                data[attr] = value
            if data[attr] != value:
                data[attr] = None
                check_attr.remove(attr)

    if data['image'] and not (data['artist'] or data['album']):
        # We have neither artist nor album. So this seems to be a video
        # or an image directory and we don't want to set the image from
        # maybe one item in that directory as our directory image.
        data['image'] = None
    data = dict([x for x in data.items() if x[1] is not None])
    for attr in data.keys():
        if data[attr] != directory._beacon_data[attr]:
            break
    else:
        # no changes.
        yield True

    yield kaa.inprogress(db.read_lock)

    # update directory in database
    db.update_object(directory._beacon_id, **data)
    directory._beacon_data.update(data)

    # check parent
    if directory._beacon_parent:
        yield add_directory_attributes(db, directory._beacon_parent)
Exemple #50
0
    if opts.update:
        tv.epg.update(config.XMLTV_FILE)
    else:
        grab()

    import kaa
    from tv.record_client import RecordClient

    def handler(result):
        if result:
            print _('Updated recording schedule')
        else:
            print _('Not updated recording schedule')
        raise SystemExit


    rc = RecordClient()
    try:
        kaa.inprogress(rc.channel).wait()
    except Exception, why:
        print 'Cannot connect to record server'
        raise SystemExit

    print 'Scheduling favorites for recording:  '
    if not rc.updateFavoritesSchedule(handler):
        print rc.recordserverdown
        raise SystemExit

    kaa.main.run()
Exemple #51
0
def _parse(db, item, mtime):
    """
    Parse the item, this can take a while.
    """
    produced_load = 0
    try:
        #
        # Parent checking
        #

        parent = item._beacon_parent
        if not parent._beacon_id:
            # There is a parent without id, update the parent now.
            r = parse(db, parent)
            if isinstance(r, kaa.InProgress):
                yield r
            if not parent._beacon_id:
                # This should never happen
                raise AttributeError('parent for %s has no dbid' % item)
            # we had no parent id which we have now. Restart the whole
            # parsing process. maye this item was in the db already
            r = parse(db, parent)
            if isinstance(r, kaa.InProgress):
                r = yield r
            yield r

        #
        # Metadata parsing
        #

        t1 = time.time()

        # FIXME: add force parameter from config file:
        # - always force (slow but best result)
        # - never force (faster but maybe wrong)
        # - only force on media 1 (good default)

        # Parse metadata in an extra named thread
        metadata = yield parse_thread(item.filename)
        if not metadata:
            metadata = {}

        attributes = {'mtime': mtime, 'image': metadata.get('image')}

        if metadata.get('media') == kaa.metadata.MEDIA_DISC and \
               metadata.get('subtype') in db.list_object_types():
            type = metadata['subtype']
            if metadata.get('type'):
                attributes['scheme'] = metadata.get('type').lower()
            item._beacon_isdir = False
        elif media_types.get(metadata.get('media')) in db.list_object_types():
            type = media_types.get(metadata['media'])
        elif item._beacon_isdir:
            type = 'dir'
        else:
            type = 'file'

        if item._beacon_id and type != item._beacon_id[0]:
            # The item changed its type. Adjust the db
            yield kaa.inprogress(db.read_lock)
            data = db.update_object_type(item._beacon_id, type)
            if not data:
                log.info('item to change not in the db anymore')
            log.info('change item %s to %s' % (item._beacon_id, type))
            item._beacon_database_update(data)

        #
        # Thumbnail / Cover / Image stuff.
        #

        produced_load = 1

        if type == 'dir':
            # If the image was detected by the parser, do not override
            # it in add_directory_attributes
            attributes['image_from_parser'] = bool(attributes.get('image'))

        elif type == 'image':
            attributes['image'] = item.filename
            if metadata.get('thumbnail'):
                t = thumbnail.Thumbnail(item.filename, item._beacon_media)
                if t.needs_update:
                    # only store the normal version
                    try:
                        produced_load = 2
                        t.normal = kaa.imlib2.open_from_memory(
                            metadata.get('thumbnail'))
                    except (ValueError, IOError):
                        log.exception('image thumbnail')
        else:
            base = os.path.splitext(item.filename)[0]
            if type == 'video' and not attributes.get(
                    'image') and thumbnail.SUPPORT_VIDEO:
                attributes['image'] = item.filename
            if metadata.get('thumbnail') and not attributes.get('image'):
                attributes['image'] = item.filename
                t = thumbnail.Thumbnail(item.filename, item._beacon_media)
                try:
                    produced_load = 2
                    t.image = kaa.imlib2.open_from_memory(
                        metadata['thumbnail'])
                except (ValueError, IOError):
                    log.exception('raw thumbnail')
            for ext in ('.jpg', '.png'):
                if os.path.isfile(base + ext):
                    if type == 'video':
                        attributes['poster'] = base + ext
                    else:
                        attributes['image'] = base + ext
                    break
                if os.path.isfile(item.filename + ext):
                    if type == 'video':
                        attributes['poster'] = item.filename + ext
                    else:
                        attributes['image'] = item.filename + ext
                    break

        #
        # Type specific attributes
        #
        if type == 'video':
            # Normally db.add_object() will take care of assigning type
            # attributes from metadata, but some attributes for videos
            # aren't at the top-level attribute object.  For video
            # dimensions, take the dimensions of the first video track
            # (of the longest title, if applicable).
            video = None
            if metadata.get('video'):
                video = metadata.video[0]
            elif metadata.get('tracks'):
                # Find the longest title with a video track.
                for title in sorted(metadata.tracks, key=lambda t: -t.length):
                    if title.get('video'):
                        video = title.video[0]
                        break
            if video:
                attributes['width'] = video.get('width')
                attributes['height'] = video.get('height')
            attributes['series'] = metadata.series
            attributes['season'] = metadata.season
            attributes['episode'] = metadata.episode

        attributes['metadata'] = metadata

        # now call extention plugins
        ext = os.path.splitext(item.filename)[1]
        for function in extention_plugins.get(ext, []) + extention_plugins.get(
                None, []):
            function(item, attributes, type)

        yield kaa.inprogress(db.read_lock)

        if attributes.get('image'):
            # create thumbnail
            t = thumbnail.Thumbnail(attributes.get('image'),
                                    item._beacon_media)
            if t.needs_update and (not type == 'video'
                                   or not hasattr(item, 'filename')
                                   or utils.do_thumbnail(item.filename)):
                t.create(t.PRIORITY_LOW)

        #
        # Database code
        #
        # add kaa.metadata results, the db module will add everything known
        # to the db. After that add or update the database.
        #

        if item._beacon_id:
            # Update old db entry
            db.update_object(item._beacon_id, **attributes)
            item._beacon_data.update(attributes)
        else:
            # check if for some reasons the same item was parsed
            # parallel. If so, do not add it again and reuse the id
            entry = db._db.query(parent=parent._beacon_id,
                                 name=item._beacon_data['name'])
            if entry:
                # Update old db entry
                log.error('item already in db, re-use beacon_id')
                db.update_object((entry[0]['type'], entry[0]['id']),
                                 **attributes)
                obj = db._db.query(parent=parent._beacon_id,
                                   name=item._beacon_data['name'])[0]
            else:
                # Create new entry
                obj = db.add_object(type,
                                    name=item._beacon_data['name'],
                                    parent=parent,
                                    **attributes)
            item._beacon_database_update(obj)

        #
        # Additional track handling
        #

        if hasattr(metadata, 'tracks'):
            # The item has tracks, e.g. a dvd image on hd.
            if not metadata.get('type'):
                log.error('%s metadata has no type', item)
                yield produced_load

            # delete all known tracks before adding new
            result = yield db.query(parent=item)
            for track in result:
                db.delete_object(track)

            if not 'track_%s' % metadata.get('type').lower() in \
                   db.list_object_types():
                key = metadata.get('type').lower()
                log.error('track_%s not in database keys', key)
                yield produced_load
            type = 'track_%s' % metadata.get('type').lower()
            for track in metadata.tracks:
                db.add_object(type,
                              name=str(track.trackno),
                              parent=item,
                              metadata=track)

        # parsing done
        log.info('scan %s (%0.3f)' % (item, time.time() - t1))

    except GeneratorExit:
        # Don't catch this, otherwise if the coroutine is aborted you get
        # "_parse() ignored GeneratorExit"
        raise
    except Exception, e:
        log.exception('parser error: %s', item)
Exemple #52
0
class LCD(object):
    """
    LCD interface
    """
    def __init__(self, server='127.0.0.1', port=13666):
        self.signals = {
            'connected': kaa.Signal()
        }
        self._server = server
        self._port = port
        self._connected = False
        self._connect()
        self._screenno = 0


    def create_screen(self, name = None, priority='foreground', duration=0):
        """
        Create a new screen with the given name.
        """
        if not name:
            name = 'lcd%d' % self._screenno
            self._screenno += 1
        return Screen(self, name, priority, duration)


    def _send(self, line):
        """
        Send a command to the server.
        """
        if not self._connected:
            return
        self.socket.write(line + '\n')

    def _disconnect(self, expected):
        self._connected = False
        self._connect()

    @kaa.coroutine()
    def _connect(self):
        """
        Connect to the server and init the connection.
        """
        if self._connected:
            yield False
        self.socket = kaa.Socket()
        try:
            yield self.socket.connect((self._server, self._port))
        except Exception, e:
            # try again later
            log.error('LCDproc connection error; will try again later')
            kaa.OneShotTimer(self._connect).start(10)
            yield False
        self.socket.signals['closed'].connect_once(self._disconnect)
        self._connected = True
        self._send('hello')
        wait = kaa.inprogress(self.socket.signals['read'])
        line = (yield wait).strip().split()
        self._send('client_set name kaa')
        self.size = int(line[7]), int(line[9])
        self.width, self.height = self.size
        log.info('LCDproc connected')
        self.signals['connected'].emit(self.width, self.height)
        yield False
Exemple #53
0


if __name__ == '__main__':
    if len(sys.argv) >= 2:
        function = sys.argv[1]
    else:
        function = 'none'

    from time import sleep

    idnr = None
    startclock = time.clock()
    es = EncodingClientActions()
    print time.clock() - startclock
    kaa.inprogress(es.channel).wait()
    print time.clock() - startclock
    if function == 'test2':
        result = es.ping()
        print 'ping:', result
        if not result:
            raise EncodingClientActions.encodingserverdown
        result = es.getContainerCAP()
        print 'getContainerCAP:', result
        container = result[1][1]
        result = es.getVideoCodecCAP()
        print 'getVideoCodecCAP:', result
        video_codec = result[1][3]
        result = es.getAudioCodecCAP()
        print 'getAudioCodecCAP:', result
        audio_codec = result[1][3]