示例#1
0
        metadata['xesam:title']) if metadata['xesam:title'] else ''

    if not artist and not song:
        print('')
    else:
        if len(song) > trunclen:
            song = song[0:trunclen]
            song += '...'
            if ('(' in song) and (')' not in song):
                song += ')'

        if font:
            artist = label_with_font.format(font=font, label=artist)
            song = label_with_font.format(font=font, label=song)

        with pulsectl.Pulse('event-printer') as pulse:
            for inp in pulse.sink_input_list():
                if inp.proplist['application.name'] == 'Spotify':
                    vol = inp.volume
                    vol.value_flat = 0.0 if not artist and (
                        song == 'Advertisement' or song == 'Spotify') else 1.0
                    pulse.volume_set(inp, vol)

        print(output.format(artist=artist, song=song, play_pause=play_pause))

except Exception as e:
    if isinstance(e, dbus.exceptions.DBusException):
        print('')
    else:
        print(e)
示例#2
0
def player4(tauon):

    pctl = tauon.pctl
    gui = tauon.gui
    prefs = tauon.prefs

    print("Start PHAzOR backend...")

    # Get output device names
    if len(prefs.phazor_devices) < 2:
        try:
            import pulsectl
            pulse = pulsectl.Pulse('Tauon Music Box')
            sink_list = pulse.sink_list()
            for sink in sink_list:
                prefs.phazor_devices[sink.description] = sink.name
            pulse.close()
        except:
            print("Warning: Missing dependency Pulsectl")

    state = 0
    player_timer = Timer()
    loaded_track = None
    fade_time = 400

    aud = ctypes.cdll.LoadLibrary(pctl.install_directory + "/lib/libphazor.so")
    aud.init()
    aud.set_volume(int(pctl.player_volume))

    def calc_rg(track):

        if prefs.replay_gain == 0 and prefs.replay_preamp == 0:
            pctl.active_replaygain = 0
            return 0

        g = 0
        p = 1

        if track is not None:
            tg = track.misc.get("replaygain_track_gain")
            tp = track.misc.get("replaygain_track_peak")
            ag = track.misc.get("replaygain_album_gain")
            ap = track.misc.get("replaygain_album_peak")

            if prefs.replay_gain > 0:
                if (prefs.replay_gain == 1 and tg is not None) or (prefs.replay_gain == 2 and ag is None and tg is not None):
                    g = tg
                    if tp is not None:
                        p = tp
                elif ag is not None:
                    g = ag
                    if ap is not None:
                        p = ap

        # print("Replay gain")
        # print("GAIN: " + str(g))
        # print("PEAK: " + str(p))
        # print("FINAL: " + str(min(10 ** ((g + prefs.replay_preamp) / 20), 1 / p)))
        pctl.active_replaygain = g
        return min(10 ** ((g + prefs.replay_preamp) / 20), 1 / p)

    audio_cache = tauon.cache_directory + "/network-audio1"

    class DownloadObject:
        def __init__(self, track):
            self.timestamp = time.time()
            self.status = "prep"
            self.tauon_id = track.index
            self.filepath = audio_cache
            if not os.path.exists(self.filepath):
                os.makedirs(self.filepath)
            self.filepath += "/" + str(self.tauon_id) + ".mp3"
            if os.path.exists(self.filepath):
                os.remove(self.filepath)
            self.network_url = ""
            self.params = ""
            self.part = None
            self.cancel = False
            self.downloaded_duration = -1

        def download(self):
            print("Start download")
            try:
                self.part = requests.get(self.network_url, stream=True, params=self.params)

                if self.part.status_code == 404:
                    gui.show_message("Server: File not found", mode="error")
                    self.status = "error"
                    return
                elif self.part.status_code != 200:
                    gui.show_message("Server Error", mode="error")
                    self.status = "error"
                    return

            except:
                gui.show_message("Could not connect to server", mode="error")
                self.status = "error"
                return

            bitrate = 0
            a = 0
            z = 0

            with open(self.filepath, 'wb') as f:
                for chunk in self.part.iter_content(chunk_size=1024):
                    if chunk:  # filter out keep-alive new chunks
                        a += 1
                        if a == 300:  # kilobyes~
                            self.status = "ready"
                        if self.cancel is True:
                            self.part.close()
                            self.status = "failed"
                            print("Abort download")
                            return

                        f.write(chunk)

                        z += 1
                        if z == 60:
                            z = 0
                            if bitrate == 0:
                                audio = auto.File(self.filepath)
                                bitrate = audio.bitrate
                            if bitrate > 0:
                                gui.update += 1
                                self.downloaded_duration = a * 1024 / (bitrate / 8) / 1000
                                #pctl.download_time = a * 1024 / (bitrate / 8) / 1000

            #pctl.download_time = -1

            self.status = "done"
            print("Download done")

    class DownloadManager:

        def __init__(self):
            self.items = {}
            if os.path.exists(audio_cache):
                shutil.rmtree(audio_cache)

        def get_filepath(self, track):
            return self.items[track.index].filepath

        def _prune(self):

            items = list(self.items.values())
            items.sort(key=lambda x: x.timestamp)
            for item in items:
                if item.status in ("ready", "prep"):
                    item.cancel = True
                elif item.status in ("failed", "error"):
                    print("prune failed item")
                    if os.path.exists(item.filepath):
                        os.remove(item.filepath)
                    del self.items[item.tauon_id]

            items = list(self.items.values())
            items.sort(key=lambda x: x.timestamp)
            items = items[:-25]
            for item in items:
                print("prune old item")
                if os.path.exists(item.filepath):
                    os.remove(item.filepath)
                del self.items[item.tauon_id]


        def request(self, track, t=0, whole=False):

            if track.index in self.items:
                item = self.items[track.index]

                if item.status == "ready":
                    if whole:
                        return "wait"
                    if t == 0:
                        return "go"
                    elif item.downloaded_duration > t + 20:
                        return "go"
                    elif t:
                        return "wait"

                if item.status == "done":
                    item.timestamp = time.time()
                    print("Use cached audio")
                    return "go"
                if item.status == "prep":
                    return "wait"
                if item.status == "error":
                    del self.items[track.index]
                    return "error"
                if item.status == "failed":
                    del self.items[track.index]

                if t:
                    print(item.status)
                    return "wait"

            self._prune()

            item = DownloadObject(track)

            try:
                item.network_url, item.params = pctl.get_url(target_object)
            except:
                return "error"

            self.items[track.index] = item
            shoot_dl = threading.Thread(target=item.download)
            shoot_dl.daemon = True
            shoot_dl.start()

            return "wait"

    dm = DownloadManager()


    class URLDownloader:

        def __init__(self):
            self.active_url = ""
            self.part = None
            self.dl_ready = False
            self.dl_running = False
            self.save_temp = ""
            self.alt = "b"

        def download_part(self, url, target, params, item):

            self.dl_running = True

            try:
                self.part = requests.get(url, stream=True, params=params)

                if self.part.status_code == 404:
                    gui.show_message("Server: File not found", mode="error")
                    self.dl_ready = "failure"
                    return
                elif self.part.status_code != 200:
                    gui.show_message("Server Error", mode="error")
                    self.dl_ready = "failure"
                    return

            except:
                gui.show_message("Could not connect to server", mode="error")
                self.dl_ready = "failure"
                return

            bitrate = 0
            a = 0
            z = 0

            if os.path.isfile(target):
                os.remove(target)

            with open(target, 'wb') as f:
                for chunk in self.part.iter_content(chunk_size=1024):
                    if chunk:  # filter out keep-alive new chunks
                        a += 1
                        if a == 300:  # kilobyes~
                            self.dl_ready = True
                        if url != self.active_url:
                            self.part.close()
                            print("Abort download")
                            break

                        f.write(chunk)

                        z += 1
                        if z == 60:
                            z = 0
                            if bitrate == 0:
                                audio = auto.File(target)
                                bitrate = audio.bitrate
                            if bitrate > 0:
                                gui.update += 1
                                pctl.download_time = a * 1024 / (bitrate / 8) / 1000

            pctl.download_time = -1

            self.dl_ready = True
            self.dl_running = False

    dl = URLDownloader()

    def set_config():
        aud.config_set_dev_buffer(prefs.device_buffer)

        if prefs.phazor_device_selected != "Default":
            if prefs.phazor_device_selected in prefs.phazor_devices.values():
                aud.config_set_dev_name(prefs.phazor_device_selected.encode())
            else:
                print("Warning: Selected audio output is now missing. Defaulting to default.")
                aud.config_set_dev_name(None)
        else:
            aud.config_set_dev_name(None)

    set_config()

    while True:

        time.sleep(0.016)
        # Level meter
        if state == 1 and gui.vis == 1:
            amp = aud.get_level_peak_l()
            l = (amp / 32767) * 12
            amp = aud.get_level_peak_r()
            r = (amp / 32767) * 12

            tauon.level_train.append((0, l, r))
            gui.level_update = True

        # Command processing
        if pctl.playerCommandReady:

            command = pctl.playerCommand
            subcommand = pctl.playerSubCommand
            pctl.playerSubCommand = ""
            pctl.playerCommandReady = False

            if command == "reload":
                set_config()

            if command == "url":
                pctl.download_time = 0
                w = 0
                while len(tauon.stream_proxy.chunks) < 200:
                    time.sleep(0.1)
                    w += 1
                    if w > 100:
                        print("Taking too long!")
                        tauon.stream_proxy.stop()
                        pctl.playerCommand = 'stop'
                        pctl.playerCommandReady = True
                        break
                else:
                    aud.start(pctl.url.encode(), 0, 0, ctypes.c_float(calc_rg(None)))
                    state = 3
                    player_timer.hit()

            if command == "open":
                if state == 2:
                    aud.set_volume(int(pctl.player_volume))

                pctl.download_time = 0
                target_object = pctl.target_object
                target_path = target_object.fullpath

                if (tauon.spot_ctl.playing or tauon.spot_ctl.coasting) and not target_object.file_ext == "SPTY":
                    tauon.spot_ctl.control("stop")

                if target_object.is_network:

                    dl.dl_running = False

                    if target_object.file_ext == "SPTY":
                        tauon.level_train.clear()
                        if state > 0:
                            aud.stop()
                        state = 0
                        try:
                            tauon.spot_ctl.play_target(target_object.url_key)
                        except:
                            print("Failed to start Spotify track")
                            pctl.playerCommand = "stop"
                            pctl.playerCommandReady = True
                        continue

                    target_path = None
                    while True:
                        s = dm.request(target_object)
                        if s == "go":
                            target_path = dm.get_filepath(target_object)
                            break
                        elif s == "wait":
                            if pctl.playerCommandReady and pctl.playerCommand == "open":
                                break
                            #print("wait")
                            time.sleep(0.01)
                        else:
                            print("Abort for error")
                            break
                    if target_path is None:
                        continue
                    #
                    # url = ""
                    # params = None
                    #
                    # try:
                    #     url, params = pctl.get_url(target_object)
                    # except:
                    #     gui.show_message("Failed to query url", "Bad login? Server offline?", mode='info')
                    #     pctl.stop()
                    #     return
                    #
                    # if url is None:
                    #     print(gui.show_message("Failed to query url", "Bad login? Server offline?", mode='info'))
                    #     pctl.stop()
                    #     return
                    #
                    # dl.save_temp = prefs.cache_directory + "/" + dl.alt + "-temp.mp3"
                    #
                    # if dl.alt == 'a':
                    #     dl.alt = 'b'
                    # else:
                    #     dl.alt = 'a'
                    #
                    # dl.active_url = url
                    # dl.dl_ready = False
                    #
                    # shoot_dl = threading.Thread(target=dl.download_part, args=([url, dl.save_temp, params, target_object]))
                    # shoot_dl.daemon = True
                    # shoot_dl.start()
                    #
                    # while not dl.dl_ready:
                    #     time.sleep(0.02)
                    # target_path = dl.save_temp
                    #
                    # if dl.dl_ready == "failure":
                    #     state = 0
                    #     aud.stop()
                    #     continue
                # if not target_object.is_network and target_object.file_ext not in ("MP3", "FLAC", "OGG", "OPUS"):
                #     state = 0
                #     aud.stop()
                #     continue

                if not os.path.isfile(target_path):
                    target_object.found = False
                    if not target_object.is_network:
                        pctl.playing_state = 0
                        pctl.jump_time = 0
                        pctl.advance(inplace=True, play=True)
                    continue
                elif not target_object.found:
                    pctl.reset_missing_flags()

                length = 0
                remain = 0
                position = 0
                if state == 1 and not pctl.start_time_target and not pctl.jump_time and \
                        loaded_track:

                    length = aud.get_length_ms() / 1000
                    position = aud.get_position_ms() / 1000
                    remain = length - position

                    # print("length: " + str(length))
                    # print("position: " + str(position))
                    # print("We are %s from end" % str(remain))

                    if loaded_track.is_network:
                        length = loaded_track.length
                        remain = length - position

                fade = 0
                if state == 1 and length and position and not pctl.start_time_target and not pctl.jump_time and \
                        loaded_track and 0 < remain < 5.5 and not loaded_track.is_cue and subcommand != "now":

                    print("Transition gapless mode")

                    aud.next(target_path.encode(), int(pctl.start_time_target + pctl.jump_time) * 1000, ctypes.c_float(calc_rg(target_object)))
                    pctl.playing_time = pctl.jump_time

                    if remain > 0:
                        time.sleep(0.01)
                        remain -= 0.01
                        if pctl.playerCommandReady and pctl.playerCommand == "open":
                            break

                    loaded_track = target_object

                else:
                    if state == 1 and prefs.use_jump_crossfade:
                        fade = 1
                    aud.start(target_path.encode(), int(pctl.start_time_target + pctl.jump_time) * 1000, fade, ctypes.c_float(calc_rg(target_object)))
                    loaded_track = target_object
                    pctl.playing_time = pctl.jump_time
                    if pctl.jump_time:
                        while aud.get_result() == 0:
                            time.sleep(0.01)
                        aud.set_position_ms(int(pctl.jump_time * 1000))

                    # Restart track is failed to load (for some network tracks) (broken with gapless loading)
                    while True:
                        r = aud.get_result()
                        if r == 1:
                            break
                        if r == 2:
                            if loaded_track.is_network:
                                gui.buffering = True
                                while dm.request(loaded_track, whole=True) == "wait":
                                    time.sleep(0.05)
                                    if pctl.playerCommandReady:
                                        break
                                print("Retry start file")
                                aud.start(target_path.encode(), int(pctl.start_time_target + pctl.jump_time) * 1000,
                                          fade, ctypes.c_float(calc_rg(target_object)))
                                gui.buffering = False
                                player_timer.set()
                                break
                            else:
                                aud.stop()
                                gui.show_message("Error loading track", mode="warning")
                        time.sleep(0.05)

                    state = 1

                player_timer.set()
                pctl.jump_time = 0
                if loaded_track.length == 0 or loaded_track.file_ext.lower() in tauon.mod_formats:
                    i = 0
                    t = 0
                    while t == 0:
                        time.sleep(0.3)
                        t = aud.get_length_ms() / 1000
                        i += 1
                        if i > 9:
                            break
                    loaded_track.length = t
                    if loaded_track.length != 0:
                        pctl.playing_length = loaded_track.length
                        gui.pl_update += 1

            if command == "seek":
                if tauon.spot_ctl.coasting or tauon.spot_ctl.playing:
                    tauon.spot_ctl.control("seek", int(pctl.new_time * 1000))
                    pctl.playing_time = pctl.new_time
                elif state > 0:

                    if loaded_track.is_network:  # and loaded_track.fullpath.endswith(".ogg"):

                        was_playing = False
                        if state == 1:
                            was_playing = True
                            aud.pause()

                        abort = False
                        while True:
                            s = dm.request(loaded_track, t=pctl.new_time)
                            if s == "go":
                                break

                            if pctl.playerCommandReady:
                                abort = True
                                break

                            if s == "wait":
                                gui.buffering = True
                                print("Can't seek yet")
                                time.sleep(0.1)
                                continue
                            abort = True
                            break
                        gui.buffering = False
                        if abort:
                            continue

                        # The vorbis decoder doesn't like appended files
                        aud.start(dm.get_filepath(loaded_track).encode(), int(pctl.new_time + pctl.start_time_target) * 1000, 0, ctypes.c_float(calc_rg(loaded_track)))
                        while aud.get_result() == 0:
                            time.sleep(0.01)
                        aud.set_position_ms(int(pctl.new_time * 1000))
                    else:
                        aud.seek(int((pctl.new_time + pctl.start_time_target) * 1000), prefs.pa_fast_seek)

                    pctl.playing_time = pctl.new_time

                pctl.decode_time = pctl.playing_time
            if command == "volume":
                if tauon.spot_ctl.coasting or tauon.spot_ctl.playing:
                    tauon.spot_ctl.control("volume", int(pctl.player_volume))
                else:
                    aud.ramp_volume(int(pctl.player_volume), 750)
            if command == "runstop":
                length = aud.get_length_ms() / 1000
                position = aud.get_position_ms() / 1000
                remain = length - position
                # print("length: " + str(length))
                # print("position: " + str(position))
                # print("We are %s from end" % str(remain))
                time.sleep(3)
                command = "stop"

            if command == "stop":

                if prefs.use_pause_fade and state != 3:
                    if pctl.player_volume > 5:
                        speed = fade_time / (int(pctl.player_volume) / 100)
                    else:
                        speed = fade_time / (5 / 100)

                    aud.ramp_volume(0, int(speed))
                    time.sleep((fade_time + 100) / 1000)

                state = 0
                pctl.playing_time = 0
                aud.stop()
                time.sleep(0.1)
                aud.set_volume(int(pctl.player_volume))

                if subcommand == "return":
                    pctl.playerSubCommand = "stopped"
                    #pctl.playerCommandReady = True

            if command == "pauseon":
                if prefs.use_pause_fade:
                    if pctl.player_volume > 5:
                        speed = fade_time / (int(pctl.player_volume) / 100)
                    else:
                        speed = fade_time / (5 / 100)

                    aud.ramp_volume(0, int(speed))
                    time.sleep((fade_time + 100) / 1000)
                aud.pause()
                state = 2

            if command == "pauseoff":
                if prefs.use_pause_fade:
                    if pctl.player_volume > 5:
                        speed = fade_time / (int(pctl.player_volume) / 100)
                    else:
                        speed = fade_time / (5 / 100)

                    aud.ramp_volume(int(pctl.player_volume), int(speed))
                aud.resume()
                player_timer.set()
                state = 1

            if command == "unload":

                if prefs.use_pause_fade:
                    if pctl.player_volume > 5:
                        speed = fade_time / (int(pctl.player_volume) / 100)
                    else:
                        speed = fade_time / (5 / 100)

                    aud.ramp_volume(0, int(speed))
                    time.sleep((fade_time + 100) / 1000)

                aud.stop()
                aud.shutdown()

                if os.path.exists(audio_cache):
                    shutil.rmtree(audio_cache)

                pctl.playerCommand = "done"
                pctl.playerCommandReady = True
                break

        else:

            pctl.spot_test_progress()

            if state == 3:
                pctl.radio_progress()
                add_time = player_timer.hit()
                pctl.playing_time += add_time
                pctl.decode_time = pctl.playing_time

                buffering = aud.is_buffering()
                if gui.buffering != buffering:
                    gui.buffering = buffering
                    gui.update += 1


            if state == 1:

                if loaded_track.is_network and pctl.playing_time < 7:
                    if aud.get_result() == 2:
                        print("STALL, RETRY")
                        time.sleep(0.5)
                        pctl.playerCommandReady = True
                        pctl.playerCommand = "open"

                add_time = player_timer.hit()
                if add_time > 2:
                    add_time = 2
                if add_time < 0:
                    add_time = 0

                pctl.playing_time += add_time

                t = aud.get_position_ms() / 1000

                pctl.total_playtime += add_time

                if t:
                    pctl.decode_time = t - loaded_track.start_time
                else:
                    pctl.decode_time = pctl.playing_time

                #print((pctl.playing_time, pctl.decode_time))

                if pctl.playing_time < 3 and pctl.a_time < 3:
                    pctl.a_time = pctl.playing_time
                else:
                    pctl.a_time += add_time

                tauon.lfm_scrobbler.update(add_time)

                if len(pctl.track_queue) > 0 and 2 > add_time > 0:
                    tauon.star_store.add(pctl.track_queue[pctl.queue_step], add_time)
                if pctl.playing_time > 1:
                    pctl.test_progress()
