Esempio n. 1
0
async def main(connection):
    component = iterm2.StatusBarComponent(
        short_description='GitHub stars',
        detailed_description='How many stars a GitHub repository has',
        exemplar='some-user/project ★ 103',
        update_cadence=300,
        identifier='engineering.dane.iterm-components.github-stars',
        knobs=[
            iterm2.StringKnob('Repository', 'some-user/project', 'some-user/project', REPO_KNOB_NAME),
            iterm2.StringKnob('Personal access token', 'token value (optional, for rate limiting or private repos)', '', TOKEN_KNOB_NAME)
        ],
    )

    @iterm2.StatusBarRPC
    async def github_stars_coroutine(knobs):
        github_repo = knobs[REPO_KNOB_NAME]
        token = knobs[TOKEN_KNOB_NAME]
        info_url = f'https://api.github.com/repos/{github_repo}'

        try:
            request = urllib.request.Request(
                info_url,
                headers={'Authorization': f'token {token}'} if token else {},
            )
            stars = json.loads(
                urllib.request.urlopen(request).read().decode()
            )['stargazers_count']
            stars = human_number(stars)
        except:
            raise
        else:
            return f'{github_repo} ★ {stars}'

    await component.async_register(connection, github_stars_coroutine)
Esempio n. 2
0
async def main(connection):
    component = iterm2.StatusBarComponent(
        short_description='Execute a user defined command',
        detailed_description='A component that displays the output of an arbitrary command with an optional prefix',
        exemplar='> hello world',
        update_cadence=7,
        identifier='engineering.dane.iterm-components.generic-command',
        knobs=[
           iterm2.StringKnob('Script', 'echo "hello world"', '', SCRIPT),
           iterm2.StringKnob('Prefix', '>', '', PREFIX)
        ],
    )

    @iterm2.StatusBarRPC
    async def generic_command_coroutine(knobs):
        proc = await asyncio.create_subprocess_shell(
            knobs[SCRIPT],
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        stdout, stderr = await proc.communicate()
        prefix = knobs[PREFIX]
        prefix = f'{prefix} ' if prefix else ''
        return f'{prefix}{stdout.decode().strip()}' if not stderr else 'Command failed!'

    await component.async_register(connection, generic_command_coroutine)
Esempio n. 3
0
async def main(connection):
    app = await iterm2.async_get_app(connection)
    # Start fetching the URL
    asyncio.create_task(updater(app, type='current'))
    asyncio.create_task(updater(app, type='forecast'))

    location_knob = "weather_location"
    update_interval_knob = "weather_update_interval"
    knobs = [
        iterm2.StringKnob("Location", "Hangzhou", "Hangzhou", location_knob),
        iterm2.StringKnob("Update Interval", "60", "60", update_interval_knob)
    ]

    # icon1x = iterm2.StatusBarComponent.Icon(1, ICON1X)
    # icon2x = iterm2.StatusBarComponent.Icon(2, ICON2X)

    # Register the status bar component.
    component = iterm2.StatusBarComponent(
        short_description="Weather",
        detailed_description="Shows your local weather",
        knobs=knobs,
        exemplar="☁️Weather",
        update_cadence=None,
        identifier="catj.moe.weather")

    @iterm2.StatusBarRPC
    async def weather(knobs,
                      value=iterm2.Reference("iterm2.user." +
                                             CURRENT_VARIABLE + "?")):
        """This function returns the value to show in a status bar."""
        global city
        global update_interval
        if location_knob in knobs and knobs[location_knob]:
            city = knobs[location_knob]
        if update_interval_knob in knobs and knobs[update_interval_knob]:
            update_interval = int(knobs[update_interval_knob])

        if value:
            return value
        return "Loading…"

    @iterm2.RPC
    async def onclick(session_id):
        session = app.get_session_by_id(session_id)
        forecast_weather = "Loading"
        try:
            forecast_weather = await format_weather(app)
        except:
            forecast_weather = "Loading"
        if forecast_weather is not None:
            await component.async_open_popover(session_id, forecast_weather,
                                               iterm2.util.Size(480, 520))

    # Register the component.
    await component.async_register(connection, weather, onclick=onclick)
Esempio n. 4
0
async def main(connection):
    api_key = "atlas_api_key"
    knobs = [iterm2.StringKnob("API key", "API KEY", "", api_key)]
    component = iterm2.StatusBarComponent(
        short_description="RIPE Atlas Credits",
        detailed_description="Shows credits balance at atlas.ripe.net",
        knobs=knobs,
        exemplar="0.0 / 34,000.0 / 4,000,000.0",
        update_cadence=300,
        identifier="com.iterm2.example.status-bar")

    @iterm2.StatusBarRPC
    async def coro(knobs):
        URL = 'https://atlas.ripe.net/api/v2/credits/'
        PARAMS = {'key': knobs[api_key]}
        try:
            r = requests.get(url=URL, params=PARAMS)
            data = r.json()
            daily = data['estimated_daily_income']
            total = data['current_balance']
            expenditure = data['estimated_daily_expenditure']
        except:
            raise
        else:
            return f'{float(expenditure):,.1f} / {float(daily):,.1f} / {float(total):,.1f}'

    await component.async_register(connection, coro)
async def main(connection):
    fmt = 'fmt'
    default_fmt = '%m/%d %a %H:%M:%S'
    knobs = [
        iterm2.StringKnob(name='format',
                          placeholder=default_fmt,
                          default_value=default_fmt,
                          key=fmt)
    ]
    component = iterm2.StatusBarComponent(
        short_description='Clock',
        detailed_description='A customized clock.',
        knobs=knobs,
        exemplar=' 08/03 Sat 01:56:48',
        update_cadence=1,
        identifier='peinan.clock')

    @iterm2.StatusBarRPC
    async def clock(knobs):
        n = datetime.now()
        clock_char = ''
        if fmt in knobs and knobs[fmt]:
            clock_face = f'{clock_char} {n.strftime(knobs[fmt])}'
        else:
            clock_face = f'{clock_char} {n.strftime(default_fmt)}'

        return clock_face

    await component.async_register(connection, clock)
Esempio n. 6
0
async def main(connection):
    knob_icons = KnobOption('icons', '')
    knob_free = KnobOption('free', True)
    knob_usedtotal = KnobOption('usedtotal', True)
    knob_usedpercent = KnobOption('usedpercent', True)
    knobs = [
        iterm2.StringKnob(name='Icons',
                          default_value=knob_icons.v,
                          placeholder=knob_icons.v,
                          key=knob_icons.name),
        iterm2.CheckboxKnob(name='Show Free Space',
                            default_value=knob_free.v,
                            key=knob_free.name),
        iterm2.CheckboxKnob(name='Show Used/Total Space',
                            default_value=knob_usedtotal.v,
                            key=knob_usedtotal.name),
        iterm2.CheckboxKnob(name='Show Used Space (%)',
                            default_value=knob_usedpercent.v,
                            key=knob_usedpercent.name),
    ]

    component = iterm2.StatusBarComponent(
        short_description='Disk Usage',
        detailed_description='Display the usage of disk.',
        knobs=knobs,
        exemplar=' 44.1 GB  179.7/233.5 GB (81.0%)',
        update_cadence=2,
        identifier='peinan.diskusage')

    def is_true_knob(knobs, knob_option: KnobOption):
        return knob_option.name in knobs and knobs[knob_option.name]

    @iterm2.StatusBarRPC
    async def diskusage(knobs):
        true_icons = is_true_knob(knobs, knob_icons)
        true_free = is_true_knob(knobs, knob_free)
        true_usedtotal = is_true_knob(knobs, knob_usedtotal)
        true_usedpercent = is_true_knob(knobs, knob_usedpercent)

        char_header = knobs[knob_icons.name][0] if true_icons else ''
        char_usedtotal = f' {knobs[knob_icons.name][-1]}' if true_icons and true_free and true_usedtotal else ''
        disk = shutil.disk_usage('/')
        unit = sizeof_fmt(disk.total)[1]

        v_free = f' {" ".join(sizeof_fmt(disk.free))}' if true_free else ''
        v_usedtotal = f' {sizeof_fmt(disk.used)[0]}/{sizeof_fmt(disk.total)[0]} {unit}' if true_usedtotal else ''
        v_usedp = f' ({100 * disk.used / disk.total:.1f}%)' if (true_free or true_usedtotal) and true_usedpercent\
                  else f' {100 * disk.used / disk.total:.1f}%' if true_usedpercent else ''

        usage = f'{char_header}{v_free}{char_usedtotal}{v_usedtotal}{v_usedp}'

        return usage

    await component.async_register(connection, diskusage)
Esempio n. 7
0
async def main(connection, update_cadence=5):

    # configure iTerm2 status bar interface
    knobs = [iterm2.StringKnob("CPU Temperature", "N/A", "", "CPU")]
    component = iterm2.StatusBarComponent(
        short_description="CPU temperature",
        detailed_description=
        "Reads CPU temperature at a specified refresh rate",
        knobs=knobs,
        exemplar="48.8°C",
        update_cadence=update_cadence,
        identifier="com.github.sheatsley.temperature",
    )

    @iterm2.StatusBarRPC
    async def temperature_component(knobs):
        return check_output("/usr/local/bin/osx-cpu-temp",
                            encoding="utf-8").strip()

    await component.async_register(connection, temperature_component)
Esempio n. 8
0
async def main(connection):
    component = iterm2.StatusBarComponent(
        short_description='Environment variable',
        detailed_description=
        'Show the current value of an environment variable',
        exemplar='SOME_ENV_VAR=foo',
        update_cadence=3,
        identifier='engineering.dane.iterm-components.environment-variable',
        knobs=[
            iterm2.StringKnob('Variable name', 'SOME_ENV_VAR', 'SOME_ENV_VAR',
                              ENV_VAR_KNOB_NAME),
            iterm2.CheckboxKnob('Show variable name', True,
                                SHOW_NAME_KNOB_NAME)
        ],
    )

    @iterm2.StatusBarRPC
    async def env_var_coroutine(knobs):
        env_var_name = knobs[ENV_VAR_KNOB_NAME]
        show_name = knobs[SHOW_NAME_KNOB_NAME]
        prefix = f'{env_var_name}=' if show_name else ''
        return f'{prefix}{os.getenv(env_var_name, "")}'

    await component.async_register(connection, env_var_coroutine)
async def main(connection):
    app = await iterm2.async_get_app(connection)
    icon = iterm2.StatusBarComponent.Icon(1, ICON)
    icon2x = iterm2.StatusBarComponent.Icon(2, ICON2X)

    # Register the status bar component
    # The username and bearer token are configurable values
    component = iterm2.StatusBarComponent(
        short_description='Twitter followers',
        detailed_description='Shows count of Twitter followers',
        exemplar='3401',
        update_cadence=600,
        identifier='andypiper.iterm-twitter-info.user-count',
        knobs=[
            iterm2.StringKnob('Twitter user', 'username', 'twitterdev',
                              USER_KNOB_NAME),
            iterm2.StringKnob('Bearer token', 'bearer token value', 'xxxxxx',
                              TOKEN_KNOB_NAME)
        ],
        icons=[icon, icon2x])

    @iterm2.StatusBarRPC
    async def twitter_user_count(knobs):
        twitter_user = knobs[USER_KNOB_NAME]
        token = knobs[TOKEN_KNOB_NAME]

        # we need to put the username into a session variable to pass to the click handler
        try:
            session = app.current_terminal_window.current_tab.current_session
        except Exception:
            return

        await session.async_set_variable("user.twitter_user", twitter_user)

        # this is the API endpoint to get user data, with metrics requested
        user_url = f'https://api.twitter.com/2/users/by/username/{twitter_user}?user.fields=public_metrics'

        try:
            request = urllib.request.Request(
                user_url,
                headers={'Authorization': f'Bearer {token}'} if token else {},
            )
            followers = json.loads(
                urllib.request.urlopen(request).read().decode()
            )['data']['public_metrics']['followers_count']
            return f'{followers}'
        except Exception:
            raise
        else:
            return f'{followers}'

    @iterm2.RPC
    async def onclick(session_id):
        try:
            session = app.current_terminal_window.current_tab.current_session
        except Exception:
            return

        # grab the username from the session user variable
        twitter_user = await session.async_get_variable("user.twitter_user")

        # open a browser window to the Twitter user profile
        proc = await asyncio.create_subprocess_shell(
            f'open https://twitter.com/{twitter_user}',
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        stdout, stderr = await proc.communicate()

    await component.async_register(connection,
                                   twitter_user_count,
                                   onclick=onclick)
Esempio n. 10
0
async def main(connection):
    knobs = [
        iterm2.StringKnob("OpenWeatherMap API key", "API_KEY", "", API_KEY),
        iterm2.StringKnob("Location name", "LOCATION_NAME", "", LOCATION_NAME),
        iterm2.CheckboxKnob("Add Humidity", False, HUMIDITY),
        iterm2.CheckboxKnob("Add Pressure", False, PRESSURE),
        iterm2.CheckboxKnob("Add Max Temperatur", False, MAX_TEMPERTUR),
        iterm2.CheckboxKnob("Add Min Temperatur", False, MIN_TEMPERTUR)
    ]
    component = iterm2.StatusBarComponent(
        short_description="Weather",
        detailed_description="This is weather status bar",
        knobs=knobs,
        exemplar="18℃ 🌙",
        update_cadence=50,
        identifier="take.weather")

    # request api
    def request_api(api_key, location):
        url = API_URL.format(location, api_key)
        response = requests.get(url)
        forecast_data = json.loads(response.text)
        if response.status_code == 401:
            return forecast_data
        elif response.status_code == 404:
            return forecast_data

        return forecast_data

    # get icon
    def get_icon(icon_id):

        if icon_id == "01d":
            return "☀️"
        elif icon_id == "01n":
            return "🌙"
        elif icon_id == "02d" or icon_id == "02n" or icon_id == "03d" or icon_id == "03n" or icon_id == "04d" or icon_id == "04n":
            return "☁️"
        elif icon_id == "09d" or icon_id == "09n":
            return "🌧"
        elif icon_id == "10d" or icon_id == "10n":
            return "☔️"
        elif icon_id == "11d" or icon_id == "11n":
            return "⚡️"
        elif icon_id == "13d" or icon_id == "13n":
            return "❄️"
        elif icon_id == "50d" or icon_id == "50n":
            return "🌫️"

    # status result
    def result_status(forecast_data, config):
        degree = forecast_data["main"]["temp"]
        icon = get_icon(forecast_data["weather"][0]["icon"])
        status = "{0}℃ {1}".format(degree, icon)

        if config["humidity"]:
            humidity = forecast_data["main"]["humidity"]
            status = status + " H:{0}%".format(humidity)
        if config["pressure"]:
            pressure = forecast_data["main"]["pressure"]
            status = status + " P:{0}".format(pressure)
        if config["max_temp"]:
            max_temp = forecast_data["main"]["temp_max"]
            status = status + " HT:{0}".format(max_temp)
        if config["min_temp"]:
            min_temp = forecast_data["main"]["temp_min"]
            status = status + " LT:{0}".format(min_temp)

        return status

    # checkbox info
    def get_checkbox_config(knobs):
        humidity = knobs[HUMIDITY]
        pressure = knobs[PRESSURE]
        max_temp = knobs[MAX_TEMPERTUR]
        min_temp = knobs[MIN_TEMPERTUR]

        config = {
            "humidity": humidity,
            "pressure": pressure,
            "max_temp": max_temp,
            "min_temp": min_temp
        }

        return config

    @iterm2.StatusBarRPC
    async def weather_component(knobs):
        # global variable
        global counter
        global status
        global forecast_data
        global time

        api_key = knobs[API_KEY]
        location = knobs[LOCATION_NAME]

        if not api_key:
            return "Please set API key"

        if not location:
            return "Please set location name"

        if counter == 0:
            # first excute
            config = get_checkbox_config(knobs)
            forecast_data = request_api(api_key, location)
            print(type(forecast_data["cod"]))
            print(forecast_data["cod"])

            if forecast_data["cod"] == 401:
                return "Invalid API key"
            elif forecast_data["cod"] == "404":
                return forecast_data["message"]

            status = result_status(forecast_data, config)
            time = datetime.datetime.now()
            counter += 1

        else:
            now_time = datetime.datetime.now()
            delta = now_time - time
            config = get_checkbox_config(knobs)
            status = result_status(forecast_data, config)

            # api reuest time 10m
            if int(delta.total_seconds()) > 600:
                delta = now_time - time
                config = get_checkbox_config(knobs)
                forecast_data = request_api(api_key, location)

                if forecast_data["cod"] == 401:
                    return "Invalid API key"
                elif forecast_data["cod"] == "404":
                    return forecast_data["message"]

                status = result_status(forecast_data, config)
                time = datetime.datetime.now()

        return status

    await component.async_register(connection, weather_component)
Esempio n. 11
0
async def main(connection):
    knob_city = KnobOption('city', 'Shibuya')
    knob_use_icon = KnobOption('use_icon', True)
    knob_use_imperial = KnobOption('use_imperial', False)
    knob_show_forecast = KnobOption('show_forecast', True)
    knobs = [
        iterm2.StringKnob('City', knob_city.v, knob_city.v, knob_city.name),
        iterm2.CheckboxKnob('Use icon', knob_use_icon.v, knob_use_icon.name),
        iterm2.CheckboxKnob('Show forecast', knob_show_forecast.v,
                            knob_show_forecast.name),
        iterm2.CheckboxKnob('Use imperial units', knob_use_imperial.v,
                            knob_use_imperial.name),
    ]

    component = iterm2.StatusBarComponent(
        short_description='Weather Info',
        detailed_description=
        'A component that will tell you the current weather and the forecast.',
        knobs=knobs,
        exemplar=' Clouds  27.1   Clear  30.2',
        update_cadence=60,
        identifier='peinan.weather')

    def have_log():
        return LOGFILE_PATH.exists()

    def is_refresh_time():
        return datetime.now().minute % 10 == 0

    def is_opt_modify(knobs):
        opt_set = {
            k.name
            for k in
            [knob_city, knob_use_icon, knob_use_imperial, knob_show_forecast]
        }
        if set(knobs.keys()) & opt_set == opt_set:
            return True
        return False

    def read_log():
        return json.load(LOGFILE_PATH.open())

    def write_log(city: str, use_icon: bool, units: str, show_forecast: bool,
                  weather_info: str):
        log_data = {
            'city': city,
            'use_icon': use_icon,
            'units': units,
            'show_forecast': show_forecast,
            'weather_info': weather_info
        }
        json.dump(log_data, LOGFILE_PATH.open('w'), ensure_ascii=False)

    def knob_value(knobs, option: KnobOption, default_value):
        """returns the option's value if the option is in the knob, otherwise returns False"""
        return knobs[option.name] if option.name in knobs else default_value

    @iterm2.StatusBarRPC
    async def weather_info(knobs):
        w.CITYNAME = knob_value(knobs, knob_city, 'Shibuya')
        w.UNITS = 'imperial' if knob_value(knobs, knob_use_imperial,
                                           False) else 'metric'
        use_icon = bool(knob_value(knobs, knob_use_icon, True))
        show_forecast = bool(knob_value(knobs, knob_show_forecast, True))

        ## for debug
        # print(f'knobs: {knobs}')
        # print(f'have log file: {have_log()}, is refresh time: {is_refresh_time()}')

        if have_log():
            log_data = read_log()
            opt_req = is_opt_modify(knobs)
            is_same_opt = w.CITYNAME == log_data['city'] and w.UNITS == log_data['units'] and \
                          use_icon == log_data['use_icon'] and show_forecast == log_data['show_forecast']

            # print(f'is knob option request: {opt_req}, is same knob options: {is_same_opt}')

            if not opt_req or (is_same_opt and not is_refresh_time()):
                # print(f'[application info] Use stored weather info: '
                #       f'city={w.CITYNAME}, units={w.UNITS}, use_icon={use_icon}, show_forecast={show_forecast}')
                return log_data['weather_info']

        print(f'[application info] Fetching weather: {knobs}')
        w.fetch_weather()
        w.parse_weather()
        weather_info = w.iterm_format(use_icon=use_icon,
                                      show_forecast=show_forecast)
        write_log(w.CITYNAME, use_icon, w.UNITS, show_forecast, weather_info)

        return weather_info

    await component.async_register(connection, weather_info)