Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
68de299763
9 changed files with 213 additions and 20 deletions
|
@ -240,11 +240,16 @@ class Config(util.store.Store):
|
||||||
:param filename: path to the file to load
|
:param filename: path to the file to load
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def load_config(self, filename):
|
def load_config(self, filename, content=None):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename) or content != None:
|
||||||
log.info("loading {}".format(filename))
|
log.info("loading {}".format(filename))
|
||||||
tmp = RawConfigParser()
|
tmp = RawConfigParser()
|
||||||
tmp.read(u"{}".format(filename))
|
tmp.optionxform = str
|
||||||
|
|
||||||
|
if content:
|
||||||
|
tmp.read_string(content)
|
||||||
|
else:
|
||||||
|
tmp.read(u"{}".format(filename))
|
||||||
|
|
||||||
if tmp.has_section("module-parameters"):
|
if tmp.has_section("module-parameters"):
|
||||||
for key, value in tmp.items("module-parameters"):
|
for key, value in tmp.items("module-parameters"):
|
||||||
|
|
|
@ -28,6 +28,8 @@ class Module(core.module.Module):
|
||||||
self.__states = {"unknown": ["unknown", "critical"],
|
self.__states = {"unknown": ["unknown", "critical"],
|
||||||
"true": ["muted", "warning"],
|
"true": ["muted", "warning"],
|
||||||
"false": ["unmuted"]}
|
"false": ["unmuted"]}
|
||||||
|
if util.format.asbool(self.parameter("disabled", False)):
|
||||||
|
util.cli.execute("dunstctl set-paused true", ignore_errors=True)
|
||||||
|
|
||||||
def toggle_state(self, event):
|
def toggle_state(self, event):
|
||||||
util.cli.execute("dunstctl set-paused toggle", ignore_errors=True)
|
util.cli.execute("dunstctl set-paused toggle", ignore_errors=True)
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Module(core.module.Module):
|
||||||
# if requested then run not async version and just execute command in this thread
|
# if requested then run not async version and just execute command in this thread
|
||||||
if not self.__async:
|
if not self.__async:
|
||||||
self.__output = util.cli.execute(self.__command, shell=True, ignore_errors=True).strip()
|
self.__output = util.cli.execute(self.__command, shell=True, ignore_errors=True).strip()
|
||||||
|
core.event.trigger("update", [self.id], redraw_only=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
# if previous thread didn't end yet then don't do anything
|
# if previous thread didn't end yet then don't do anything
|
||||||
|
|
|
@ -50,8 +50,9 @@ class Module(core.module.Module):
|
||||||
|
|
||||||
# create a connection with i3ipc
|
# create a connection with i3ipc
|
||||||
self.__i3 = i3ipc.Connection()
|
self.__i3 = i3ipc.Connection()
|
||||||
# event is called both on focus change and title change
|
# event is called both on focus change and title change, and on workspace change
|
||||||
self.__i3.on("window", lambda __p_i3, __p_e: self.__pollTitle())
|
self.__i3.on("window", lambda __p_i3, __p_e: self.__pollTitle())
|
||||||
|
self.__i3.on("workspace", lambda __p_i3, __p_e: self.__pollTitle())
|
||||||
# begin listening for events
|
# begin listening for events
|
||||||
threading.Thread(target=self.__i3.main).start()
|
threading.Thread(target=self.__i3.main).start()
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,8 @@ class Module(core.module.Module):
|
||||||
res = f"{res} {util.graph.hbar(self.__volume*100)}"
|
res = f"{res} {util.graph.hbar(self.__volume*100)}"
|
||||||
|
|
||||||
if self.__show_device_name:
|
if self.__show_device_name:
|
||||||
friendly_name = self.parameter(self.__devicename.lower(), self.__devicename)
|
friendly_name = self.parameter(self.__devicename, self.__devicename)
|
||||||
icon = self.parameter("icon." + self.__devicename.lower(), "")
|
icon = self.parameter("icon." + self.__devicename, "")
|
||||||
res = (
|
res = (
|
||||||
icon + " " + friendly_name + " | " + res
|
icon + " " + friendly_name + " | " + res
|
||||||
if icon != ""
|
if icon != ""
|
||||||
|
|
|
@ -52,7 +52,19 @@ def execute(
|
||||||
raise RuntimeError("{} not found".format(cmd))
|
raise RuntimeError("{} not found".format(cmd))
|
||||||
|
|
||||||
if wait:
|
if wait:
|
||||||
out, _ = proc.communicate()
|
timeout = 60
|
||||||
|
try:
|
||||||
|
out, _ = proc.communicate(timeout=timeout)
|
||||||
|
except subprocess.TimeoutExpired as e:
|
||||||
|
logging.warning(
|
||||||
|
f"""
|
||||||
|
Communication with process pid={proc.pid} hangs for more
|
||||||
|
than {timeout} seconds.
|
||||||
|
If this is not expected, the process is stale, or
|
||||||
|
you might have run in stdout / stderr deadlock.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
out, _ = proc.communicate()
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
err = "{} exited with code {}".format(cmd, proc.returncode)
|
err = "{} exited with code {}".format(cmd, proc.returncode)
|
||||||
logging.warning(err)
|
logging.warning(err)
|
||||||
|
|
|
@ -44,6 +44,14 @@ like this:
|
||||||
-t <theme>
|
-t <theme>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Line continuations (breaking a single line into multiple lines) is allowed in
|
||||||
|
the i3 configuration, but please ensure that all lines except the final one need to have a trailing
|
||||||
|
"\".
|
||||||
|
This is explained in detail here:
|
||||||
|
[i3 user guide: line continuation](https://i3wm.org/docs/userguide.html#line_continuation)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You can retrieve a list of modules (and their parameters) and themes by
|
You can retrieve a list of modules (and their parameters) and themes by
|
||||||
entering:
|
entering:
|
||||||
|
|
||||||
|
|
184
docs/modules.rst
184
docs/modules.rst
|
@ -264,6 +264,8 @@ Parameters:
|
||||||
* pulsectl.autostart: If set to 'true' (default is 'false'), automatically starts the pulsectl daemon if it is not running
|
* pulsectl.autostart: If set to 'true' (default is 'false'), automatically starts the pulsectl daemon if it is not running
|
||||||
* pulsectl.percent_change: How much to change volume by when scrolling on the module (default is 2%)
|
* pulsectl.percent_change: How much to change volume by when scrolling on the module (default is 2%)
|
||||||
* pulsectl.limit: Upper limit for setting the volume (default is 0%, which means 'no limit')
|
* pulsectl.limit: Upper limit for setting the volume (default is 0%, which means 'no limit')
|
||||||
|
* pulsectl.popup-filter: Comma-separated list of device strings (if the device name contains it) to exclude
|
||||||
|
from the default device popup menu (e.g. Monitor for sources)
|
||||||
* pulsectl.showbars: 'true' for showing volume bars, requires --markup=pango;
|
* pulsectl.showbars: 'true' for showing volume bars, requires --markup=pango;
|
||||||
'false' for not showing volume bars (default)
|
'false' for not showing volume bars (default)
|
||||||
* pulsectl.showdevicename: If set to 'true' (default is 'false'), the currently selected default device is shown.
|
* pulsectl.showdevicename: If set to 'true' (default is 'false'), the currently selected default device is shown.
|
||||||
|
@ -424,6 +426,7 @@ Requires the following executable:
|
||||||
* amixer
|
* amixer
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
* amixer.card: Sound Card to use (default is 0)
|
||||||
* amixer.device: Device to use (default is Master,0)
|
* amixer.device: Device to use (default is Master,0)
|
||||||
* amixer.percent_change: How much to change volume by when scrolling on the module (default is 4%)
|
* amixer.percent_change: How much to change volume by when scrolling on the module (default is 4%)
|
||||||
|
|
||||||
|
@ -431,6 +434,8 @@ contributed by `zetxx <https://github.com/zetxx>`_ - many thanks!
|
||||||
|
|
||||||
input handling contributed by `ardadem <https://github.com/ardadem>`_ - many thanks!
|
input handling contributed by `ardadem <https://github.com/ardadem>`_ - many thanks!
|
||||||
|
|
||||||
|
multiple audio cards contributed by `hugoeustaquio <https://github.com/hugoeustaquio>`_ - many thanks!
|
||||||
|
|
||||||
.. image:: ../screenshots/amixer.png
|
.. image:: ../screenshots/amixer.png
|
||||||
|
|
||||||
apt
|
apt
|
||||||
|
@ -685,6 +690,49 @@ lacking the aforementioned pattern settings or they have wrong values.
|
||||||
|
|
||||||
contributed by `somospocos <https://github.com/somospocos>`_ - many thanks!
|
contributed by `somospocos <https://github.com/somospocos>`_ - many thanks!
|
||||||
|
|
||||||
|
cpu3
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
Multiwidget CPU module
|
||||||
|
|
||||||
|
Can display any combination of:
|
||||||
|
|
||||||
|
* max CPU frequency
|
||||||
|
* total CPU load in percents (integer value)
|
||||||
|
* per-core CPU load as graph - either mono or colored
|
||||||
|
* CPU temperature (in Celsius degrees)
|
||||||
|
* CPU fan speed
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
* the psutil Python module for the first three items from the list above
|
||||||
|
* sensors executable for the rest
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* cpu3.layout: Space-separated list of widgets to add.
|
||||||
|
Possible widgets are:
|
||||||
|
|
||||||
|
* cpu3.maxfreq
|
||||||
|
* cpu3.cpuload
|
||||||
|
* cpu3.coresload
|
||||||
|
* cpu3.temp
|
||||||
|
* cpu3.fanspeed
|
||||||
|
* cpu3.colored: 1 for colored per core load graph, 0 for mono (default)
|
||||||
|
* cpu3.temp_json: json path to look for in the output of 'sensors -j';
|
||||||
|
required if cpu3.temp widget is used
|
||||||
|
* cpu3.fan_json: json path to look for in the output of 'sensors -j';
|
||||||
|
required if cpu3.fanspeed widget is used
|
||||||
|
|
||||||
|
Note: if you are getting 'n/a' for CPU temperature / fan speed, then you're
|
||||||
|
lacking the aforementioned json path settings or they have wrong values.
|
||||||
|
|
||||||
|
Example json paths:
|
||||||
|
* `cpu3.temp_json="coretemp-isa-0000.Package id 0.temp1_input"`
|
||||||
|
* `cpu3.fan_json="thinkpad-isa-0000.fan1.fan1_input"`
|
||||||
|
|
||||||
|
contributed by `SuperQ <https://github.com/SuperQ>`
|
||||||
|
based on cpu2 by `<somospocos <https://github.com/somospocos>`
|
||||||
|
|
||||||
currency
|
currency
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
|
@ -836,6 +884,9 @@ be running. Scripts will be executed when dunst gets unpaused.
|
||||||
Requires:
|
Requires:
|
||||||
* dunst v1.5.0+
|
* dunst v1.5.0+
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* dunstctl.disabled(Boolean): dunst state on start
|
||||||
|
|
||||||
contributed by `cristianmiranda <https://github.com/cristianmiranda>`_ - many thanks!
|
contributed by `cristianmiranda <https://github.com/cristianmiranda>`_ - many thanks!
|
||||||
contributed by `joachimmathes <https://github.com/joachimmathes>`_ - many thanks!
|
contributed by `joachimmathes <https://github.com/joachimmathes>`_ - many thanks!
|
||||||
|
|
||||||
|
@ -866,7 +917,9 @@ Displays first upcoming event in google calendar.
|
||||||
Events that are set as 'all-day' will not be shown.
|
Events that are set as 'all-day' will not be shown.
|
||||||
|
|
||||||
Requires credentials.json from a google api application where the google calendar api is installed.
|
Requires credentials.json from a google api application where the google calendar api is installed.
|
||||||
On first time run the browser will open and google will ask for permission for this app to access the google calendar and then save a .gcalendar_token.json file to the credentials_path directory which stores this permission.
|
On first time run the browser will open and google will ask for permission for this app to access
|
||||||
|
the google calendar and then save a .gcalendar_token.json file to the credentials_path directory
|
||||||
|
which stores this permission.
|
||||||
|
|
||||||
A refresh is done every 15 minutes.
|
A refresh is done every 15 minutes.
|
||||||
|
|
||||||
|
@ -878,7 +931,7 @@ Parameters:
|
||||||
|
|
||||||
Requires these pip packages:
|
Requires these pip packages:
|
||||||
* google-api-python-client >= 1.8.0
|
* google-api-python-client >= 1.8.0
|
||||||
* google-auth-httplib2
|
* google-auth-httplib2
|
||||||
* google-auth-oauthlib
|
* google-auth-oauthlib
|
||||||
|
|
||||||
getcrypto
|
getcrypto
|
||||||
|
@ -923,6 +976,29 @@ contributed by:
|
||||||
|
|
||||||
.. image:: ../screenshots/github.png
|
.. image:: ../screenshots/github.png
|
||||||
|
|
||||||
|
gitlab
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
Displays the GitLab todo count:
|
||||||
|
|
||||||
|
* https://docs.gitlab.com/ee/user/todos.html
|
||||||
|
* https://docs.gitlab.com/ee/api/todos.html
|
||||||
|
|
||||||
|
Uses `xdg-open` or `x-www-browser` to open web-pages.
|
||||||
|
|
||||||
|
Requires the following library:
|
||||||
|
* requests
|
||||||
|
|
||||||
|
Errors:
|
||||||
|
if the GitLab todo query failed, the shown value is `n/a`
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* gitlab.token: GitLab personal access token, the token needs to have the "read_api" scope.
|
||||||
|
* gitlab.host: Host of the GitLab instance, default is "gitlab.com".
|
||||||
|
* gitlab.actions: Comma separated actions to be parsed (e.g.: gitlab.actions=assigned,approval_required)
|
||||||
|
|
||||||
|
.. image:: ../screenshots/gitlab.png
|
||||||
|
|
||||||
gpmdp
|
gpmdp
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
|
@ -1107,6 +1183,7 @@ Parameters:
|
||||||
if {file} = '/foo/bar.baz', then {file2} = 'bar'
|
if {file} = '/foo/bar.baz', then {file2} = 'bar'
|
||||||
|
|
||||||
* mpd.host: MPD host to connect to. (mpc behaviour by default)
|
* mpd.host: MPD host to connect to. (mpc behaviour by default)
|
||||||
|
* mpd.port: MPD port to connect to. (mpc behaviour by default)
|
||||||
* mpd.layout: Space-separated list of widgets to add. Possible widgets are the buttons/toggles mpd.prev, mpd.next, mpd.shuffle and mpd.repeat, and the main display with play/pause function mpd.main.
|
* mpd.layout: Space-separated list of widgets to add. Possible widgets are the buttons/toggles mpd.prev, mpd.next, mpd.shuffle and mpd.repeat, and the main display with play/pause function mpd.main.
|
||||||
|
|
||||||
contributed by `alrayyes <https://github.com/alrayyes>`_ - many thanks!
|
contributed by `alrayyes <https://github.com/alrayyes>`_ - many thanks!
|
||||||
|
@ -1126,9 +1203,7 @@ network_traffic
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Displays network traffic
|
Displays network traffic
|
||||||
|
* No extra configuration needed
|
||||||
Requires the following library:
|
|
||||||
* netifaces
|
|
||||||
|
|
||||||
contributed by `izn <https://github.com/izn>`_ - many thanks!
|
contributed by `izn <https://github.com/izn>`_ - many thanks!
|
||||||
|
|
||||||
|
@ -1155,7 +1230,7 @@ nvidiagpu
|
||||||
Displays GPU name, temperature and memory usage.
|
Displays GPU name, temperature and memory usage.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
* nvidiagpu.format: Format string (defaults to '{name}: {temp}°C %{mem_used}/{mem_total} MiB')
|
* nvidiagpu.format: Format string (defaults to '{name}: {temp}°C %{usedmem}/{totalmem} MiB')
|
||||||
Available values are: {name} {temp} {mem_used} {mem_total} {fanspeed} {clock_gpu} {clock_mem} {gpu_usage_pct} {mem_usage_pct} {mem_io_pct}
|
Available values are: {name} {temp} {mem_used} {mem_total} {fanspeed} {clock_gpu} {clock_mem} {gpu_usage_pct} {mem_usage_pct} {mem_io_pct}
|
||||||
|
|
||||||
Requires nvidia-smi
|
Requires nvidia-smi
|
||||||
|
@ -1239,12 +1314,19 @@ Displays the pi-hole status (up/down) together with the number of ads that were
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
* pihole.address : pi-hole address (e.q: http://192.168.1.3)
|
* pihole.address : pi-hole address (e.q: http://192.168.1.3)
|
||||||
* pihole.pwhash : pi-hole webinterface password hash (can be obtained from the /etc/pihole/SetupVars.conf file)
|
|
||||||
|
|
||||||
|
* pihole.apitoken : pi-hole API token (can be obtained in the pi-hole webinterface (Settings -> API)
|
||||||
|
|
||||||
|
OR (deprecated!)
|
||||||
|
|
||||||
|
* pihole.pwhash : pi-hole webinterface password hash (can be obtained from the /etc/pihole/SetupVars.conf file)
|
||||||
|
|
||||||
|
|
||||||
contributed by `bbernhard <https://github.com/bbernhard>`_ - many thanks!
|
contributed by `bbernhard <https://github.com/bbernhard>`_ - many thanks!
|
||||||
|
|
||||||
pipewire
|
pipewire
|
||||||
~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
get volume level or control it
|
get volume level or control it
|
||||||
|
|
||||||
|
@ -1575,7 +1657,9 @@ Display a stock quote from finance.yahoo.com
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
* stock.symbols : Comma-separated list of symbols to fetch
|
* stock.symbols : Comma-separated list of symbols to fetch
|
||||||
* stock.change : Should we fetch change in stock value (defaults to True)
|
* stock.apikey : API key created on https://alphavantage.co
|
||||||
|
* stock.url : URL to use, defaults to "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={symbol}&apikey={apikey}"
|
||||||
|
* stock.fields : Fields from the response to show, defaults to "01. symbol,05. price,10. change percent"
|
||||||
|
|
||||||
|
|
||||||
contributed by `msoulier <https://github.com/msoulier>`_ - many thanks!
|
contributed by `msoulier <https://github.com/msoulier>`_ - many thanks!
|
||||||
|
@ -1610,11 +1694,11 @@ adds the possibility to
|
||||||
* reboot
|
* reboot
|
||||||
|
|
||||||
the system.
|
the system.
|
||||||
|
|
||||||
Per default a confirmation dialog is shown before the actual action is performed.
|
Per default a confirmation dialog is shown before the actual action is performed.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
* system.confirm: show confirmation dialog before performing any action (default: true)
|
* system.confirm: show confirmation dialog before performing any action (default: true)
|
||||||
* system.reboot: specify a reboot command (defaults to 'reboot')
|
* system.reboot: specify a reboot command (defaults to 'reboot')
|
||||||
* system.shutdown: specify a shutdown command (defaults to 'shutdown -h now')
|
* system.shutdown: specify a shutdown command (defaults to 'shutdown -h now')
|
||||||
* system.logout: specify a logout command (defaults to 'i3exit logout')
|
* system.logout: specify a logout command (defaults to 'i3exit logout')
|
||||||
|
@ -1713,6 +1797,27 @@ Parameters:
|
||||||
* todo_org.remaining: False by default. When true, will output the number of remaining todos instead of the number completed (i.e. 1/4 means 1 of 4 todos remaining, rather than 1 of 4 todos completed)
|
* todo_org.remaining: False by default. When true, will output the number of remaining todos instead of the number completed (i.e. 1/4 means 1 of 4 todos remaining, rather than 1 of 4 todos completed)
|
||||||
Based on the todo module by `codingo <https://github.com/codingo>`
|
Based on the todo module by `codingo <https://github.com/codingo>`
|
||||||
|
|
||||||
|
todoist
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
Displays the nº of Todoist tasks that are due:
|
||||||
|
|
||||||
|
* https://developer.todoist.com/rest/v2/#get-active-tasks
|
||||||
|
|
||||||
|
Uses `xdg-open` or `x-www-browser` to open web-pages.
|
||||||
|
|
||||||
|
Requires the following library:
|
||||||
|
* requests
|
||||||
|
|
||||||
|
Errors:
|
||||||
|
if the Todoist get active tasks query failed, the shown value is `n/a`
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* todoist.token: Todoist api token, you can get it in https://todoist.com/app/settings/integrations/developer.
|
||||||
|
* todoist.filter: a filter statement defined by Todoist (https://todoist.com/help/articles/introduction-to-filters), eg: "!assigned to: others & (Overdue | due: today)"
|
||||||
|
|
||||||
|
.. image:: ../screenshots/todoist.png
|
||||||
|
|
||||||
traffic
|
traffic
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
@ -1751,6 +1856,27 @@ contributed by `ccoors <https://github.com/ccoors>`_ - many thanks!
|
||||||
|
|
||||||
.. image:: ../screenshots/uptime.png
|
.. image:: ../screenshots/uptime.png
|
||||||
|
|
||||||
|
usage
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
Module for ActivityWatch (https://activitywatch.net/)
|
||||||
|
Displays the amount of time the system was used actively.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
* sqlite3 module for python
|
||||||
|
* ActivityWatch
|
||||||
|
|
||||||
|
Errors:
|
||||||
|
* when you get 'error: unable to open database file', modify the parameter 'database' to your ActivityWatch database file
|
||||||
|
-> often found by running 'locate aw-server/peewee-sqlite.v2.db'
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* usage.database: path to your database file
|
||||||
|
* usage.format: Specify what gets printed to the bar
|
||||||
|
-> use 'HH', 'MM' or 'SS', they will get replaced by the number of hours, minutes and seconds, respectively
|
||||||
|
|
||||||
|
contributed by lasnikr (https://github.com/lasnikr)
|
||||||
|
|
||||||
vpn
|
vpn
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
@ -1770,6 +1896,34 @@ Displays the VPN profile that is currently in use.
|
||||||
|
|
||||||
contributed by `bbernhard <https://github.com/bbernhard>`_ - many thanks!
|
contributed by `bbernhard <https://github.com/bbernhard>`_ - many thanks!
|
||||||
|
|
||||||
|
wakatime
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
Displays the WakaTime daily/weekly/monthly times:
|
||||||
|
|
||||||
|
* https://wakatime.com/developers#stats
|
||||||
|
|
||||||
|
Uses `xdg-open` or `x-www-browser` to open web-pages.
|
||||||
|
|
||||||
|
Requires the following library:
|
||||||
|
* requests
|
||||||
|
|
||||||
|
Errors:
|
||||||
|
if the Wakatime status query failed, the shown value is `n/a`
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* wakatime.token: Wakatime secret api key, you can get it in https://wakatime.com/settings/account.
|
||||||
|
* wakatime.range: Range of the output, default is "Today". Can be one of “Today”, “Yesterday”, “Last 7 Days”, “Last 7 Days from Yesterday”, “Last 14 Days”, “Last 30 Days”, “This Week”, “Last Week”, “This Month”, or “Last Month”.
|
||||||
|
* wakatime.format: Format of the output, default is "digital"
|
||||||
|
Valid inputs are:
|
||||||
|
* "decimal" -> 1.37
|
||||||
|
* "digital" -> 1:22
|
||||||
|
* "seconds" -> 4931.29
|
||||||
|
* "text" -> 1 hr 22 mins
|
||||||
|
* "%H:%M:%S" -> 01:22:31 (or any other valid format)
|
||||||
|
|
||||||
|
.. image:: ../screenshots/wakatime.png
|
||||||
|
|
||||||
watson
|
watson
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
|
@ -1778,6 +1932,10 @@ Displays the status of watson (time-tracking tool)
|
||||||
Requires the following executable:
|
Requires the following executable:
|
||||||
* watson
|
* watson
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
* watson.format: Output format, defaults to "{project} [{tags}]"
|
||||||
|
Supported fields are: {project}, {tags}, {relative_start}, {absolute_start}
|
||||||
|
|
||||||
contributed by `bendardenne <https://github.com/bendardenne>`_ - many thanks!
|
contributed by `bendardenne <https://github.com/bendardenne>`_ - many thanks!
|
||||||
|
|
||||||
weather
|
weather
|
||||||
|
@ -1795,7 +1953,7 @@ Parameters:
|
||||||
* weather.unit: metric (default), kelvin, imperial
|
* weather.unit: metric (default), kelvin, imperial
|
||||||
* weather.showcity: If set to true, show location information, otherwise hide it (defaults to true)
|
* weather.showcity: If set to true, show location information, otherwise hide it (defaults to true)
|
||||||
* weather.showminmax: If set to true, show the minimum and maximum temperature, otherwise hide it (defaults to false)
|
* weather.showminmax: If set to true, show the minimum and maximum temperature, otherwise hide it (defaults to false)
|
||||||
* weather.apikey: API key from http://api.openweathermap.org
|
* weather.apikey: API key from https://api.openweathermap.org
|
||||||
|
|
||||||
|
|
||||||
contributed by `TheEdgeOfRage <https://github.com/TheEdgeOfRage>`_ - many thanks!
|
contributed by `TheEdgeOfRage <https://github.com/TheEdgeOfRage>`_ - many thanks!
|
||||||
|
|
|
@ -113,6 +113,12 @@ def test_missing_parameter():
|
||||||
assert cfg.get("test.key") == None
|
assert cfg.get("test.key") == None
|
||||||
assert cfg.get("test.key", "no-value-set") == "no-value-set"
|
assert cfg.get("test.key", "no-value-set") == "no-value-set"
|
||||||
|
|
||||||
|
def test_file_case_sensitivity():
|
||||||
|
cfg = core.config.Config([])
|
||||||
|
cfg.load_config("", content="[module-parameters]\ntest.key = VaLuE\ntest.KeY2 = value")
|
||||||
|
|
||||||
|
assert cfg.get("test.key") == "VaLuE"
|
||||||
|
assert cfg.get("test.KeY2") == "value"
|
||||||
|
|
||||||
#
|
#
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||||
|
|
Loading…
Reference in a new issue