示例#3
0
文件: client.py 项目: vlad-pbr/kiwi
def kiwi_main(kiwi):
    pass

    parser = argparse.ArgumentParser(
        description=kiwi.module_desc,
        epilog=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)

    subparsers = parser.add_subparsers(dest="action")
    parser.add_argument("-q",
                        "--quiet",
                        help="do not display any output",
                        action="store_true")

    # system volume control
    volume_subparser = subparsers.add_parser("volume")
    volume_subparser.add_argument("-I",
                                  "--intervals",
                                  type=int,
                                  metavar="AMOUNT",
                                  help="intervals of the entire volume range")
    volume_subparser.add_argument("-s",
                                  "--sink",
                                  type=int,
                                  metavar="INDEX",
                                  help="target sink index",
                                  default=0)
    volume_subparser.add_argument(
        "--range-symbol",
        type=str,
        metavar="SYMBOL",
        help="symbol that represents a unit of range",
        default="─")
    volume_subparser.add_argument(
        "--value-symbol",
        type=str,
        metavar="SYMBOL",
        help="symbol that represents the current value of range",
        default="|")
    volume_control_group = volume_subparser.add_mutually_exclusive_group()
    volume_control_group.add_argument("-t",
                                      "--toggle-mute",
                                      action="store_true",
                                      help="toggle sound mute")
    volume_control_group.add_argument("-m",
                                      "--mute",
                                      action="store_true",
                                      help="mute sound")
    volume_control_group.add_argument("-u",
                                      "--unmute",
                                      action="store_true",
                                      help="unmute sound")
    volume_control_group.add_argument(
        "-i",
        "--increment",
        type=int,
        metavar="PERCENTAGE",
        help="increment volume by specified percentage",
        choices=range(1, 100))
    volume_control_group.add_argument(
        "-d",
        "--decrement",
        type=int,
        metavar="PERCENTAGE",
        help="decrement volume by specified percentage",
        choices=range(1, 100))

    # system information
    info_subparser = subparsers.add_parser("info")
    info_subparser.add_argument("-j",
                                "--jsonpath",
                                type=str,
                                metavar="PATH",
                                help="fetch specific fields from result")
    info_subparsers = info_subparser.add_subparsers(dest="info_action")

    # system information
    for item in [
            "wan", "lan", "ram", "swap", "cpu", "net", "temp", "fans",
            "battery"
    ]:
        info_subparsers.add_parser(item)

    args = parser.parse_args()

    # write stdout to devnull if quiet
    stdout = sys.stdout
    devnull = open(os.devnull, 'w')
    if args.quiet:
        sys.stdout = devnull

    try:

        # system volume control
        if args.action == "volume":

            import pulsectl

            # must provide a range to print it out
            if not args.quiet:
                if not args.intervals:
                    parser.error("must provide interval range if not using -q")
            else:
                args.intervals = 0

            # pulseaudio client
            with pulsectl.Pulse('client') as pulse:

                # get target sink
                target_sink = pulse.sink_list()[args.sink]

                # base off of the left channel volume
                current_volume = target_sink.volume.values[0]

                # if volume should be altered
                if args.increment or args.decrement or args.toggle_mute or args.mute or args.unmute:

                    # if volume should be incremented
                    if args.increment or args.decrement:

                        # decide on a value
                        increment_value = args.increment if args.increment else -args.decrement

                        # keep target volume in range
                        target_volume = current_volume + (increment_value /
                                                          100.0)
                        if target_volume > 1 or target_volume < 0:
                            target_volume = abs(target_volume) - (
                                abs(target_volume) % 1)

                    # mute/unmute
                    else:

                        # action related functions
                        def mute(current_volume):
                            with open(VOLUME_CACHE_FILENAME,
                                      'w') as VOLUME_CACHE:
                                VOLUME_CACHE.write(str(current_volume))
                            return 0

                        def unmute():
                            if os.path.isfile(VOLUME_CACHE_FILENAME):
                                with open(VOLUME_CACHE_FILENAME,
                                          'r') as VOLUME_CACHE:
                                    return float(VOLUME_CACHE.read())
                            return 1.0

                        def toggle():

                            if current_volume == 0:
                                return unmute()
                            else:
                                return mute(current_volume)

                        # act based on parameter
                        if args.toggle_mute:
                            target_volume = toggle()
                        elif args.mute:
                            target_volume = mute(current_volume)
                        else:
                            target_volume = unmute()

                    # set result volume
                    pulse.volume_set_all_chans(target_sink, target_volume)

                    # update current volume value
                    current_volume = target_volume

                # print volume state
                volume_range = args.range_symbol * args.intervals
                value_index = max(
                    0,
                    math.floor(args.intervals * current_volume) - 1)
                print(volume_range[:value_index] + args.value_symbol +
                      volume_range[value_index + 1:])

        # networking information
        elif args.action == "info":

            import psutil
            import jsonpath

            # get appropriate info
            info_json = {
                "wan":
                lambda: loads(kiwi.request(Request('GET', '/info/wan')).text),
                "lan":
                lambda: psutil.net_if_addrs(),
                "ram":
                lambda: psutil.virtual_memory()._asdict(),
                "swap":
                lambda: psutil.swap_memory()._asdict(),
                "cpu":
                lambda: {
                    'system-wide': psutil.cpu_percent(interval=1),
                    'per-cpu': psutil.cpu_percent(percpu=True),
                    'stats': psutil.cpu_stats()._asdict(),
                    'freq': psutil.cpu_freq()._asdict()
                },
                "net":
                lambda: psutil.net_io_counters()._asdict(),
                "temp":
                lambda: psutil.sensors_temperatures(),
                "fans":
                lambda: psutil.sensors_fans(),
                "battery":
                lambda: psutil.sensors_battery()._asdict(),
            }.get(args.info_action, lambda: None)()
            info_json = info_json if info_json else {}

            # print query if specified, otherwise print everything
            if args.jsonpath:
                result = jsonpath.jsonpath(loads(dumps(info_json)),
                                           args.jsonpath)

                # format result
                if result:
                    if len(result) == 1:
                        result = result[0]
                else:
                    result = ""

                print(result, end="")
            else:
                print(dumps(info_json, indent=4), end="")

    finally:
        sys.stdout = stdout
