This file is indexed.

/usr/share/pyshared/quodlibet/plugins/events.py is in exfalso 2.4-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# -*- coding: utf-8 -*-
# Copyright 2005 Michael Urman, Joe Wreschnig
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation

import gobject

from quodlibet import util
from quodlibet.plugins import Manager, SongWrapper, ListWrapper

class EventPlugin(object):
    """Plugins that run in the background and receive events.

    Event plugins, unlike other plugins, are instantiated on startup and
    the same instance is used even when the plugin is enabled or disabled.

    Callables:
        obj.plugin_on_song_started(song)
        obj.plugin_on_song_ended(song, stopped)
        obj.plugin_on_added([song1, song2, ...])
        obj.plugin_on_changed([song1, song2, ...])
        obj.plugin_on_removed([song1, song2, ...])
        obj.plugin_on_paused()
        obj.plugin_on_unpaused()
        obj.plugin_on_seek(song, msec)
    """

    def enabled(self):
        """Called when the plugin is enabled."""
        pass

    def disabled(self):
        """Called when the plugin is disabled."""
        pass

    def destroy(self):
        """Called when the plugin should release any private resources,
        usually because it's being upgraded or on program exit"""
        pass

class EventPlugins(Manager):
    library_events = []
    player_events = []

    def __init__(self, librarian=None, player=None, folders=[], name=None):
        super(EventPlugins, self).__init__(folders, name)

        if librarian:
            self.library_events = [
                (s.replace('-', '_'), 'plugin_on_' + s.replace('-', '_'))
                for s in gobject.signal_list_names(librarian)]
        if player:
            self.player_events = [
                (s.replace('-', '_'), 'plugin_on_' + s.replace('-', '_'))
                for s in gobject.signal_list_names(player)]
            self.player_events.remove(('error', 'plugin_on_error'))
        self.all_events = self.library_events + self.player_events

        self.librarian = librarian

        if librarian:
            for event, handle in self.library_events:
                def handler(librarian, *args):
                    self.__invoke(librarian, args[-1], *args[:-1])
                librarian.connect(event, handler, event)
        if player:
            for event, handle in self.player_events:
                def handler(player, *args):
                    self.__invoke(player, args[-1], *args[:-1])
                player.connect_object(event, handler, librarian, event)

    def _load(self, name, module):
        try: objs = [getattr(module, attr) for attr in module.__all__]
        except AttributeError:
            objs = [getattr(module, attr) for attr in vars(module)
                    if not attr.startswith("_")]
        def is_plugin(obj):
            if not isinstance(obj, type): return False
            elif not issubclass(obj, EventPlugin): return False
            elif obj is EventPlugin: return False
            else: return True

        kinds = filter(is_plugin, objs)

        for Kind in kinds:
            try: Kind.PLUGIN_ID
            except AttributeError:
                try: Kind.PLUGIN_ID = Kind.PLUGIN_NAME
                except AttributeError:
                    Kind.PLUGIN_ID = Kind.__name__

            try: Kind.PLUGIN_NAME
            except AttributeError:
                Kind.PLUGIN_NAME = Kind.PLUGIN_ID

            try: obj = Kind()
            except:
                util.print_exc()
            else:
                if obj.PLUGIN_ID in self._plugins:
                    old_obj = self._plugins[obj.PLUGIN_ID]
                    self.enable(old_obj, False)
                    old_obj.destroy()
                self._plugins[obj.PLUGIN_ID] = obj

    def list(self):
        return self._plugins.values()

    def enable(self, plugin, enabled):
        if self.enabled(plugin) != enabled:
            super(EventPlugins, self).enable(plugin, enabled)
            try:
                if enabled: plugin.enabled()
                else: plugin.disabled()
            except:
                util.print_exc()

    def destroy(self, *args):
        for obj in self._plugins.itervalues():
            self.enable(obj, False)
            obj.destroy()

    def __invoke(self, librarian, event, *args):
        try:
            args = list(args)
            if args and args[0]:
                if isinstance(args[0], dict):
                    args[0] = SongWrapper(args[0])
                elif isinstance(args[0], list):
                    args[0] = ListWrapper(args[0])
            for plugin in self._plugins.itervalues():
                if not self.enabled(plugin):
                    continue
                handler = getattr(plugin, 'plugin_on_' + event, None)
                if handler is not None:
                    try: handler(*args)
                    except Exception:
                        util.print_exc()
        finally:
            if event not in ["removed", "changed"] and args:
                from quodlibet.widgets import main
                songs = args[0]
                if not isinstance(songs, list):
                    songs = [songs]
                songs = filter(None, songs)
                self._check_change(librarian, main, songs)