Ejemplo n.º 1
0
 def start(self):
     assert not self._process
     env = os.environ.copy()
     env['PYTHONPATH'] = os.pathsep.join(
         filter(None, [
             os.path.join(__file__, *[os.pardir] * 3),
             env.get('PYTHONPATH')
         ]))
     self._process = subprocess.Popen(
         [sys.executable, '-u', '-m', 'video_downloader.downloader'],
         stdin=subprocess.PIPE,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         env=env,
         universal_newlines=True,
         start_new_session=True)
     fcntl.fcntl(self._process.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
     fcntl.fcntl(self._process.stderr, fcntl.F_SETFL, os.O_NONBLOCK)
     self._process.stdout_remainder = self._process.stderr_remainder = ''
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stdout.fileno(),
                           GLib.IOCondition.IN, self._on_process_stdout)
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stderr.fileno(),
                           GLib.IOCondition.IN, self._on_process_stderr,
                           self._process)
Ejemplo n.º 2
0
 def start(self):
     assert not self._process
     env = os.environ.copy()
     env['PYTHONPATH'] = os.pathsep.join(
         filter(None, [
             os.path.join(__file__, *[os.pardir] * 3),
             env.get('PYTHONPATH')
         ]))
     # Start child process in its own process group to shield it from
     # signals by terminals (e.g. SIGINT) and to identify remaning children.
     # youtube-dl doesn't kill ffmpeg and other subprocesses on error.
     self._process = subprocess.Popen(
         [sys.executable, '-u', '-m', 'video_downloader.downloader'],
         stdin=subprocess.PIPE,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         env=env,
         universal_newlines=True,
         preexec_fn=os.setpgrp)
     fcntl.fcntl(self._process.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
     fcntl.fcntl(self._process.stderr, fcntl.F_SETFL, os.O_NONBLOCK)
     self._process.stdout_remainder = self._process.stderr_remainder = ''
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stdout.fileno(),
                           GLib.IOCondition.IN, self._on_process_stdout)
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stderr.fileno(),
                           GLib.IOCondition.IN, self._on_process_stderr,
                           self._process)
Ejemplo n.º 3
0
def _fd_output_future(fd, log_fn):
    """Return a future for all output on fd.

    :param fd: A Python file object to collect output from and close.  The
    caller should not touch it in any way after calling this function.
    """
    output_chunks = [] # A list of strings to avoid an O(N^2) behavior

    # A string holding output data for logging
    # Needs to be stored as a one-item array because strings
    # are immutable and it would otherwise be overwritten by
    # input_handler below
    linebuf = ['']
    future = Future()

    def input_handler(unused_fd, condition, unused_data):
        finished = True
        if (condition & (GLib.IOCondition.ERR | GLib.IOCondition.NVAL)) != 0:
            log.error("Unexpected input handler state %s" % condition)
        else:
            assert (condition & (GLib.IOCondition.IN | GLib.IOCondition.HUP)) != 0
            # Note that HUP and IN can happen at the same time, so don’t
            # explicitly test for HUP.
            try:
                chunk = fd.read()
            except IOError as e:
                log.error("Error reading subprocess output: %s" % e)
            else:
                if len(chunk) > 0:
                    output_chunks.append(chunk.decode('utf-8'))

                    # Log the input at the requested level
                    lines = (linebuf[0] + chunk.decode('utf-8')).split('\n')
                    for line in lines[:-1]:
                        try:
                            msg = line.encode(errors='backslashreplace')
                        except UnicodeError:
                            # Line contains non-ASCII content that
                            # cannot be escaped. Log it as base64.
                            msg = line.encode(encoding='base64')
                        log_fn(msg)
                    linebuf[0] = lines[-1];

                    # Continue until there's no more data to be had
                    finished = False

        if finished:
            fd.close()
            future.set_result("".join(output_chunks))
            return False
        return True

    fcntl.fcntl(fd, fcntl.F_SETFL,
                fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
    condition = (GLib.IOCondition.IN | GLib.IOCondition.ERR |
                 GLib.IOCondition.HUP | GLib.IOCondition.NVAL)
    GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT, fd.fileno(), condition,
                          input_handler, None)

    return future