示例#4
0
文件: module.py 项目: Peziman/pyCAR
from PyQt4 import Qt, QtCore, QtGui, uic
import os, netifaces as ni, psutil, time, alsaaudio, pulsectl
from subprocess import call
from xml.dom import minidom

path=os.path.dirname(os.path.abspath( __file__ ))
form_class = uic.loadUiType(path+"/gui.ui")[0]
pulse = pulsectl.Pulse('pyCAR')

class tableModel(QtGui.QStandardItemModel):
    def __init__(self,datain,parent=None,*args):
        QtGui.QStandardItemModel.__init__(self,parent,*args)
        self.header = None
        self.modules = None
        
    def headerData(self,section,orientation,role=QtCore.Qt.DisplayRole):
        if orientation==QtCore.Qt.Vertical:
            if role==QtCore.Qt.DecorationRole:
                mPath = path.rsplit('/', 1)
                module = self.modules[section]
                return QtGui.QPixmap(mPath[0]+"/"+module.attributes["name"].value+"/button.png")
            if role==QtCore.Qt.DisplayRole:
                return ""
        if role==QtCore.Qt.DisplayRole and orientation==QtCore.Qt.Horizontal:
            return self.header[section]
        return QtGui.QStandardItemModel.headerData(self,section,orientation,role)
        
    def itemChanged(self, item):
        print(item)
        print("Item {!r} checkState: {}".format(item.text(), item.checkState())) 
示例#5
0
def init_pulse():
    return pulsectl.Pulse('rofi_sinks')
示例#6
0
class Ui_MainWindow(object):

    #txrxOffset = 10057500000 # Difference between rx & tx
    txrxOffsetFixed = 10057500000  # Difference between rx & tx
    txrxOffset = txrxOffsetFixed
    #txrxOffset = 10057500080 # Difference between rx & tx
    #txrxOffset = 10057500030 # Difference between rx & tx
    #txrxOffset = 10057500050 # Difference between rx & tx
    #txrxOffset = 10057499700 # Difference between rx & tx
    #txrxOffset = 10057499950 # Difference between rx & tx
    #txrxOffset = 10057499930 # Difference between rx & tx
    #txrxOffset = 10057499900 # Difference between rx & tx
    #txrxOffset = 10057499990 # Difference between rx & tx
    #txrxOffset = 10057500950 # Difference between rx & tx  # RTL +650 Hz
    #txrxOffset = 10057500250 # Difference between rx & tx  # RTL +650 Hz
    #txrxOffset = 10057500700 # Difference between rx & tx  # RTL +650 Hz
    rxHost = "localhost"  # expecting rx to be 10498
    rxPort = 7356
    txHost = "localhost"  # expecting 432.
    txPort = 4568
    soundcardName = 'HyperX Virtual Surround Sound Analogue Stereo'  # Get sound card name from list with output from below script

    #pulseDev = 1 	# Audio sink in pulse to mute, list devs with:
    # import pulsectl
    # pulse = pulsectl.Pulse('my-client-name')
    # for x in pulse.sink_list() :
    #  print x
    pulse = pulsectl.Pulse('my-client-name')
    pulseDev = 0
    rxFreq = 0
    txFreq = 0
    syncRxReq = 0
    syncRxFreq = 0
    syncTxReq = 0
    syncTxFreq = 0
    offsetHz = 0
    pttSet = 0  # 0 = no change, 1 = request ptt on, 2 = request ptt off

    for x in pulse.sink_list():
        if re.search(soundcardName, str(x)):
            break
        pulseDev = pulseDev + 1

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(759, 284)
        MainWindow.setFixedSize(MainWindow.size())
        self.centralWidget = QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.offsetLbl1 = QLabel(self.centralWidget)
        self.offsetLbl1.setGeometry(QRect(30, 170, 101, 31))
        font = QFont()
        font.setPointSize(17)
        self.offsetLbl1.setFont(font)
        self.offsetLbl1.setObjectName("offsetLbl1")
        self.txLabel = QLabel(self.centralWidget)
        self.txLabel.setGeometry(QRect(480, 0, 231, 31))
        font = QFont()
        font.setPointSize(17)
        self.txLabel.setFont(font)
        self.txLabel.setObjectName("txLabel")
        self.rxLabel = QLabel(self.centralWidget)
        self.rxLabel.setGeometry(QRect(60, 0, 231, 31))
        font = QFont()
        font.setPointSize(17)
        self.rxLabel.setFont(font)
        self.rxLabel.setObjectName("rxLabel")
        self.offsetLbl2 = QLabel(self.centralWidget)
        self.offsetLbl2.setGeometry(QRect(140, 170, 51, 31))
        font = QFont()
        font.setPointSize(17)
        self.offsetLbl2.setFont(font)
        self.offsetLbl2.setLayoutDirection(Qt.LeftToRight)
        self.offsetLbl2.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                     | Qt.AlignVCenter)
        self.offsetLbl2.setObjectName("offsetLbl2")
        self.syncRxButton = QPushButton(self.centralWidget)
        self.syncRxButton.setGeometry(QRect(340, 120, 85, 27))
        self.syncRxButton.setObjectName("syncRxButton")
        self.syncRxButton.clicked.connect(self.syncRx)  # Added
        self.muteButton = QPushButton(self.centralWidget)
        self.muteButton.setGeometry(QRect(330, 170, 101, 71))
        font = QFont()
        font.setPointSize(13)
        self.muteButton.setFont(font)
        self.muteButton.setCheckable(True)
        self.muteButton.setObjectName("muteButton")
        self.muteButton.clicked.connect(self.setMute)  # Added
        self.offsetSlider = QSlider(self.centralWidget)
        self.offsetSlider.setGeometry(QRect(10, 210, 311, 18))
        self.offsetSlider.setMinimum(-500)
        self.offsetSlider.setMaximum(500)
        self.offsetSlider.setSingleStep(10)
        self.offsetSlider.setOrientation(Qt.Horizontal)
        self.offsetSlider.setTickPosition(QSlider.TicksBelow)
        self.offsetSlider.setTickInterval(100)
        self.offsetSlider.setObjectName("offsetSlider")
        self.offsetSlider.valueChanged.connect(self.offsetChange)  # Added
        self.lcdTx = QLCDNumber(self.centralWidget)
        self.lcdTx.setGeometry(QRect(440, 40, 311, 121))
        self.lcdTx.setDigitCount(8)
        self.lcdTx.setObjectName("lcdTx")
        self.lcdRx = QLCDNumber(self.centralWidget)
        self.lcdRx.setGeometry(QRect(10, 40, 311, 121))
        self.lcdRx.setDigitCount(8)
        self.lcdRx.setObjectName("lcdRx")
        self.syncTxButton = QPushButton(self.centralWidget)
        self.syncTxButton.setGeometry(QRect(340, 40, 85, 27))
        self.syncTxButton.setObjectName("syncTxButton")
        self.syncTxButton.clicked.connect(self.syncTx)  # Added
        self.linkButton = QPushButton(self.centralWidget)
        self.linkButton.setGeometry(QRect(340, 80, 85, 27))
        self.linkButton.setCheckable(True)  # Added
        self.linkButton.setObjectName("linkButton")
        self.linkButton.clicked.connect(self.linkTx)  # Added
        self.pttButton = QPushButton(self.centralWidget)
        self.pttButton.setGeometry(QRect(440, 170, 301, 71))
        font = QFont()
        font.setPointSize(27)
        self.pttButton.setFont(font)
        self.pttButton.setCheckable(True)
        self.pttButton.setObjectName("pttButton")
        self.pttButton.clicked.connect(self.setPtt)  # Added

        self.offsetLbl3 = QLabel(self.centralWidget)
        self.offsetLbl3.setGeometry(QRect(200, 170, 71, 31))
        font = QFont()
        font.setPointSize(17)
        self.offsetLbl3.setFont(font)
        self.offsetLbl3.setObjectName("offsetLbl3")
        MainWindow.setCentralWidget(self.centralWidget)
        self.mainToolBar = QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

        self.threadpool = QThreadPool()

        rxWorker = Worker(self.connRx)
        self.threadpool.start(rxWorker)

        txWorker = Worker(self.connTx)
        self.threadpool.start(txWorker)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(
            _translate("MainWindow", "QO-100 Hamlib Helper"))
        self.offsetLbl1.setText(_translate("MainWindow", "TX Offset"))
        self.txLabel.setText(_translate("MainWindow", "  Transmit 2400."))
        self.rxLabel.setText(_translate("MainWindow", " Receive 10498."))
        self.offsetLbl2.setText(_translate("MainWindow", "0"))
        self.syncRxButton.setText(_translate("MainWindow", "<< SYNC  "))
        self.muteButton.setText(_translate("MainWindow", "Mute On TX"))
        self.syncTxButton.setText(_translate("MainWindow", "  SYNC >>"))
        self.linkButton.setText(_translate("MainWindow", "<< LINK >>"))
        self.pttButton.setText(_translate("MainWindow", "PTT"))
        self.offsetLbl3.setText(_translate("MainWindow", "Hz"))

    def setMute(self):  # Added
        if self.pttButton.isChecked():
            if self.muteButton.isChecked():
                self.pulse.mute(self.pulse.sink_list()[self.pulseDev], True)
            else:
                self.pulse.mute(self.pulse.sink_list()[self.pulseDev], False)

    def setPtt(
            self
    ):  # Added, need to allow easier configuration and setting by name
        if self.pttButton.isChecked():
            self.pttButton.setStyleSheet(
                "background-color: red; border-radius: 1px;")
            if (self.muteButton.isChecked()):
                self.pulse.mute(self.pulse.sink_list()[self.pulseDev], True)
            self.pttSet = 1  # request ptt on
        else:
            self.pttButton.setStyleSheet("background-color: light grey")
            if (self.muteButton.isChecked()):
                self.pulse.mute(self.pulse.sink_list()[self.pulseDev], False)
            self.pttSet = 2  # request ptt off, 0 = no change
        #print ("Mute: %d" % self.isMuted)

    def offsetChange(self):
        self.offsetHz = int(round(self.offsetSlider.value(), -1))
        self.offsetLbl2.setText(str(self.offsetHz))

    def syncTx(self):
        #print ("sync Tx Txold: %d Rxnow: %d" % (int(self.txFreq), int(self.rxFreq)))
        shortF = self.txFreq[3:]  # strip leading three, 432 here
        self.lcdTx.display(shortF[:3] + "." + shortF[3:])  # display xxx.xxx
        self.txFreq = str((int(self.rxFreq) - self.txrxOffset))
        self.syncTxFreq = str((int(self.rxFreq) - self.txrxOffset))
        self.syncTxReq = 1

    def syncRx(self):
        shortF = self.rxFreq[5:]  # strip leading three, 10368 here
        self.lcdRx.display(shortF[:3] + "." + shortF[3:])  # display xxx.xxx
        self.rxFreq = str((int(self.txFreq) + self.txrxOffset))
        self.syncRxFreq = str((int(self.txFreq) + self.txrxOffset))
        self.syncRxReq = 1

    def linkTx(self):
        if self.linkButton.isChecked():
            #print ("linking")
            self.syncTxButton.setEnabled(False)
            self.syncRxButton.setEnabled(False)
            self.linkButton.setStyleSheet(
                "background-color: red; border-radius: 1px;")
        else:
            #print ("unlinking")
            self.syncTxButton.setEnabled(True)
            self.syncRxButton.setEnabled(True)
            self.linkButton.setStyleSheet("background-color: light grey;")

    def connRx(self):
        try:
            connSock = socket(AF_INET, SOCK_STREAM)
            connSock.connect((self.rxHost, self.rxPort))
            while 1:
                time.sleep(0.1)
                if (self.syncRxReq):
                    #connSock.send('F %s' % self.rxFreq)
                    sendString = ('F %s' % self.syncRxFreq)
                    connSock.send(sendString.encode())
                    #connSock.send('F %s'.encode() % self.syncRxFreq)
                    self.syncRxReq = 0
                else:
                    connSock.send('f\n'.encode())
                output = connSock.recv(100).decode()
                if not (re.match(r'^[0-9]+$',
                                 str(output))):  # change to not that or RPRT0
                    #print ("Unexpected non frequency response from hamlib: " + str(output)) # not strictly true F does this
                    continue
                self.rxFreq = str(output)
                #print ('RX Frequency offset: %d read: %d real: %d' % (self.offsetHz, int(self.rxFreq), (int(self.rxFreq) + self.offsetHz)))
                #print ('TXRX Offset:%d With Adjust: %d' % (self.txrxOffset, int(self.txrxOffset - self.offsetHz)) )
                shortF = self.rxFreq[5:]  # strip leading three, 10368 here
                self.lcdRx.display(shortF[:3] + "." +
                                   shortF[3:])  # display xxx.xxx
                #print shortF[:3] + "." + shortF[3:]
                #self.lcdRx.display(self.rxFreq)
            ConnSock.close()
        except:
            print('Could not connect to Rx.')
            os._exit(1)

    def connTx(
            self
    ):  # ****** make sure turns PTT off when program exits? ********
        try:
            connSock = socket(AF_INET, SOCK_STREAM)
            connSock.connect((self.txHost, self.txPort))
            while 1:
                time.sleep(0.1)
                if ((self.txrxOffsetFixed - self.offsetHz) !=
                        self.txrxOffset):  # Adjust TX offset if changed in GUI
                    self.txrxOffset = self.txrxOffsetFixed - self.offsetHz
                if (self.syncTxReq):
                    #print ("TX Sync requested %s" % self.syncTxFreq)
                    sendString = ('F %s\n' % self.syncTxFreq)
                    connSock.send(sendString.encode())
                    self.syncTxReq = 0
                elif (self.pttSet == 1):
                    #print ("PTT ON REQUESTED")
                    connSock.send("T 1\n".encode())
                    os.system(
                        "(/usr/bin/mosquitto_pub -h 192.168.0.201 -t '/radio/amp/set2' -m 'ON')"
                    )
                    self.pttSet = 0
                elif (self.pttSet == 2):
                    #print ("PTT OFF REQUESTED")
                    connSock.send('T 0\n'.encode())
                    os.system(
                        "(/usr/bin/mosquitto_pub -h 192.168.0.201 -t '/radio/amp/set2' -m 'OFF')"
                    )
                    self.pttSet = 0
                elif (self.linkButton.isChecked()):
                    newTx = int(self.rxFreq) - self.txrxOffset
                    if (int(self.txFreq) != newTx):
                        #print ("Not equal, sync %d to %d" %(int(self.txFreq), newTx))
                        sendString = ('F %s\n' % newTx)
                        connSock.send(sendString.encode())
                        self.txFreq = str(newTx)
                    else:
                        connSock.send('f\n'.encode())
                else:
                    connSock.send('f\n'.encode())
                output = connSock.recv(100).decode()

                if not (re.match(r'^[0-9]+$', str(output))):
                    #print ("Unexpected non frequency response from hamlib: " + str(output))
                    continue

                self.txFreq = str(output)
                #print ('TX Frequency offset: %d read: %d real: %d' % (self.offsetHz, int(self.txFreq), (int(self.txFreq) + self.offsetHz)))
                shortF = self.txFreq[3:]  # strip leading three, 432 here
                self.lcdTx.display(shortF[:3] + "." +
                                   shortF[3:])  # display xxx.xxx
                #print shortF[:3] + "." + shortF[3:]
                #self.lcdTx.display(self.txFreq)
            ConnSock.close()
        except:
            print('Could not connect to Tx.')
            os._exit(1)