Ejemplo n.º 4
0
def _fd_output_future(fd, log_fn):
    """Return a future for all output on fd.

    :param fd: A Python file object to collect output from and close.  The
    caller should not touch it in any way after calling this function.
    """
    output_chunks = [] # A list of strings to avoid an O(N^2) behavior

    # A string holding output data for logging
    # Needs to be stored as a one-item array because strings
    # are immutable and it would otherwise be overwritten by
    # input_handler below
    linebuf = ['']
    future = Future()

    def input_handler(unused_fd, condition, unused_data):
        finished = True
        if (condition & (GLib.IOCondition.ERR | GLib.IOCondition.NVAL)) != 0:
            log.error("Unexpected input handler state %s" % condition)
        else:
            assert (condition & (GLib.IOCondition.IN | GLib.IOCondition.HUP)) != 0
            # Note that HUP and IN can happen at the same time, so don’t
            # explicitly test for HUP.
            try:
                chunk = fd.read()
            except IOError as e:
                log.error("Error reading subprocess output: %s" % e)
            else:
                if len(chunk) > 0:
                    output_chunks.append(chunk.decode('utf-8'))

                    # Log the input at the requested level
                    lines = (linebuf[0] + chunk.decode('utf-8')).split('\n')
                    for line in lines[:-1]:
                        try:
                            msg = line.encode(errors='backslashreplace')
                        except UnicodeError:
                            # Line contains non-ASCII content that
                            # cannot be escaped. Log it as base64.
                            msg = line.encode(encoding='base64')
                        log_fn(msg)
                    linebuf[0] = lines[-1];

                    # Continue until there's no more data to be had
                    finished = False

        if finished:
            fd.close()
            future.set_result("".join(output_chunks))
            return False
        return True

    fcntl.fcntl(fd, fcntl.F_SETFL,
                fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
    condition = (GLib.IOCondition.IN | GLib.IOCondition.ERR |
                 GLib.IOCondition.HUP | GLib.IOCondition.NVAL)
    GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT, fd.fileno(), condition,
                          input_handler, None)

    return future
Ejemplo n.º 5
0
    def add_writer(self, fd, callback, *args):
        def doit(_1, _2, _3, _4):  # not sure what the args are
            callback(*args)
            return \
                True # keep watching

        #end doit

    #begin add_writer
        fileno = _fd_fileno(fd)
        self._add_source \
          (
            attr = "_writer_sources",
            key = fileno,
            source_nr = GLib.unix_fd_add_full
              (
                0,
                fileno,
                GLib.IOCondition.OUT | GLib.IOCondition.PRI,
                doit,
                None,
                None
              )
          )
        self = None  # avoid circular references
Ejemplo n.º 6
0
def Inhibit(_, what, who, why, mode):
    if not hasattr(mockobject, "inhibitors"):
        mockobject.inhibitors = []

    fd_r, fd_w = os.pipe()

    inhibitor = (what, who, why, mode, 1000, 123456)
    mockobject.inhibitors.append(inhibitor)

    def inhibitor_dropped(fd, cond):
        # pylint: disable=unused-argument
        os.close(fd)
        mockobject.inhibitors.remove(inhibitor)
        return False

    GLib.unix_fd_add_full(GLib.PRIORITY_HIGH, fd_r, GLib.IO_HUP,
                          inhibitor_dropped)
    GLib.idle_add(os.close, fd_w)

    return fd_w
Ejemplo n.º 7
0
 def __init__(self, mainloop, fd, read, write, desc):
     self._mainloop = mainloop
     self.description = desc
     condition = GLib.IOCondition(0)
     if read:
         condition |= GLib.IOCondition.IN | GLib.IOCondition.HUP
     if write:
         condition |= GLib.IOCondition.OUT
     self._doread = read
     self._dowrite = write
     self._handle = GLib.unix_fd_add_full(0, fd, condition, self._call,
                                          None, None)