示例#7
0
文件: sound.py 项目: mtshrmn/dotfiles
import pulsectl

# streams that should be regarded as a game
game = [
    "Overwatch.exe;Audio Stream",
    "wine64-preloader;Simple DirectMedia Layer",
    "FactoryGame-Win64-Shipping.exe;Audio Stream",
    "FactoryGame-Win64-Shipping.exe;audio stream #1",
    "Borderlands2;Simple DirectMedia Layer",
    "Overwatch.exe;audio stream #1",
    "We Were Here.exe;audio stream #1",
    "FMOD Ex App;Mixer Stream",
    # "ZOOM VoiceEngine;playStream", <-- uncomment when zoom fixes their shitty app
]

with pulsectl.Pulse("sink handler") as pulse:
    # get indices of sinks:
    sinks = pulse.sink_list()
    game_sink = next(filter(lambda s: "Game" in s.description, sinks))
    chat_sink = next(filter(lambda s: "Chat" in s.description, sinks))
    monitor_sink = next(filter(lambda s: "HDMI" in s.description, sinks))

    for sink in pulse.sink_input_list():
        props = sink.proplist
        app_name = props["application.name"]
        description = props["media.name"]
        id_str = app_name + ";" + description

        if os.environ["PA_OUTPUT"] == "monitor":
            pulse.sink_input_move(sink.index, monitor_sink.index)
            continue
import time

import pulsectl

pulse = pulsectl.Pulse('app-volume-ctl2')

while True:
    for a in pulse.sink_input_list():
        print(a.proplist)
    print("===")
    time.sleep(1)
示例#9
0
 def __init__(self):
     super().__init__()
     self.pulse = pulsectl.Pulse()
     self.sink_name = self.pulse.server_info().default_sink_name
示例#10
0
import pulsectl

with pulsectl.Pulse('volume-increaser') as pulse:
    for sink in pulse.sink_list():
        # Volume is usually in 0-1.0 range, with >1.0 being soft-boosted
        pulse.volume_change_all_chans(sink, 0.1)
示例#11
0
import pulsectl

pulse = pulsectl.Pulse()

for source in pulse.source_list():
    print(f"Source {source.index} mute state is: {source.mute}")
    pulse.mute(source)

for source in pulse.source_list():
    print(f"Source {source.index} mute state is: {source.mute}")
import json
import subprocess
import pulsectl

import gi

gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')

from gi.repository import Gtk as gtk
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Notify as notify

APPINDICATOR_ID = 'soundprofileswitcher'
pulse = pulsectl.Pulse('soundprofileswitcher')

def main():
    indicator = appindicator.Indicator.new(APPINDICATOR_ID, "", appindicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu())
    notify.init(APPINDICATOR_ID)
    gtk.main()
    
def build_menu():
    menu = gtk.Menu()
    
    for card in pulse.card_list():
        menu.append(gtk.SeparatorMenuItem())    
        
        radio_group = None
示例#13
0
    def OnKeyPress(self, keyId):
        print("key press: {}".format(keyId))
        focus = self.GetFocus()
        parent = focus.GetParent()

        if keyId == Key.FOCUS_RIGHT.value:
            focus = self.GetFocusTiled() if focus.IsFloating(
            ) else focus.GetNext()
            #focus = focus.GetAdjacent(chamfer.adjacent.RIGHT);
            focus.Focus()

        elif keyId == Key.FOCUS_LEFT.value:
            focus = self.GetFocusTiled() if focus.IsFloating(
            ) else focus.GetPrev()
            #focus = focus.GetAdjacent(chamfer.adjacent.LEFT);
            focus.Focus()

        elif keyId == Key.FOCUS_DOWN.value:
            focus = focus.GetNext()
            #focus = focus.GetAdjacent(chamfer.adjacent.DOWN);
            focus.Focus()

        elif keyId == Key.FOCUS_UP.value:
            focus = focus.GetPrev()
            #focus = focus.GetAdjacent(chamfer.adjacent.UP);
            focus.Focus()

        elif keyId == Key.MOVE_RIGHT.value:
            focus.MoveNext()

        elif keyId == Key.MOVE_LEFT.value:
            focus.MovePrev()

        elif keyId == Key.FOCUS_PARENT.value:
            if parent is None:
                return
            parent.Focus()

        elif keyId == Key.FOCUS_CHILD.value:
            focus = focus.GetFocus()
            if focus is None:
                return
            focus.Focus()

        elif keyId == Key.FOCUS_MRU.value:
            try:
                self.shiftFocus.shaderFlags &= ~ShaderFlag.FOCUS_NEXT.value
            except AttributeError:
                pass

            try:
                self.shiftFocus = self.shiftFocus.GetTiledFocus()
            except AttributeError:
                self.shiftFocus = focus.GetTiledFocus()

            if self.shiftFocus is None:
                return
            self.shiftFocus.shaderFlags |= ShaderFlag.FOCUS_NEXT.value

            self.GrabKeyboard(True)

        elif keyId == Key.FOCUS_FLOAT.value:
            try:
                self.shiftFocus.shaderFlags &= ~ShaderFlag.FOCUS_NEXT.value
            except AttributeError:
                pass

            try:
                self.shiftFocus = self.shiftFocus.GetFloatFocus()
            except AttributeError:
                self.shiftFocus = focus.GetFloatFocus()

            if self.shiftFocus is None:
                return
            self.shiftFocus.shaderFlags |= ShaderFlag.FOCUS_NEXT.value

            self.GrabKeyboard(True)

        elif keyId == Key.FOCUS_FLOAT_PREV.value:
            #TODO, get previous from the focus history
            pass

        elif keyId == Key.FOCUS_PARENT_RIGHT.value:
            if parent is None:
                return
            parent1 = parent.GetNext()
            focus = parent1.GetFocus()
            if focus is None:
                return
            focus.Focus()

        elif keyId == Key.FOCUS_PARENT_LEFT.value:
            if parent is None:
                return
            parent1 = parent.GetPrev()
            focus = parent1.GetFocus()
            if focus is None:
                return
            focus.Focus()

        elif keyId == Key.YANK_CONTAINER.value:
            print("yanking container...")
            self.yank = {focus}

        elif keyId == Key.YANK_APPEND_CONTAINER.value:
            print("yanking container (append)...")
            try:
                self.yank.add(focus)
            except AttributeError:
                self.yank = {focus}

        elif keyId == Key.PASTE_CONTAINER.value:
            print("pasting container...")
            try:
                if focus in self.yank:
                    print(
                        "cannot paste on selection (one of the yanked containers)."
                    )
                    self.yank.remove(focus)
                peers = list(self.yank)

                focus1 = focus.GetFocus()
                peers[0].Move(focus)
                #warning! need to know wether yank is still alive

                if focus1 is None:
                    focus = focus.GetParent()
                for peer in peers[1:]:
                    peer.Move(focus)

            except (AttributeError, IndexError):
                print("no containers to paste.")

        elif keyId == Key.LIFT_CONTAINER.value:
            sibling = focus.GetNext()
            peer = sibling.GetNext()
            if peer is not focus:
                sibling = peer.Place(sibling)

                peer = sibling.GetNext()
                while peer is not focus:
                    peer1 = peer.GetNext()
                    peer.Move(sibling)
                    peer = peer1

        elif keyId == Key.LAYOUT.value:
            if parent is None:
                return
            layout = {
                chamfer.layout.VSPLIT: chamfer.layout.HSPLIT,
                chamfer.layout.HSPLIT: chamfer.layout.VSPLIT
            }[parent.layout]
            parent.ShiftLayout(layout)

        elif keyId == Key.SPLIT_V.value:
            #TODO: add render flags property, bitwise OR them
            print("split armed.")
            focus.splitArmed = not focus.splitArmed

        elif keyId == Key.FULLSCREEN.value:
            print("setting fullscreen")
            focus.SetFullscreen(not focus.fullscreen)

        elif keyId == Key.CONTRACT_ROOT_RESET.value:
            root = self.GetRoot()
            root.canvasOffset = (0.0, 0.0)
            root.canvasExtent = (0.0, 0.0)
            root.ShiftLayout(root.layout)

        elif keyId == Key.CONTRACT_ROOT_LEFT.value:
            root = self.GetRoot()
            root.canvasOffset = (root.canvasOffset[0] + 0.1,
                                 root.canvasOffset[1])
            root.canvasExtent = (root.canvasExtent[0] + 0.1,
                                 root.canvasExtent[1])
            #root.canvasOffset;
            root.ShiftLayout(root.layout)

        elif keyId == Key.CONTRACT_ROOT_RIGHT.value:
            root = self.GetRoot()
            root.canvasExtent = (root.canvasExtent[0] + 0.1,
                                 root.canvasExtent[1])
            root.ShiftLayout(root.layout)

        elif keyId == Key.EXPAND_ROOT_LEFT.value:
            root = self.GetRoot()
            root.canvasOffset = (root.canvasOffset[0] - 0.1,
                                 root.canvasOffset[1])
            root.canvasExtent = (root.canvasExtent[0] - 0.1,
                                 root.canvasExtent[1])
            root.ShiftLayout(root.layout)

        elif keyId == Key.EXPAND_ROOT_RIGHT.value:
            root = self.GetRoot()
            root.canvasExtent = (root.canvasExtent[0] - 0.1,
                                 root.canvasExtent[1])
            root.ShiftLayout(root.layout)

        elif keyId == Key.CONTRACT_RESET.value:
            focus.canvasOffset = (0.0, 0.0)
            focus.canvasExtent = (0.0, 0.0)
            focus.ShiftLayout(focus.layout)

        elif keyId == Key.CONTRACT_HORIZONTAL.value:
            focus.canvasOffset = (focus.canvasOffset[0] + 0.05,
                                  focus.canvasOffset[1])
            focus.canvasExtent = (focus.canvasExtent[0] + 0.10,
                                  focus.canvasExtent[1])
            focus.ShiftLayout(focus.layout)

        elif keyId == Key.CONTRACT_VERTICAL.value:
            focus.canvasOffset = (focus.canvasOffset[0],
                                  focus.canvasOffset[1] + 0.05)
            focus.canvasExtent = (focus.canvasExtent[0],
                                  focus.canvasExtent[1] + 0.10)
            focus.ShiftLayout(focus.layout)

        elif keyId == Key.EXPAND_HORIZONTAL.value:
            focus.canvasOffset = (focus.canvasOffset[0] - 0.05,
                                  focus.canvasOffset[1])
            focus.canvasExtent = (focus.canvasExtent[0] - 0.10,
                                  focus.canvasExtent[1])
            focus.ShiftLayout(focus.layout)

        elif keyId == Key.EXPAND_VERTICAL.value:
            focus.canvasOffset = (focus.canvasOffset[0],
                                  focus.canvasOffset[1] - 0.05)
            focus.canvasExtent = (focus.canvasExtent[0],
                                  focus.canvasExtent[1] - 0.10)
            focus.ShiftLayout(focus.layout)

        elif keyId == Key.KILL.value:
            focus.Kill()

        elif keyId == Key.LAUNCH_TERMINAL.value:
            psutil.Popen(["termite"], stdout=None, stderr=None)

        elif keyId == Key.LAUNCH_BROWSER.value:
            psutil.Popen(["firefox"], stdout=None, stderr=None)

        elif keyId == Key.LAUNCH_BROWSER_PRIVATE.value:
            psutil.Popen(["firefox", "--private-window"],
                         stdout=None,
                         stderr=None)

        elif keyId == Key.AUDIO_VOLUME_UP.value:
            if "pulsectl" in sys.modules:
                with pulsectl.Pulse('volume-increaser') as pulse:
                    for sink in pulse.sink_list():
                        pulse.volume_change_all_chans(sink, 0.05)

        elif keyId == Key.AUDIO_VOLUME_DOWN.value:
            if "pulsectl" in sys.modules:
                with pulsectl.Pulse('volume-increaser') as pulse:
                    for sink in pulse.sink_list():
                        pulse.volume_change_all_chans(sink, -0.05)

        elif keyId == Key.MONITOR_BRIGHTNESS_UP.value:
            psutil.Popen(["xbacklight", "-inc", "20"])

        elif keyId == Key.MONITOR_BRIGHTNESS_DOWN.value:
            psutil.Popen(["xbacklight", "-dec", "20"])