Ejemplo n.º 8
0
 def __init__(self, mainloop, fd, read, write, desc):
     self._mainloop = mainloop
     self.description = desc
     condition = GLib.IOCondition(0)
     if read:
         condition |= GLib.IOCondition.IN | GLib.IOCondition.HUP
     if write:
         condition |= GLib.IOCondition.OUT
     self._doread = read
     self._dowrite = write
     self._handle = GLib.unix_fd_add_full(
         0, fd, condition, self._call, None, None)
Ejemplo n.º 9
0
 def start(self):
     assert not self._process
     env = os.environ.copy()
     env['PYTHONPATH'] = os.pathsep.join(
         filter(None, [
             os.path.join(__file__, *[os.pardir] * 3),
             env.get('PYTHONPATH')
         ]))
     # Start child process in its own process group to shield it from
     # signals by terminals (e.g. SIGINT) and to identify remaning children.
     # youtube-dl doesn't kill ffmpeg and other subprocesses on error.
     self._process = subprocess.Popen(
         [sys.executable, '-u', '-m', 'video_downloader.downloader'],
         stdin=subprocess.PIPE,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         env=env,
         universal_newlines=True,
         preexec_fn=os.setpgrp)
     # WARNING: O_NONBLOCK can break mult ibyte decoding and line splitting
     # under rare circumstances.
     # E.g. when the buffer only includes the first byte of a multi byte
     # UTF-8 character, TextIOWrapper would normally block until all bytes
     # of the character are read. This does not work with O_NONBLOCK, and it
     # raises UnicodeDecodeError instead.
     # E.g. when the buffer only includes `b'\r'`, TextIOWrapper would
     # normally block to read the next byte and check if it's `b'\n'`.
     # This does not work with O_NONBLOCK, and it gets transformed to `'\n'`
     # directly. The line ending `b'\r\n'` will be transformed to `'\n\n'`.
     fcntl.fcntl(self._process.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
     fcntl.fcntl(self._process.stderr, fcntl.F_SETFL, os.O_NONBLOCK)
     self._process.stdout_remainder = self._process.stderr_remainder = b''
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stdout.fileno(),
                           GLib.IOCondition.IN, self._on_process_stdout,
                           self._process)
     GLib.unix_fd_add_full(GLib.PRIORITY_DEFAULT_IDLE,
                           self._process.stderr.fileno(),
                           GLib.IOCondition.IN, self._on_process_stderr,
                           self._process)