示例#14
0
weekdays = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]


def time():
    today = datetime.datetime.today()
    now = datetime.datetime.now()
    time_string = weekdays[today.weekday()] + " {:%H:%M}".format(now)
    text = time_string

    t = (now.hour * 60 + now.minute) / 60
    fade_value = -t * (t - 24) / 144  #Parabola
    bg_color = lerp_as_hsv(colors["yellow"], colors["red"], fade_value)
    return section(text, bg_color)


pulse = pulsectl.Pulse("lemonbar", threading_lock=True)


def volume():
    sink = pulse.sink_list()[0]
    if sink.mute:
        text = "MUTE"
        fade_value = 0.0
    else:
        vol = round(sink.volume.value_flat * 100)
        text = "VOL {}%".format(vol)
        fade_value = (vol / 100)**2

    bg_color = lerp_as_hsv(colors["dark_blue"], colors["yellow"], fade_value)
    return section(text, bg_color)
	def test_connect(self):
		with pulsectl.Pulse('t', server=self.sock_unix) as pulse: si = pulse.server_info()
		with pulsectl.Pulse('t', server=self.sock_tcp4) as pulse: si4 = pulse.server_info()
		self.assertEqual(vars(si), vars(si4))
		with pulsectl.Pulse('t', server=self.sock_tcp6) as pulse: si6 = pulse.server_info()
		self.assertEqual(vars(si), vars(si6))
示例#16
0
import pulsectl
pulse = pulsectl.Pulse('pulsepy')

preferred_output = [
    "CalDigit Thunderbolt 3 Audio Analogue Stereo",
    "Built-in Audio Analogue Stereo"
]

preferred_input = [
    "RØDE VideoMic NTG Analogue Stereo",
    "CalDigit Thunderbolt 3 Audio Analogue Stereo",
    "Built-in Audio Analogue Stereo"
]

outputs = {}
inputs = {}

for sink in pulse.sink_list():
    outputs[sink.description] = sink

for source in pulse.source_list():
    inputs[source.description] = source

for s in preferred_output:
    if s in outputs:
        pulse.sink_default_set(outputs[s])
        print("Sink set to '" + s + "'")
        break

for s in preferred_input:
    if s in inputs:
	def test_server_info(self):
		with pulsectl.Pulse('t', server=self.sock_unix) as pulse:
			si, srcs, sinks = pulse.server_info(), pulse.source_list(), pulse.sink_list()
		self.assertEqual(len(srcs), 2)
		self.assertEqual(len(sinks), 2)
示例#18
0
import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction, QWidget, QWidgetAction, QSlider
from PyQt5.QtCore import Qt
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from shutil import copyfile
import contextlib
import os
import pulsectl

pulse = pulsectl.Pulse("t")


class CadmusPulseInterface:
    @staticmethod
    def cli_command(command):
        if not isinstance(command, list):
            command = [command]
        with contextlib.closing(pulsectl.connect_to_cli()) as s:
            for c in command:
                s.write(c + "\n")

    @staticmethod
    def load_modules(mic_name, mic_rate, cadmus_lib_path):
        print(mic_name)
        print(mic_rate)
        print(cadmus_lib_path)

        pulse.module_load(
            "module-null-sink",
	def test_get_sink_src(self):
		with pulsectl.Pulse('t', server=self.sock_unix) as pulse:
			src, sink = pulse.source_list()[0], pulse.sink_list()[0]
			self.assertEqual(sink.index, pulse.get_sink_by_name(sink.name).index)
			self.assertEqual(src.index, pulse.get_source_by_name(src.name).index)
示例#20
0
def run_gui():
    with pulsectl.Pulse("pulseaudio-loopback-tool") as pulseaudio:
        palt_gui = PaltGui(pulseaudio)
        palt_gui.run_gui()
示例#21
0
    def processCommand(self, command, x, url, number):
        msg = "Unknown command"
        longMsg = None

        if command == "power off":
            if self.can_poweroff():
                self.ioloop.add_timeout(datetime.timedelta(seconds=3),
                                        self.cmd_poweroff)
                msg = "Powering off"
            else:
                msg = "Cannot power off"
        elif command == "sleep":
            if self.can_sleep():
                self.ioloop.add_timeout(datetime.timedelta(seconds=3),
                                        self.cmd_sleep)
                msg = "Sleeping"
            else:
                msg = "Cannot sleep"
        elif command == "reboot":
            if self.can_reboot():
                self.ioloop.add_timeout(datetime.timedelta(seconds=3),
                                        self.cmd_reboot)
                msg = "Rebooting"
            else:
                msg = "Cannot reboot"
        elif command == "lock":
            self.cmd_lock()
            msg = "Locking"
        elif command == "unlock":
            self.cmd_unlock()
            msg = "Unlocking"
        elif command == "open":
            if x:
                results = yield self.cmd_findApp(x.strip().lower())

                if len(results) > 0:
                    fn = results[0][7:]  # remove file://
                    name = yield self.getAppName(fn)
                    if name:
                        msg = "Opening " + name
                        longMsg = "Opening " + name + ": " + fn
                    else:
                        msg = "Opening"
                        longMsg = "Opening " + fn
                    self.ioloop.add_callback(
                        lambda: self.cmd_openApp(fn, name))
                else:
                    msg = "No results found"
            else:
                msg = "Missing program to start"
        elif command == "close":
            msg = "Not implemented yet"
        elif command == "kill":
            msg = "Not implemented yet"
        elif command == "locate":
            if x:
                # Search might be slow
                try:
                    results = yield tornado.gen.with_timeout(
                        datetime.timedelta(seconds=3.5), self.cmd_locateDB(x))
                except tornado.gen.TimeoutError:
                    msg = "Timed out"
                else:
                    self.locateResults = {}

                    if results:
                        msg = "Found " + str(len(results)) + " results"
                        longMsg = "Results:\n"

                        for i, r in enumerate(results):
                            self.locateResults[i + 1] = url_unescape(r)
                            longMsg += str(i + 1) + ") " + r + "\n"
                    else:
                        msg = "No results found"
            else:
                msg = "Missing search query"

        elif command == "fetch":
            if number:
                try:
                    item = int(re.search(r'\d+', number).group())
                except ValueError:
                    msg = "Invalid item number: " + number
                except AttributeError:
                    msg = "Invalid item number: " + number
                else:
                    if item in self.locateResults:
                        # Input filename, what we saved from the locate command
                        inputFile = self.locateResults[item]

                        # Output filename
                        ext = os.path.splitext(inputFile)[-1]
                        fn = datetime.datetime.now().strftime(
                            "LinuxControl-Fetch-%Y-%m-%d-%Hh-%Mm-%Ss") + ext
                        outputFile = os.path.join(os.environ["HOME"],
                                                  "Dropbox", fn)

                        msg = "Fetching item " + str(item)
                        longMsg = "Fetching item "+str(item)+": copying"+ \
                            inputFile+" to "+outputFile
                        self.ioloop.add_callback(
                            lambda: self.cmd_fetchFile(inputFile, outputFile))
                    else:
                        msg = "Item not found in last locate results"
            else:
                msg = "Please specify which item of your locate command to fetch."
        elif command == "set volume":
            if number:
                try:
                    volume = int(re.search(r'\d+', number).group())
                except ValueError:
                    msg = "Invalid percentage: " + number
                except AttributeError:
                    msg = "Invalid percentage: " + number
                else:
                    with pulsectl.Pulse('setting-volume') as pulse:
                        for sink in pulse.sink_list():
                            pulse.volume_set_all_chans(sink, volume / 100.0)
                    msg = "Volume set"
                    longMsg = "Volume set to " + str(volume) + "%"
            else:
                msg = "Please specify volume percentage"
        elif command == "stop":
            msg = "Not implemented yet"
        elif command == "take a picture":
            filename = os.path.join(
                os.environ["HOME"], "Dropbox",
                datetime.datetime.now().strftime(
                    "LinuxControl-Picture-%Y-%m-%d-%Hh-%Mm-%Ss.png"))
            msg = "Taking picture, saving in Dropbox"
            longMsg = "Taking picture: " + filename
            self.ioloop.add_callback(lambda: self.cmd_image(filename))
        elif command == "screenshot":
            filename = os.path.join(
                os.environ["HOME"], "Dropbox",
                datetime.datetime.now().strftime(
                    "LinuxControl-Screenshot-%Y-%m-%d-%Hh-%Mm-%Ss.png"))
            msg = "Taking screenshot, saving in Dropbox"
            longMsg = "Taking screenshot: " + filename
            self.ioloop.add_callback(lambda: self.cmd_screenshot(filename))
        elif command == "download":
            msg = "Not implemented yet"
        elif command == "start recording":
            msg = "Not implemented yet"
        elif command == "stop recording":
            msg = "Not implemented yet"

        return msg, longMsg
示例#22
0
def mic_set():
    print(
        '-------------------------------------------------------------------')
    print("[SETUP_MIC_SPEAKER] - THIẾT LẬP MICROPHONE VÀ MIC")
    try:
        os.system('sudo apt-get install -y -qq python3-pip >> /dev/null')
    except:
        pass
    if platform.machine() == 'x86':
        m = os.system(
            'sudo apt-get install -y -qq libpulse0:i386 >> /dev/null')
    elif platform.machine() == 'armv7l':
        n = os.system('sudo apt-get install -y -qq  libpulse0>> /dev/null')
    try:
        import pulsectl
    except:
        pass
    import pulsectl
    os.system('killall pulseaudio')
    os.system('sudo killall pulseaudio')
    os.system('pulseaudio --start')
    time.sleep(1)
    pulse = pulsectl.Pulse('my-client')
    blist = pulse.source_list()
    ee = len(blist)
    slist = pulse.sink_list()
    ss = len(slist)
    #	print(blist)
    print('')
    print("ĐANG NHẬN DIỆN MICROPHONE...")
    print('')
    time.sleep(0.7)
    for i in range(0, ee):
        print('MIC ' + str(i) + ' :' + blist[i].name)
        if 'OmniVision' in blist[i].name:
            source = blist[i].name
            print(
                '------------------->>>MIC ARRAY SONY PS3<<<--------------------------'
            )
        elif 'mono' in blist[i].name and 'input' in blist[
                i].name and 'monitor' not in blist[i].name:
            source = blist[i].name
            print(
                '------------------------->>>MIC USB<<<-----------------------------'
            )
        elif 'input' in blist[i].name and 'monitor' not in blist[i].name:
            source = blist[i].name
            print(
                '------------------------->>>MIC KHÁC<<<-----------------------------'
            )
        else:
            source = blist[0].name
        time.sleep(0.7)
#			print ('KHÔNG RÕ LOẠI MIC BẠN ĐANG SỬ DỤNG HOẶC BẠN QUÊN CHƯA GẮN MIC')
#		iii = input('NHẬP TÊN MIC BẠN SỬ DỤNG (TỐT NHẤT LÀ BÔI ĐEN ĐOẠN TÊN BÊN TRÊN): ')
#		source = str(iii)
    print("--->>>XONG")
    print('')
    time.sleep(1)
    print("THIẾT LẬP MẶC ĐỊNH CỔNG RA 3.5 PI...")
    print('')
    # time.sleep(0.7)
    for j in range(0, ss):
        print('OUTPUT LIST: ' + str(j) + ' LÀ THIẾT BỊ ' +
              slist[j].description)
        if 'USB' in slist[j].description and 'output' in slist[j].name:
            sink = slist[j].index
            print('ĐẦU RA USB SOUND')
        elif 'Analog Stereo' in slist[j].description and 'output' in slist[
                j].name and 'fallback' not in slist[j].name:
            sink = slist[j].index
            print('ĐẦU RA 3.5 PI')
        else:
            sink = slist[0].index
        print('CÁC ĐẦU RA KHÁC VUI LÒNG QUAN SÁT VÀ CÀI ĐẶT THỦ CÔNG')


#			sss = input('NHẬP SỐ THỨ TỰ OUTPUT LIST: ')
#			sink = int(sss)
# time.sleep(0.7)
#	os.system('amixer cset numid=3 1')
    print("--->>>XONG")
    print('')
    time.sleep(1)
    if str(source) != '':
        os.system('pacmd set-default-source ' + str(source))
        os.system('pactl set-source-volume 0 80%')
    if str(sink) != '':
        os.system('pacmd set-default-sink ' + str(sink))
        os.system('pactl set-sink-volume 0 80%')
    print('')
    print('NẾU MIC KHÔNG HOẠT ĐỘNG HÃY DÙNG LỆNH DƯỚI ĐÂY. LƯU Ý ĐÚNG TÊN MIC')
    print('')
    print(
        'pacmd set-default-source tên_mic, ví dụ: pacmd set-default-source ' +
        str(source))
    print('')
    print(
        'NẾU KHÔNG CÓ ÂM THANH PHÁT RA LOA. HÃY CÀI ĐẶT LẠI OUTPUT VỚI LỆNH: ')
    print(
        'pacmd set-default-sink + số_thứ_tự_sinklist, ví dụ:  pacmd set-default-sink '
        + str(sink))
    print('')
    #	i=0
    #	while i<5:
    #		try:
    #			i+=1
    #			if 'OmniVision' in blist[i].name:
    #				source_ps3 = blist[i].name
    #				with open('/etc/pulse/default.pa','a+') as pulsewrite:
    #					pulsewrite.writelines('set-default-source '+ str(source_ps3))
    #					print("Cài đặt mic PS3 làm mic mặc định")
    #				break
    #			elif 'mono' in blist[i].name:
    #				source_mono = blist[i].name
    #				with open('/etc/pulse/default.pa','a+') as pulsewrite:
    #					pulsewrite.writelines('set-default-source '+ str(source_mono))
    #					print("Cài đặt mic USB làm mic mặc định")
    #				break
    #		except:
    #			pass

    time.sleep(1)
    os.system('pacmd set-source-volume 1 120000')
    time.sleep(1)
    print('[SETUP] - KẾT THÚC SETUP BOT LBMINH')
    try:
        print('SỐ MODULE LỖI BƯỚC 1: ' + str(len(c)))
        print('SỐ MODULE LỖI BƯỚC 2: ' + str(len(d)))
        time.sleep(1)
        if len(c) == 0 and len(d) == 0:
            print('CHÚC MỪNG BẠN. CÀI ĐẶT THÀNH CÔNG')
            print(
                'VUI LÒNG THIẾT LẬP CẤU HÌNH TRONG FILE CONFIG.YAML TRƯỚC KHI DÙNG'
            )
            print(" ")
            print(
                "GÕ: 'python3 main.py' ĐỂ CHẠY THỦ CÔNG SAU KHI ĐÃ CẤU HÌNH XONG"
            )
            print(
                "GÕ: 'sudo systemctl start bot.service' ĐỂ KHỞI ĐỘNG BOT SAU 4 PHÚT"
            )
        else:
            print('VUI LÒNG CÀI LẠI CÁC MODULE LỖI')

    except:
        pass
示例#23
0
import sys

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from shutil import copyfile
import contextlib
import os
import pulsectl

pulse = pulsectl.Pulse('t')


class AudioMenuItem(QAction):
    def __init__(self, text, parent, disable_menu, mic_name, context):
        super().__init__(text, parent)
        self.mic_name = mic_name
        self.disable_menu = disable_menu
        self.context = context
        self.setStatusTip('Use the %s as an input for noise suppression' %
                          text)
        self.triggered.connect(
            lambda: enable_noise_suppression(self, self.context))


def cli_command(command):
    with contextlib.closing(pulsectl.connect_to_cli()) as s:
        s.write(command)


def load_modules(mic_name, context):