Ejemplo n.º 10
0
    def __init__(self, app, patch):

        self.app = app
        self.patch = patch

        # 0 : patched channels
        # 1 : all channels
        self.view_type = 0

        self.percent_level = Gio.Application.get_default().settings.get_boolean('percent')

        Gtk.Window.__init__(self, title="Open Lighting Console", application=app)
        self.set_default_size(1400, 1200)
        self.set_name('olc')

        self.header = Gtk.HeaderBar(title="Open Lighting Console")
        self.header.set_subtitle("Fonctionne avec ola")
        self.header.props.show_close_button = True

        box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        #Gtk.StyleContext.add_class(box.get_style_context(), "linked")
        button = Gtk.Button()
        icon = Gio.ThemedIcon(name="view-grid-symbolic")
        image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
        button.connect("clicked", self.button_clicked_cb)
        button.add(image)
        box.add(button)
        button = Gtk.Button()
        icon = Gio.ThemedIcon(name="open-menu-symbolic")
        image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
        button.add(image)
        box.add(button)
        self.header.pack_end(box)

        self.set_titlebar(self.header)

        self.paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
        self.paned.set_position(950)
        #self.paned.set_wide_handle(True)

        self.scrolled = Gtk.ScrolledWindow()
        self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        self.flowbox = Gtk.FlowBox()
        self.flowbox.set_valign(Gtk.Align.START)
        self.flowbox.set_max_children_per_line(20)
        self.flowbox.set_homogeneous(True)
        self.flowbox.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
        self.flowbox.set_filter_func(self.filter_func, None) # Fonction de filtrage

        self.keystring = ""
        self.last_chan_selected = ""

        self.channels = []

        for i in range(512):
            self.channels.append(ChannelWidget(i+1, 0, 0))
            self.flowbox.add(self.channels[i])

        self.scrolled.add(self.flowbox)
        self.paned.add1(self.scrolled)

        # Gtk.Statusbar to display keyboard's keys
        self.statusbar = Gtk.Statusbar()
        self.context_id = self.statusbar.get_context_id("keypress")

        self.grid = Gtk.Grid()
        label = Gtk.Label("Saisie clavier : ")
        self.grid.add(label)
        self.grid.attach_next_to(self.statusbar, label, Gtk.PositionType.RIGHT, 1, 1)
        self.paned.add2(self.grid)

        self.paned2 = Gtk.Paned(orientation=Gtk.Orientation.HORIZONTAL)
        self.paned2.set_position(950)
        self.paned2.add1(self.paned)

        self.app = Gio.Application.get_default()
        self.seq = self.app.sequence
        
        # Sequential part of the window
        position = self.seq.position
        t_total = self.seq.cues[position].total_time
        t_in = self.seq.cues[position].time_in
        t_out = self.seq.cues[position].time_out
        t_wait = self.seq.cues[position].wait
        channel_time = self.seq.cues[position].channel_time

        # Crossfade widget
        self.sequential = SequentialWidget(t_total, t_in, t_out, t_wait, channel_time)

        # Model : Step, Memory, Text, Wait, Time Out, Time In, Channel Time
        self.cues_liststore1 = Gtk.ListStore(str, str, str, str, str, str, str, str)
        self.cues_liststore2 = Gtk.ListStore(str, str, str, str, str, str, str)

        for i in range(self.app.sequence.last):
            if self.seq.cues[i].wait.is_integer():
                wait = str(int(self.seq.cues[i].wait))
                if wait == "0":
                    wait = ""
            else:
                wait = str(self.seq.cues[i].wait)
            if self.seq.cues[i].time_out.is_integer():
                t_out = str(int(self.seq.cues[i].time_out))
            else:
                t_out = str(self.seq.cues[i].time_out)
            if self.seq.cues[i].time_in.is_integer():
                t_in = str(int(self.seq.cues[i].time_in))
            else:
                t_in = str(self.seq.cues[i].time_in)
            channel_time = str(len(self.seq.cues[i].channel_time))
            if channel_time == "0":
                channel_time = ""
            bg = "#232729"
            self.cues_liststore1.append([str(i), str(self.seq.cues[i].memory), self.seq.cues[i].text,
                wait, t_out, t_in, channel_time, bg])
            self.cues_liststore2.append([str(i), str(self.seq.cues[i].memory), self.seq.cues[i].text,
                wait, t_out, t_in, channel_time])

        # Filter for the first part of the cue list
        self.step_filter1 = self.cues_liststore1.filter_new()
        self.step_filter1.set_visible_func(self.step_filter_func1)
        # List
        self.treeview1 = Gtk.TreeView(model=self.step_filter1)
        self.treeview1.set_enable_search(False)
        sel = self.treeview1.get_selection()
        sel.set_mode(Gtk.SelectionMode.NONE)
        for i, column_title in enumerate(["Pas", "Mémoire", "Texte", "Wait", "Out", "In", "Channel Time"]):
            renderer = Gtk.CellRendererText()
            # Change background color one column out of two
            if i % 2 == 0:
                renderer.set_property("background-rgba", Gdk.RGBA(alpha=0.03))
            column = Gtk.TreeViewColumn(column_title, renderer, text=i, background=7)
            if i == 2:
                column.set_min_width(600)
                column.set_resizable(True)
            self.treeview1.append_column(column)

        # Filter
        self.step_filter2 = self.cues_liststore2.filter_new()
        self.step_filter2.set_visible_func(self.step_filter_func2)
        # List
        self.treeview2 = Gtk.TreeView(model=self.step_filter2)
        self.treeview2.set_enable_search(False)
        sel = self.treeview2.get_selection()
        sel.set_mode(Gtk.SelectionMode.NONE)
        for i, column_title in enumerate(["Pas", "Mémoire", "Texte", "Wait", "Out", "In", "Channel Time"]):
            renderer = Gtk.CellRendererText()
            # Change background color one column out of two
            if i % 2 == 0:
                renderer.set_property("background-rgba", Gdk.RGBA(alpha=0.03))
            column = Gtk.TreeViewColumn(column_title, renderer, text=i)
            if i == 2:
                column.set_min_width(600)
                column.set_resizable(True)
            self.treeview2.append_column(column)
        # Put Cues List in a scrolled window
        self.scrollable2 = Gtk.ScrolledWindow()
        self.scrollable2.set_vexpand(True)
        self.scrollable2.set_hexpand(True)
        self.scrollable2.add(self.treeview2)
        # Put Cues lists and sequential in a grid
        self.seq_grid = Gtk.Grid()
        self.seq_grid.set_row_homogeneous(False)
        self.seq_grid.attach(self.treeview1, 0, 0, 1, 1)
        self.seq_grid.attach_next_to(self.sequential, self.treeview1, Gtk.PositionType.BOTTOM, 1, 1)
        self.seq_grid.attach_next_to(self.scrollable2, self.sequential, Gtk.PositionType.BOTTOM, 1, 1)

        # Sequential in a Tab
        self.notebook = Gtk.Notebook()

        self.notebook.append_page(self.seq_grid, Gtk.Label('Main Playback'))

        self.paned2.add2(self.notebook)

        self.add(self.paned2)

        # Select first Cue
        self.cues_liststore1[0][7] = "#997004"

        # Open MIDI input port
        #self.inport = mido.open_input('UC-33 USB MIDI Controller:UC-33 USB MIDI Controller MIDI  24:1')
        try:
            self.inport = mido.open_input('UC-33 USB MIDI Controller:UC-33 USB MIDI Controller MIDI  24:0')
        except:
            self.inport = mido.open_input()

        # Scan MIDI every 100ms
        self.timeout_id = GObject.timeout_add(100, self.on_timeout, None)
        # Scan Ola messages - 27 = IN(1) + HUP(16) + PRI(2) + ERR(8)
        GLib.unix_fd_add_full(0, self.app.sock.fileno(), GLib.IOCondition(27), self.app.on_fd_read, None)

        # TODO: Add Enttec wing playback support with Gio.SocketService (et Gio.SocketListener.add_address)
        """
        service = Gio.SocketService()
        service.connect('incoming', self.incoming_connection_cb)
        #service.add_address(Gio.InetSocketAddress(Gio.SocketFamily(2), 3330), Gio.SocketType(2), Gio.SocketProtocal(17), None)
        address = Gio.InetAddress.new_any(2)
        #address = Gio.InetAddress.new_from_string('127.0.0.1')
        #inetsock = Gio.InetSocketAddress.new(address, 3330)
        inetsock = Gio.InetSocketAddress.new_from_string('127.0.0.1', 3330)
        service.add_address(inetsock, Gio.SocketType.DATAGRAM, Gio.SocketProtocol.UDP)
        """
        """
        socket = Gio.Socket.new(Gio.SocketFamily.IPV4, Gio.SocketType.DATAGRAM, Gio.SocketProtocol.UDP)
        address = Gio.InetAddress.new_any(Gio.SocketFamily.IPV4)
        inetsock = Gio.InetSocketAddress.new(address, 3330)
        ret = socket.connect(inetsock)
        print(ret)
        fd = socket.get_fd()
        print(fd)
        ch = GLib.IOChannel.unix_new(fd)
        print(ch)
        GLib.io_add_watch(ch, 0, GLib.IOCondition.IN, self.incoming_connection_cb)
        """
        import socket
        address = ('', 3330)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind(address)
        self.fd = self.sock.fileno()
        #ch = GLib.IOChannel.unix_new(fd)
        #GLib.io_add_watch(ch, 0, GLib.IOCondition.IN, self.incoming_connection_cb)
        GLib.unix_fd_add_full(0, self.fd, GLib.IOCondition.IN, self.incoming_connection_cb, None)

        self.connect('key_press_event', self.on_key_press_event)

        self.set_icon_name('olc')