New upstream version 0.30
Apollon Oikonomopoulos
4 years ago
12 | 12 | /out/ |
13 | 13 | /cabal.config |
14 | 14 | codex.tags |
15 | cabal.project.local⏎ | |
15 | cabal.project.localtags | |
16 | *.swp | |
17 | tags | |
18 | /cabal.project.local |
0 | ## Version 0.30 (August, 2019) | |
1 | ||
2 | _New features_ | |
3 | ||
4 | - New monitor `MultiCoreTemp`, thanks to Felix Springer. | |
5 | - `DiskIO`: Additional template variables for absolute number of | |
6 | bytes rather than speeds (see [issue #390]. | |
7 | - `WeatherX`: An extension to the `Weather` monitor allowing the | |
8 | spefication of custom strings or icons for sky conditions. | |
9 | - The battery monitors accept the new arguments `-a` and `-A` to | |
10 | specify a system command executed if battery left goes beyond a | |
11 | given threshold. | |
12 | ||
13 | [issue #390]: https://github.com/jaor/xmobar/issues/390 | |
14 | ||
15 | ## Version 0.29.5 (March, 2019) | |
16 | ||
17 | _Bug fixes_ | |
18 | ||
19 | - Honour command line flags when starting xmobar without any | |
20 | configuration file (issue #375). | |
21 | - `Alsa` plugin: restart `alsactl` if it quits, e.g. because of a | |
22 | sleep/awake cycle (issue #376). | |
23 | - `Weather` using the new HTTPS URL, which requires http-conduit as | |
24 | a dependency (issue #378). | |
25 | - `MarqueePipeReader` exported at the API level (issue #381). | |
26 | ||
0 | 27 | ## Version 0.29.4 (December, 2018) |
1 | 28 | |
2 | 29 | Upgrade to alsa-mixer 0.3.0. See issues #372 and #373. |
0 | { mkDerivation, alsa-core, alsa-mixer, async, base, bytestring | |
1 | , containers, dbus, directory, extensible-exceptions, filepath | |
2 | , hinotify, hspec, http-conduit, http-types, iwlib, libmpd, libXpm | |
3 | , libXrandr, libXrender, mtl, old-locale, parsec, parsec-numbers | |
4 | , process, regex-compat, stdenv, stm, temporary, time | |
5 | , timezone-olson, timezone-series, transformers, unix, utf8-string | |
6 | , wirelesstools, X11, X11-xft | |
7 | }: | |
8 | mkDerivation { | |
9 | pname = "xmobar"; | |
10 | version = "0.29.5"; | |
11 | src = ./.; | |
12 | configureFlags = [ | |
13 | "-fwith_alsa" "-fwith_conduit" "-fwith_datezone" "-fwith_dbus" | |
14 | "-fwith_inotify" "-fwith_iwlib" "-fwith_mpd" "-fwith_mpris" | |
15 | "-fwith_rtsopts" "-fwith_threaded" "-fwith_utf8" "-fwith_uvmeter" | |
16 | "-fwith_weather" "-fwith_xft" "-fwith_xpm" | |
17 | ]; | |
18 | isLibrary = true; | |
19 | isExecutable = true; | |
20 | libraryHaskellDepends = [ | |
21 | alsa-core alsa-mixer async base bytestring containers dbus | |
22 | directory extensible-exceptions filepath hinotify http-conduit | |
23 | http-types iwlib libmpd mtl old-locale parsec parsec-numbers | |
24 | process regex-compat stm time timezone-olson timezone-series | |
25 | transformers unix utf8-string X11 X11-xft | |
26 | ]; | |
27 | librarySystemDepends = [ | |
28 | libXpm libXrandr libXrender wirelesstools | |
29 | ]; | |
30 | executableHaskellDepends = [ | |
31 | async base containers directory filepath parsec unix X11 | |
32 | ]; | |
33 | testHaskellDepends = [ | |
34 | alsa-core alsa-mixer async base bytestring containers directory | |
35 | filepath hspec mtl old-locale parsec parsec-numbers process | |
36 | regex-compat stm temporary time transformers unix X11 | |
37 | ]; | |
38 | doCheck = false; | |
39 | homepage = "http://xmobar.org"; | |
40 | description = "A Minimalistic Text Based Status Bar"; | |
41 | license = stdenv.lib.licenses.bsd3; | |
42 | } |
0 | index.src = ../readme.md | |
1 | index = readme.md | |
2 | releases = ../news.md | |
3 | css = xmobar.css | |
4 | images = xmobar-sawfish.png xmobar-xmonad.png | |
5 | remote = community.haskell.org:/srv/projects/xmobar/ | |
6 | htmls = index.html releases.html | |
7 | title = % xmobar - a minimalistic status bar | |
8 | ||
9 | default: index.html | |
10 | ||
11 | $(index): $(index.src) | |
12 | @tail -n+3 $(index.src) | sed "1s/^/$(title)\n/" > $(index) | |
13 | ||
14 | index.html: releases.html $(index) $(css) | |
15 | pandoc -f markdown -t html -c $(css) --toc -N -s \ | |
16 | $(index) > index.html | |
17 | ||
18 | releases.html: $(releases) $(css) | |
19 | pandoc -f markdown -t html -c $(css) -s \ | |
20 | $(releases) > releases.html | |
21 | ||
22 | upload-images: | |
23 | rsync -zav $(images) $(remote) | |
24 | ||
25 | upload-pages: $(htmls) | |
26 | scp $(htmls) $(css) $(remote) | |
27 | ||
28 | upload: upload-images upload-pages | |
29 | ||
30 | clean: | |
31 | rm -f $(htmls) $(index) |
0 | index.src = ../../readme.md | |
1 | index = readme.md | |
2 | releases = ../../changelog.md | |
3 | css = xmobar.css | |
4 | images = ../xmobar-sawfish.png ../xmobar-xmonad.png | |
5 | remote = root@xmobar.org:/var/www/xmobar.org/ | |
6 | htmls = index.html releases.html | |
7 | title = % xmobar - a minimalistic status bar | |
8 | ||
9 | default: index.html | |
10 | ||
11 | $(index): $(index.src) | |
12 | @tail -n+3 $(index.src) | sed "1s/^/$(title)\n/" > $(index) | |
13 | ||
14 | index.html: releases.html $(index) $(css) | |
15 | pandoc -f markdown -t html -c $(css) --toc -N -s \ | |
16 | $(index) > index.html | |
17 | ||
18 | releases.html: $(releases) $(css) | |
19 | pandoc -f markdown -t html -c $(css) -s \ | |
20 | $(releases) > releases.html | |
21 | ||
22 | imgs: | |
23 | cp $(images) . | |
24 | ||
25 | upload-images: imgs | |
26 | rsync -zav $(images) $(remote) | |
27 | ||
28 | upload-pages: $(htmls) | |
29 | scp $(htmls) $(css) $(remote) | |
30 | ||
31 | upload: upload-images upload-pages | |
32 | ||
33 | clean: | |
34 | rm -f $(htmls) $(index) *.png |
12 | 12 | } |
13 | 13 | pre { |
14 | 14 | border: 1px dotted gray; |
15 | background-color: #efebe7; | |
15 | background-color: #fafafa; | |
16 | 16 | color: #111111; |
17 | 17 | padding: 0.5em; |
18 | 18 | } |
0 | 0 | ------------------------------------------------------------------------------ |
1 | 1 | -- | |
2 | -- Copyright: (c) 2018 Jose Antonio Ortega Ruiz | |
2 | -- Copyright: (c) 2018, 2019 Jose Antonio Ortega Ruiz | |
3 | 3 | -- License: BSD3-style (see LICENSE) |
4 | 4 | -- |
5 | 5 | -- Maintainer: jao@gnu.org |
29 | 29 | -- Configuration, using predefined monitors as well as our HelloWorld |
30 | 30 | -- plugin: |
31 | 31 | |
32 | config :: Config | |
32 | 33 | config = defaultConfig { |
33 | 34 | font = "xft:Sans Mono-9" |
34 | 35 | , additionalFonts = [] |
10 | 10 | features, like dynamic color management, icons, output templates, and |
11 | 11 | extensibility through plugins. |
12 | 12 | |
13 | [This screenshot](doc/xmobar-sawfish.png) shows xmobar running under | |
14 | [sawfish], and [this one](doc/xmobar-xmonad.png) is a desktop with | |
15 | [xmonad] and two instances of xmobar. | |
13 | These are two xmobar instances using the author's configuration: | |
14 | ||
15 | ![top](https://gitlab.com/jaor/xmobar-config/raw/master/img/xmobar-top.png) | |
16 | ||
17 | ![bottom](https://gitlab.com/jaor/xmobar-config/raw/master/img/xmobar-bottom.png) | |
18 | ||
19 | and [this one](doc/xmobar-xmonad.png) is a full desktop with [xmonad] | |
20 | and, again, two instances of xmobar. | |
16 | 21 | |
17 | 22 | [xmonad]: http://xmonad.org |
18 | 23 | [Ion3]: http://tuomov.iki.fi/software/ |
129 | 134 | .xpm files in `<icon>`. Requires the [libXpm] C library. |
130 | 135 | |
131 | 136 | - `with_uvmeter` Enables UVMeter plugin. The plugin shows UV data for |
132 | Australia. Requires `with_conduit` to connect to HTTPS URLs. | |
137 | Australia. | |
133 | 138 | |
134 | 139 | - `with_weather` Support to display weather information. Enables |
135 | 140 | Weather plugin. |
136 | ||
137 | - `with_conduit` Use http-conduit for getting weather data enabling | |
138 | support for http proxies. Requires [http-conduit] and [http-types]. | |
139 | Note that this flag has only an effect if `with_weather` is also set. | |
140 | 141 | |
141 | 142 | - `all_extensions` Enables all the extensions above. |
142 | 143 | |
742 | 743 | - Default template: `<station>: <tempC>C, rh <rh>% (<hour>)` |
743 | 744 | - Retrieves weather information from http://tgftp.nws.noaa.gov. |
744 | 745 | |
746 | ### `WeatherX StationID SkyConditions Args RefreshRate` | |
747 | ||
748 | - Works in the same way as `Weather`, but takes an additional | |
749 | argument, a list of pairs from sky conditions to their replacement | |
750 | (typically a unicode string or an icon specification). | |
751 | - Use the variable `skyConditionS` to display the replacement of the | |
752 | corresponding sky condition. All other `Weather` template variables | |
753 | are available as well. | |
754 | ||
755 | For example: | |
756 | ||
757 | ```haskell | |
758 | WeatherX "LEBL" | |
759 | [ ("clear", "🌣") | |
760 | , ("sunny", "🌣") | |
761 | , ("mostly clear", "🌤") | |
762 | , ("mostly sunny", "🌤") | |
763 | , ("partly sunny", "⛅") | |
764 | , ("fair", "🌑") | |
765 | , ("cloudy","☁") | |
766 | , ("overcast","☁") | |
767 | , ("partly cloudy", "⛅") | |
768 | , ("mostly cloudy", "🌧") | |
769 | , ("considerable cloudiness", "⛈")] | |
770 | ["-t", "<fn=2><skyConditionS></fn> <tempC>° <rh>% <windKmh> (<hour>)" | |
771 | , "-L","10", "-H", "25", "--normal", "black" | |
772 | , "--high", "lightgoldenrod4", "--low", "darkseagreen4"] | |
773 | 18000 | |
774 | ``` | |
775 | ||
776 | As mentioned, the replacement string can also be an icon | |
777 | specification, such as `("clear", "<icon=weather-clear.xbm/>")`. | |
778 | ||
745 | 779 | ### `Network Interface Args RefreshRate` |
746 | 780 | |
747 | 781 | - Aliases to the interface name: so `Network "eth0" []` can be used as |
868 | 902 | - `-p`: color to display positive power (battery charging) |
869 | 903 | - `-f`: file in `/sys/class/power_supply` with AC info (default: |
870 | 904 | "AC/online") |
905 | - `-A`: a number between 0 and 100, threshold below which the action | |
906 | given by `-a`, if any, is performed (default: 5) | |
907 | - `-a`: a string with a system command that is run when the | |
908 | percentage left in the battery is less or equal than the threshold | |
909 | given by the `-A` option. If not present, no action is | |
910 | undertaken. | |
871 | 911 | - `--on-icon-pattern`: dynamic string for current battery charge |
872 | 912 | when AC is "on" in `leftipat`. |
873 | 913 | - `--off-icon-pattern`: dynamic string for current battery charge |
886 | 926 | "-L", "10", "-H", "80", "-p", "3", |
887 | 927 | "--", "-O", "<fc=green>On</fc> - ", "-i", "", |
888 | 928 | "-L", "-15", "-H", "-5", |
889 | "-l", "red", "-m", "blue", "-h", "green"] | |
929 | "-l", "red", "-m", "blue", "-h", "green" | |
930 | "-a", "notify-send -u critical 'Battery running out!!'", | |
931 | "-A", "3"] | |
890 | 932 | 600 |
891 | 933 | |
892 | 934 | In the above example, the thresholds before the "--" separator |
893 | 935 | affect only the `<left>` and `<leftbar>` fields, while those after |
894 | 936 | the separator affect how `<watts>` is displayed. For this monitor, |
895 | 937 | neither the generic nor the specific options have any effect on |
896 | `<timeleft>`. | |
938 | `<timeleft>`. We are also telling the monitor to execute the unix | |
939 | command `notify-send` when the percentage left in the battery | |
940 | reaches 6%. | |
897 | 941 | |
898 | 942 | It is also possible to specify template variables in the `-O` and |
899 | 943 | `-o` switches, as in the following example: |
967 | 1011 | |
968 | 1012 | - Aliases to `diskio` |
969 | 1013 | - Disks: list of pairs of the form (device or mount point, template), |
970 | where the template can contain `<total>`, `<read>`, `<write>` for total, | |
971 | read and write speed, respectively. There are also bar versions of each: | |
972 | `<totalbar>`, `<totalvbar>`, `<totalipat>`, | |
973 | `<readbar>`, `<readvbar>`, `<readipat>`, | |
974 | `<writebar>`, `<writevbar>`, and `<writeipat>`. | |
1014 | where the template can contain `<total>`, `<read>`, `<write>` for | |
1015 | total, read and write speed, respectively, as well as `<totalb>`, | |
1016 | `<readb>`, `<writeb>`, which report number of bytes during the last | |
1017 | refresh period rather than speed. There are also bar versions of | |
1018 | each: `<totalbar>`, `<totalvbar>`, `<totalipat>`, `<readbar>`, | |
1019 | `<readvbar>`, `<readipat>`, `<writebar>`, `<writevbar>`, and | |
1020 | `<writeipat>`; and their "bytes" counterparts: `<totalbbar>`, | |
1021 | `<totalbvbar>`, `<totalbipat>`, `<readbbar>`, `<readbvbar>`, | |
1022 | `<readbipat>`, `<writebbar>`, `<writebvbar>`, and `<writebipat>`. | |
975 | 1023 | - Thresholds refer to speed in b/s |
976 | 1024 | - Args: default monitor arguments. `-t`/`--template` is ignored. Plus |
977 | 1025 | - `--total-icon-pattern`: dynamic string for total disk I/O in `<totalipat>`. |
1044 | 1092 | Run CoreTemp ["-t", "Temp:<core0>|<core1>C", |
1045 | 1093 | "-L", "40", "-H", "60", |
1046 | 1094 | "-l", "lightblue", "-n", "gray90", "-h", "red"] 50 |
1095 | ||
1096 | ### `MultiCoreTemp Args RefreshRate` | |
1097 | ||
1098 | - Aliases to `multicoretemp` | |
1099 | - Args: default monitor arguments, plus: | |
1100 | - `--max-icon-pattern`: dynamic string for overall cpu load in `maxipat`. | |
1101 | - `--avg-icon-pattern`: dynamic string for overall cpu load in `avgipat`. | |
1102 | - `--mintemp`: temperature in degree Celsius, that sets the lower | |
1103 | limit for percentage calculation. | |
1104 | - `--maxtemp`: temperature in degree Celsius, that sets the upper | |
1105 | limit for percentage calculation. | |
1106 | - Thresholds refer to temperature in degree Celsius | |
1107 | - Variables that can be used with the `-t`/`--template` argument: | |
1108 | `max`, `maxpc`, `maxbar`, `maxvbar`, `maxipat`, | |
1109 | `avg`, `avgpc`, `avgbar`, `avgvbar`, `avgipat`, | |
1110 | `core0`, `core1`, ..., `coreN` | |
1111 | ||
1112 | The *pc, *bar, *vbar and *ipat variables are showing percentages on the scale | |
1113 | defined by `--mintemp` and `--maxtemp`. | |
1114 | The max* and avg* variables to the highest and the average core temperature. | |
1115 | - Default template: `Temp: <max>°C - <maxpc>%` | |
1116 | - This monitor requires coretemp module to be loaded in kernel | |
1117 | - Example: | |
1118 | ||
1119 | Run MultiCoreTemp ["-t", "Temp: <avg>°C | <avgpc>%", | |
1120 | "-L", "60", "-H", "80", | |
1121 | "-l", "green", "-n", "yellow", "-h", "red" | |
1122 | "--", "--mintemp", "20", "--maxtemp", "100"] 50 | |
1047 | 1123 | |
1048 | 1124 | ### `Volume Mixer Element Args RefreshRate` |
1049 | 1125 | |
1470 | 1546 | |
1471 | 1547 | `start` must receive a callback to be used to display the `String` |
1472 | 1548 | produced by the plugin. This method can be used for plugins that need |
1473 | to perform asynchronous actions. See `Plugins/PipeReader.hs` for an | |
1474 | example. | |
1549 | to perform asynchronous actions. See | |
1550 | `src/Xmobar/Plugins/PipeReader.hs` for an example. | |
1475 | 1551 | |
1476 | 1552 | `run` can be used for simpler plugins. If you define only `run` the |
1477 | 1553 | plugin will be run every second. To overwrite this default you just |
1478 | 1554 | need to implement `rate`, which must return the number of tenth of |
1479 | seconds between every successive runs. See `Plugins/HelloWorld.hs` for | |
1480 | an example of a plugin that runs just once, and `Plugins/Date.hs` for | |
1481 | one that implements `rate`. | |
1555 | seconds between every successive runs. See `examples/xmobar.hs` for an | |
1556 | example of a plugin that runs just once, and | |
1557 | `src/Xmobar/Plugins/Date.hs` for one that implements `rate`. | |
1482 | 1558 | |
1483 | 1559 | Notice that Date could be implemented as: |
1484 | 1560 | |
1507 | 1583 | |
1508 | 1584 | To use your new plugin, you need to use a pure Haskell configuration |
1509 | 1585 | for xmobar, and load your definitions there. You can see an example |
1510 | in [examples/xmobar.hs] showing you how to write a Haskell | |
1511 | configuration that uses a new plugin, all in one file. | |
1586 | in [examples/xmobar.hs](./examples/xmobar.hs) showing you how to write | |
1587 | a Haskell configuration that uses a new plugin, all in one file. | |
1512 | 1588 | |
1513 | 1589 | When xmobar runs with the full path to that Haskell file as its |
1514 | 1590 | argument (or if you put it in `~/.config/xmobar/xmobar.hs`), and with |
1517 | 1593 | |
1518 | 1594 | That's it! |
1519 | 1595 | |
1596 | ## Configurations written in pure Haskell | |
1597 | ||
1598 | xmobar can be used as a pure Haskell program, that is compiled with | |
1599 | your specific configuration, expressed as Haskell source code. For an | |
1600 | example, see [the author's | |
1601 | configuration](https://gitlab.com/jaor/xmobar-config/). | |
1602 | ||
1520 | 1603 | # Authors and credits |
1521 | 1604 | |
1522 | 1605 | Andrea Rossato originally designed and implemented xmobar up to |
1524 | 1607 | with the help of the greater xmobar and Haskell communities. |
1525 | 1608 | |
1526 | 1609 | In particular, xmobar [incorporates patches] by Mohammed Alshiekh, |
1527 | Axel Angel, Dragos Boca, Ben Boeckel, Duncan Burke, Roman Cheplyaka, | |
1528 | Patrick Chilton, Antoine Eiche, Nathaniel Wesley Filardo, John | |
1529 | Goerzen, Reto Hablützel, Juraj Hercek, Tomáš Janoušek, Ada Joule, | |
1530 | Spencer Janssen, Roman Joost, Jochen Keil, Lennart Kolmodin, Krzysztof | |
1531 | Kosciuszkiewicz, Dmitry Kurochkin, Todd Lunter, Vanessa McHale, Robert | |
1532 | J. Macomber, Dmitry Malikov, David McLean, Marcin Mikołajczyk, Dino | |
1533 | Morelli, Tony Morris, Eric Mrak, Thiago Negri, Edward O'Callaghan, | |
1534 | Svein Ove, Martin Perner, Jens Petersen, Alexander Polakov, Pavan | |
1535 | Rikhi, Petr Rockai, Andrew Sackville-West, Markus Scherer, Daniel | |
1536 | Schüssler, Olivier Schneider, Alexander Shabalin, Valentin Shirokov, | |
1537 | Peter Simons, Alexander Solovyov, Will Song, John Soros, Travis | |
1538 | Staton, Artem Tarasov, Samuli Thomasson, Edward Tjörnhammar, Sergei | |
1539 | Trofimovich, Thomas Tuegel, Jan Vornberger, Anton Vorontsov, Daniel | |
1540 | Wagner, Zev Weiss, Phil Xiaojun Hu, Edward Z. Yang and Norbert Zeh. | |
1610 | Alex Ameen, Axel Angel, Claudio Bley, Dragos Boca, Ben Boeckel, Duncan | |
1611 | Burke, Roman Cheplyaka, Patrick Chilton, Antoine Eiche, Nathaniel | |
1612 | Wesley Filardo, John Goerzen, Reto Hablützel, Juraj Hercek, Tomáš | |
1613 | Janoušek, Ada Joule, Spencer Janssen, Roman Joost, Jochen Keil, | |
1614 | Lennart Kolmodin, Krzysztof Kosciuszkiewicz, Dmitry Kurochkin, Todd | |
1615 | Lunter, Vanessa McHale, Robert J. Macomber, Dmitry Malikov, David | |
1616 | McLean, Marcin Mikołajczyk, Dino Morelli, Tony Morris, Eric Mrak, | |
1617 | Thiago Negri, Edward O'Callaghan, Svein Ove, Martin Perner, Jens | |
1618 | Petersen, Alexander Polakov, Pavan Rikhi, Petr Rockai, Andrew | |
1619 | Sackville-West, Markus Scherer, Daniel Schüssler, Olivier Schneider, | |
1620 | Alexander Shabalin, Valentin Shirokov, Peter Simons, Alexander | |
1621 | Solovyov, Will Song, John Soros, Felix Springer, Travis Staton, Artem | |
1622 | Tarasov, Samuli Thomasson, Edward Tjörnhammar, Sergei Trofimovich, | |
1623 | Thomas Tuegel, Jan Vornberger, Anton Vorontsov, Daniel Wagner, Zev | |
1624 | Weiss, Phil Xiaojun Hu, Edward Z. Yang and Norbert Zeh. | |
1541 | 1625 | |
1542 | 1626 | [jao]: http://jao.io |
1543 | 1627 | [incorporates patches]: http://www.ohloh.net/p/xmobar/contributors |
1574 | 1658 | This software is released under a BSD-style license. See [LICENSE] for |
1575 | 1659 | more details. |
1576 | 1660 | |
1577 | Copyright © 2010-2018 Jose Antonio Ortega Ruiz | |
1661 | Copyright © 2010-2019 Jose Antonio Ortega Ruiz | |
1578 | 1662 | |
1579 | 1663 | Copyright © 2007-2010 Andrea Rossato |
1580 | 1664 |
0 | 0 | ------------------------------------------------------------------------------ |
1 | 1 | -- | |
2 | 2 | -- Module: Xmobar.App.Main |
3 | -- Copyright: (c) 2018 Jose Antonio Ortega Ruiz | |
3 | -- Copyright: (c) 2018, 2019 Jose Antonio Ortega Ruiz | |
4 | 4 | -- License: BSD3-style (see LICENSE) |
5 | 5 | -- |
6 | 6 | -- Maintainer: jao@gnu.org |
98 | 98 | case cf of |
99 | 99 | Nothing -> case rest of |
100 | 100 | (c:_) -> error $ c ++ ": file not found" |
101 | _ -> xmobar defaultConfig | |
101 | _ -> doOpts defaultConfig flags >>= xmobar | |
102 | 102 | Just p -> do r <- readConfig defaultConfig p |
103 | 103 | case r of |
104 | 104 | Left e -> |
0 | 0 | ------------------------------------------------------------------------------ |
1 | 1 | -- | |
2 | 2 | -- Module: Xmobar.App.Opts |
3 | -- Copyright: (c) 2018 Jose Antonio Ortega Ruiz | |
3 | -- Copyright: (c) 2018, 2019 Jose Antonio Ortega Ruiz | |
4 | 4 | -- License: BSD3-style (see LICENSE) |
5 | 5 | -- |
6 | 6 | -- Maintainer: jao@gnu.org |
104 | 104 | info :: String |
105 | 105 | info = "xmobar " ++ showVersion version |
106 | 106 | ++ "\n (C) 2007 - 2010 Andrea Rossato " |
107 | ++ "\n (C) 2010 - 2018 Jose A Ortega Ruiz\n " | |
107 | ++ "\n (C) 2010 - 2019 Jose A Ortega Ruiz\n " | |
108 | 108 | ++ mail ++ "\n" ++ license |
109 | 109 | |
110 | 110 | mail :: String |
11 | 11 | -- |
12 | 12 | ----------------------------------------------------------------------------- |
13 | 13 | |
14 | module Xmobar.Plugins.MarqueePipeReader where | |
14 | module Xmobar.Plugins.MarqueePipeReader(MarqueePipeReader(..)) where | |
15 | 15 | |
16 | 16 | import System.IO (openFile, IOMode(ReadWriteMode), Handle) |
17 | 17 | import Xmobar.System.Environment |
11 | 11 | -- |
12 | 12 | ----------------------------------------------------------------------------- |
13 | 13 | |
14 | {-# LANGUAGE PatternGuards #-} | |
14 | 15 | module Xmobar.Plugins.Monitors.Alsa |
15 | 16 | ( startAlsaPlugin |
16 | 17 | , withMonitorWaiter |
22 | 23 | import Control.Concurrent.Async |
23 | 24 | import Control.Exception |
24 | 25 | import Control.Monad |
26 | import Data.IORef | |
27 | import Data.Time.Clock | |
25 | 28 | import Xmobar.Plugins.Monitors.Common |
26 | 29 | import qualified Xmobar.Plugins.Monitors.Volume as Volume; |
27 | 30 | import System.Console.GetOpt |
28 | 31 | import System.Directory |
29 | 32 | import System.Exit |
30 | 33 | import System.IO |
34 | import System.IO.Error | |
31 | 35 | import System.Process |
36 | ||
37 | alsaCtlRestartRateLimit :: NominalDiffTime | |
38 | alsaCtlRestartRateLimit = 3 -- 'Num NominalDiffTime' assumes seconds | |
32 | 39 | |
33 | 40 | data AlsaOpts = AlsaOpts |
34 | 41 | { aoVolumeOpts :: Volume.VolumeOpts |
75 | 82 | opts2 <- io $ parseOpts args2 |
76 | 83 | Volume.runVolumeWith (aoVolumeOpts opts2) mixerName controlName |
77 | 84 | |
78 | withMonitorWaiter mixerName (aoAlsaCtlPath opts) $ \wait_ -> | |
85 | withMonitorWaiter mixerName (aoAlsaCtlPath opts) cb $ \wait_ -> | |
79 | 86 | runMB args Volume.volumeConfig run wait_ cb |
80 | 87 | |
81 | withMonitorWaiter :: String -> Maybe FilePath -> (IO () -> IO a) -> IO a | |
82 | withMonitorWaiter mixerName alsaCtlPath cont = do | |
88 | withMonitorWaiter :: String -> Maybe FilePath -> (String -> IO ()) -> (IO () -> IO a) -> IO a | |
89 | withMonitorWaiter mixerName alsaCtlPathOverride outputCallback cont = do | |
83 | 90 | mvar <- newMVar () |
84 | 91 | |
85 | path <- determineAlsaCtlPath | |
92 | effectivePath <- determineAlsaCtlPath | |
86 | 93 | |
87 | bracket (async $ readerThread mvar path) cancel $ \a -> do | |
94 | bracket (async $ alsaReaderThread mixerName effectivePath outputCallback mvar) cancel $ \a -> do | |
88 | 95 | |
89 | 96 | -- Throw on this thread if there's an exception |
90 | 97 | -- on the reader thread. |
93 | 100 | cont $ takeMVar mvar |
94 | 101 | |
95 | 102 | where |
96 | ||
97 | readerThread mvar path = | |
98 | let createProc = (proc "stdbuf" ["-oL", path, "monitor", mixerName]) | |
99 | {std_out = CreatePipe} | |
100 | in | |
101 | withCreateProcess createProc $ \_ (Just alsaOut) _ _ -> do | |
102 | hSetBuffering alsaOut LineBuffering | |
103 | ||
104 | forever $ do | |
105 | c <- hGetChar alsaOut | |
106 | when (c == '\n') $ | |
107 | -- This uses 'tryPutMVar' because 'putMVar' would make 'runVolume' run | |
108 | -- once for each event. But we want it to run only once after a burst | |
109 | -- of events. | |
110 | void $ tryPutMVar mvar () | |
111 | ||
112 | 103 | defaultPath = "/usr/sbin/alsactl" |
113 | 104 | |
114 | 105 | determineAlsaCtlPath = |
115 | case alsaCtlPath of | |
106 | case alsaCtlPathOverride of | |
116 | 107 | Just path -> do |
117 | 108 | found <- doesFileExist path |
118 | 109 | if found |
136 | 127 | alsaCtlOptionName ++ "=/path/to/alsactl" |
137 | 128 | |
138 | 129 | |
130 | alsaReaderThread :: String -> String -> (String -> IO a) -> MVar () -> IO b | |
131 | alsaReaderThread mixerName alsaCtlPath outputCallback mvar = | |
132 | let createProc = (proc "stdbuf" ["-oL", alsaCtlPath, "monitor", mixerName]) | |
133 | {std_out = CreatePipe} | |
134 | ||
135 | runAlsaOnce = | |
136 | withCreateProcess createProc $ \_ (Just alsaOut) _ _ -> do | |
137 | hSetBuffering alsaOut LineBuffering | |
138 | ||
139 | tryPutMVar mvar () -- Refresh immediately after restarting alsactl | |
140 | ||
141 | forever $ do | |
142 | c <- hGetChar alsaOut | |
143 | when (c == '\n') $ | |
144 | -- This uses 'tryPutMVar' because 'putMVar' would make 'runVolume' run | |
145 | -- once for each event. But we want it to run only once after a burst | |
146 | -- of events. | |
147 | void $ tryPutMVar mvar () | |
148 | in do | |
149 | limiter <- createRateLimiter alsaCtlRestartRateLimit | |
150 | ||
151 | forever $ do | |
152 | limiter | |
153 | ||
154 | catchJust | |
155 | (guard . isEOFError) | |
156 | runAlsaOnce | |
157 | pure | |
158 | ||
159 | outputCallback "Restarting alsactl..." | |
160 | ||
161 | ||
162 | ||
139 | 163 | -- This is necessarily very inefficient on 'String's |
140 | 164 | trimTrailingNewline :: String -> String |
141 | 165 | trimTrailingNewline x = |
143 | 167 | '\n' : '\r' : y -> reverse y |
144 | 168 | '\n' : y -> reverse y |
145 | 169 | _ -> x |
170 | ||
171 | -- | | |
172 | -- Returns an IO action that completes at most once per @interval@. | |
173 | -- The returned cation is not safe for concurrent use. | |
174 | createRateLimiter :: NominalDiffTime -> IO (IO ()) | |
175 | createRateLimiter interval = do | |
176 | prevTimeRef <- newIORef Nothing | |
177 | ||
178 | let | |
179 | limiter = do | |
180 | prevTime0 <- readIORef prevTimeRef | |
181 | curTime <- getCurrentTime | |
182 | ||
183 | case prevTime0 of | |
184 | Just prevTime | diff <- interval - (curTime `diffUTCTime` prevTime), | |
185 | diff > 0 | |
186 | -> do | |
187 | threadDelayNDT diff | |
188 | writeIORef prevTimeRef . Just =<< getCurrentTime | |
189 | ||
190 | _ -> writeIORef prevTimeRef (Just curTime) | |
191 | ||
192 | pure limiter | |
193 | ||
194 | threadDelayNDT :: NominalDiffTime -> IO () | |
195 | threadDelayNDT ndt = | |
196 | threadDelay (round (realToFrac ndt * 1e6 :: Double)) |
0 | 0 | ----------------------------------------------------------------------------- |
1 | 1 | -- | |
2 | 2 | -- Module : Plugins.Monitors.Batt |
3 | -- Copyright : (c) 2010, 2011, 2012, 2013, 2015, 2016, 2018 Jose A Ortega | |
3 | -- Copyright : (c) 2010, 2011, 2012, 2013, 2015, 2016, 2018, 2019 Jose A Ortega | |
4 | 4 | -- (c) 2010 Andrea Rossato, Petr Rockai |
5 | 5 | -- License : BSD-style (see LICENSE) |
6 | 6 | -- |
14 | 14 | |
15 | 15 | module Xmobar.Plugins.Monitors.Batt ( battConfig, runBatt, runBatt' ) where |
16 | 16 | |
17 | import System.Process (system) | |
18 | import Control.Monad (void, unless) | |
17 | 19 | import Control.Exception (SomeException, handle) |
18 | 20 | import Xmobar.Plugins.Monitors.Common |
19 | 21 | import System.FilePath ((</>)) |
35 | 37 | , highWColor :: Maybe String |
36 | 38 | , lowThreshold :: Float |
37 | 39 | , highThreshold :: Float |
40 | , onLowAction :: Maybe String | |
41 | , actionThreshold :: Float | |
38 | 42 | , onlineFile :: FilePath |
39 | 43 | , scale :: Float |
40 | 44 | , onIconPattern :: Maybe IconPattern |
51 | 55 | , lowWColor = Nothing |
52 | 56 | , mediumWColor = Nothing |
53 | 57 | , highWColor = Nothing |
58 | , onLowAction = Nothing | |
59 | , actionThreshold = 6 | |
54 | 60 | , lowThreshold = 10 |
55 | 61 | , highThreshold = 12 |
56 | 62 | , onlineFile = "AC/online" |
73 | 79 | , Option "H" ["hight"] (ReqArg (\x o -> o { highThreshold = read x }) "") "" |
74 | 80 | , Option "f" ["online"] (ReqArg (\x o -> o { onlineFile = x }) "") "" |
75 | 81 | , Option "s" ["scale"] (ReqArg (\x o -> o {scale = read x}) "") "" |
82 | , Option "a" ["action"] (ReqArg (\x o -> o { onLowAction = Just x }) "") "" | |
83 | , Option "A" ["action-threshold"] | |
84 | (ReqArg (\x o -> o { actionThreshold = read x }) "") "" | |
76 | 85 | , Option "" ["on-icon-pattern"] (ReqArg (\x o -> |
77 | 86 | o { onIconPattern = Just $ parseIconPattern x }) "") "" |
78 | 87 | , Option "" ["off-icon-pattern"] (ReqArg (\x o -> |
171 | 180 | mostCommonDef :: Eq a => a -> [a] -> a |
172 | 181 | mostCommonDef x xs = head $ last $ [x] : sortOn length (group xs) |
173 | 182 | |
183 | maybeAlert :: BattOpts -> Float -> IO () | |
184 | maybeAlert opts left = | |
185 | case onLowAction opts of | |
186 | Nothing -> return () | |
187 | Just x -> unless (isNaN left || actionThreshold opts < 100 * left) | |
188 | $ void $ system x | |
189 | ||
174 | 190 | readBatteries :: BattOpts -> [Files] -> IO Result |
175 | 191 | readBatteries opts bfs = |
176 | 192 | do let bfs' = filter (/= NoFiles) bfs |
191 | 207 | | time == 0 = Idle |
192 | 208 | | ac = Charging |
193 | 209 | | otherwise = Discharging |
210 | unless ac (maybeAlert opts left) | |
194 | 211 | return $ if isNaN left then NA else Result left watts time racst |
195 | 212 | |
196 | 213 | runBatt :: [String] -> Monitor String |
208 | 225 | do l <- fmtPercent x |
209 | 226 | ws <- fmtWatts w opts suffix d |
210 | 227 | si <- getIconPattern opts s x |
211 | parseTemplate (l ++ [fmtStatus opts s nas, fmtTime $ floor t, ws, si]) | |
228 | st <- showWithColors' (fmtStatus opts s nas) (100 * x) | |
229 | parseTemplate (l ++ [st, fmtTime $ floor t, ws, si]) | |
212 | 230 | NA -> getConfigValue naString |
213 | 231 | where fmtPercent :: Float -> Monitor [String] |
214 | 232 | fmtPercent x = do |
0 | 0 | ----------------------------------------------------------------------------- |
1 | 1 | -- | |
2 | 2 | -- Module : Plugins.Monitors.Disk |
3 | -- Copyright : (c) 2010, 2011, 2012, 2014, 2018 Jose A Ortega Ruiz | |
3 | -- Copyright : (c) 2010, 2011, 2012, 2014, 2018, 2019 Jose A Ortega Ruiz | |
4 | 4 | -- License : BSD-style (see LICENSE) |
5 | 5 | -- |
6 | 6 | -- Maintainer : Jose A Ortega Ruiz <jao@gnu.org> |
53 | 53 | |
54 | 54 | diskIOConfig :: IO MConfig |
55 | 55 | diskIOConfig = mkMConfig "" ["total", "read", "write" |
56 | ,"totalb", "readb", "writeb" | |
56 | 57 | ,"totalbar", "readbar", "writebar" |
58 | ,"totalbbar", "readbbar", "writebbar" | |
57 | 59 | ,"totalvbar", "readvbar", "writevbar" |
60 | ,"totalbvbar", "readbvbar", "writebvbar" | |
58 | 61 | ,"totalipat", "readipat", "writeipat" |
62 | ,"totalbipat", "readbipat", "writebipat" | |
59 | 63 | ] |
60 | 64 | |
61 | 65 | data DiskUOpts = DiskUOpts |
147 | 151 | case find ((==dev) . fst) dat of |
148 | 152 | Nothing -> (dev, [0, 0, 0]) |
149 | 153 | Just (_, xs) -> |
150 | let rSp = speed (xs !! 2) (xs !! 3) | |
151 | wSp = speed (xs !! 6) (xs !! 7) | |
152 | sp = speed (xs !! 2 + xs !! 6) (xs !! 3 + xs !! 7) | |
153 | speed x t = if t == 0 then 0 else 500 * x / t | |
154 | dat' = if length xs > 6 then [sp, rSp, wSp] else [0, 0, 0] | |
154 | let r = xs !! 2 | |
155 | w = xs !! 6 | |
156 | t = r + w | |
157 | rSp = speed r (xs !! 3) | |
158 | wSp = speed w (xs !! 7) | |
159 | sp = speed t (xs !! 3 + xs !! 7) | |
160 | speed x d = if d == 0 then 0 else 500 * x / d | |
161 | dat' = if length xs > 6 | |
162 | then [sp, rSp, wSp, t, r, w] | |
163 | else [0, 0, 0, 0, 0, 0] | |
155 | 164 | in (dev, dat') |
156 | 165 | |
157 | 166 | speedToStr :: Float -> String |
183 | 192 | b <- mapM (showLogBar 0.8) xs |
184 | 193 | vb <- mapM (showLogVBar 0.8) xs |
185 | 194 | ipat <- mapM (\(f,v) -> showLogIconPattern (f opts) 0.8 v) |
186 | $ zip [totalIconPattern, readIconPattern, writeIconPattern] xs | |
195 | $ zip [totalIconPattern, readIconPattern, writeIconPattern | |
196 | , totalIconPattern, readIconPattern, writeIconPattern] | |
197 | xs | |
187 | 198 | setConfigValue tmp template |
188 | 199 | parseTemplate $ s ++ b ++ vb ++ ipat |
189 | 200 |
84 | 84 | runMPRIS :: (MprisVersion a) => a -> String -> [String] -> Monitor String |
85 | 85 | runMPRIS version playerName _ = do |
86 | 86 | metadata <- io $ getMetadata version dbusClient playerName |
87 | if [] == metadata then | |
87 | if null metadata then | |
88 | 88 | getConfigValue naString |
89 | 89 | else mapM showWithPadding (makeList version metadata) >>= parseTemplate |
90 | 90 |
0 | ----------------------------------------------------------------------------- | |
1 | -- | | |
2 | -- Module : Plugins.Monitors.MultiCoreTemp | |
3 | -- Copyright : (c) 2019 Felix Springer | |
4 | -- License : BSD-style (see LICENSE) | |
5 | -- | |
6 | -- Maintainer : Felix Springer <felixspringer149@gmail.com> | |
7 | -- Stability : unstable | |
8 | -- Portability : unportable | |
9 | -- | |
10 | -- A core temperature monitor for Xmobar | |
11 | -- | |
12 | ----------------------------------------------------------------------------- | |
13 | ||
14 | module Xmobar.Plugins.Monitors.MultiCoreTemp (startMultiCoreTemp) where | |
15 | ||
16 | import Xmobar.Plugins.Monitors.Common | |
17 | import Control.Monad (filterM) | |
18 | import System.Console.GetOpt | |
19 | import System.Directory ( doesDirectoryExist | |
20 | , doesFileExist | |
21 | ) | |
22 | ||
23 | -- | Declare Options. | |
24 | data CTOpts = CTOpts { maxIconPattern :: Maybe IconPattern | |
25 | , avgIconPattern :: Maybe IconPattern | |
26 | , mintemp :: Float | |
27 | , maxtemp :: Float | |
28 | } | |
29 | ||
30 | -- | Set default Options. | |
31 | defaultOpts :: CTOpts | |
32 | defaultOpts = CTOpts { maxIconPattern = Nothing | |
33 | , avgIconPattern = Nothing | |
34 | , mintemp = 0 | |
35 | , maxtemp = 100 | |
36 | } | |
37 | ||
38 | -- | Apply configured Options. | |
39 | options :: [OptDescr (CTOpts -> CTOpts)] | |
40 | options = [ Option [] ["max-icon-pattern"] | |
41 | (ReqArg | |
42 | (\ arg opts -> opts { maxIconPattern = Just $ parseIconPattern arg }) | |
43 | "") | |
44 | "" | |
45 | , Option [] ["avg-icon-pattern"] | |
46 | (ReqArg | |
47 | (\ arg opts -> opts { avgIconPattern = Just $ parseIconPattern arg }) | |
48 | "") | |
49 | "" | |
50 | , Option [] ["mintemp"] | |
51 | (ReqArg | |
52 | (\ arg opts -> opts { mintemp = read arg }) | |
53 | "") | |
54 | "" | |
55 | , Option [] ["maxtemp"] | |
56 | (ReqArg | |
57 | (\ arg opts -> opts { maxtemp = read arg }) | |
58 | "") | |
59 | "" | |
60 | ] | |
61 | ||
62 | -- | Parse Arguments and apply them to Options. | |
63 | parseOpts :: [String] -> IO CTOpts | |
64 | parseOpts argv = case getOpt Permute options argv of | |
65 | (opts , _ , [] ) -> return $ foldr id defaultOpts opts | |
66 | (_ , _ , errs) -> ioError . userError $ concat errs | |
67 | ||
68 | -- | Generate Config with a default template and options. | |
69 | cTConfig :: IO MConfig | |
70 | cTConfig = mkMConfig cTTemplate cTOptions | |
71 | where cTTemplate = "Temp: <max>°C - <maxpc>%" | |
72 | cTOptions = [ "max" , "maxpc" , "maxbar" , "maxvbar" , "maxipat" | |
73 | , "avg" , "avgpc" , "avgbar" , "avgvbar" , "avgipat" | |
74 | ] ++ map (("core" ++) . show) [0 :: Int ..] | |
75 | ||
76 | -- | Returns the first coretemp.N path found. | |
77 | coretempPath :: IO String | |
78 | coretempPath = do xs <- filterM doesDirectoryExist ps | |
79 | let x = head xs | |
80 | return x | |
81 | where ps = [ "/sys/bus/platform/devices/coretemp." ++ show (x :: Int) ++ "/" | x <- [0..9] ] | |
82 | ||
83 | -- | Returns the first hwmonN path found. | |
84 | hwmonPath :: IO String | |
85 | hwmonPath = do p <- coretempPath | |
86 | xs <- filterM doesDirectoryExist [ p ++ "hwmon/hwmon" ++ show (x :: Int) ++ "/" | x <- [0..9] ] | |
87 | let x = head xs | |
88 | return x | |
89 | ||
90 | -- | Checks Labels, if they refer to a core and returns Strings of core- | |
91 | -- temperatures. | |
92 | corePaths :: IO [String] | |
93 | corePaths = do p <- hwmonPath | |
94 | ls <- filterM doesFileExist [ p ++ "temp" ++ show (x :: Int) ++ "_label" | x <- [0..9] ] | |
95 | cls <- filterM isLabelFromCore ls | |
96 | return $ map labelToCore cls | |
97 | ||
98 | -- | Checks if Label refers to a core. | |
99 | isLabelFromCore :: FilePath -> IO Bool | |
100 | isLabelFromCore p = do a <- readFile p | |
101 | return $ take 4 a == "Core" | |
102 | ||
103 | -- | Transform a path to Label to a path to core-temperature. | |
104 | labelToCore :: FilePath -> FilePath | |
105 | labelToCore = (++ "input") . reverse . drop 5 . reverse | |
106 | ||
107 | -- | Reads core-temperatures as data from the system. | |
108 | cTData :: IO [Float] | |
109 | cTData = do fps <- corePaths | |
110 | traverse readSingleFile fps | |
111 | where readSingleFile :: FilePath -> IO Float | |
112 | readSingleFile s = do a <- readFile s | |
113 | return $ parseContent a | |
114 | where parseContent :: String -> Float | |
115 | parseContent = read . head . lines | |
116 | ||
117 | -- | Transforms data of temperatures into temperatures of degree Celsius. | |
118 | parseCT :: IO [Float] | |
119 | parseCT = do rawCTs <- cTData | |
120 | let normalizedCTs = map (/ 1000) rawCTs :: [Float] | |
121 | return normalizedCTs | |
122 | ||
123 | -- | Performs calculation for maximum and average. | |
124 | -- Sets up Bars and Values to be printed. | |
125 | formatCT :: CTOpts -> [Float] -> Monitor [String] | |
126 | formatCT opts cTs = do let CTOpts { mintemp = minT | |
127 | , maxtemp = maxT } = opts | |
128 | domainT = maxT - minT | |
129 | maxCT = maximum cTs | |
130 | avgCT = sum cTs / fromIntegral (length cTs) | |
131 | calcPc t = (t - minT) / domainT | |
132 | maxCTPc = calcPc maxCT | |
133 | avgCTPc = calcPc avgCT | |
134 | ||
135 | cs <- traverse showTempWithColors cTs | |
136 | ||
137 | m <- showTempWithColors maxCT | |
138 | mp <- showWithColors' (show (round (100*maxCTPc) :: Int)) maxCT | |
139 | mb <- showPercentBar maxCT maxCTPc | |
140 | mv <- showVerticalBar maxCT maxCTPc | |
141 | mi <- showIconPattern (maxIconPattern opts) maxCTPc | |
142 | ||
143 | a <- showTempWithColors avgCT | |
144 | ap <- showWithColors' (show (round (100*avgCTPc) :: Int)) avgCT | |
145 | ab <- showPercentBar avgCT avgCTPc | |
146 | av <- showVerticalBar avgCT avgCTPc | |
147 | ai <- showIconPattern (avgIconPattern opts) avgCTPc | |
148 | ||
149 | let ms = [ m , mp , mb , mv , mi ] | |
150 | as = [ a , ap , ab , av , ai ] | |
151 | ||
152 | return (ms ++ as ++ cs) | |
153 | where showTempWithColors :: Float -> Monitor String | |
154 | showTempWithColors = showWithColors (show . (round :: Float -> Int)) | |
155 | ||
156 | ||
157 | runCT :: [String] -> Monitor String | |
158 | runCT argv = do cTs <- io parseCT | |
159 | opts <- io $ parseOpts argv | |
160 | l <- formatCT opts cTs | |
161 | parseTemplate l | |
162 | ||
163 | startMultiCoreTemp :: [String] -> Int -> (String -> IO ()) -> IO () | |
164 | startMultiCoreTemp a = runM a cTConfig runCT |
18 | 18 | |
19 | 19 | import qualified Control.Exception as CE |
20 | 20 | |
21 | #ifdef HTTP_CONDUIT | |
22 | 21 | import Network.HTTP.Conduit |
23 | 22 | import Network.HTTP.Types.Status |
24 | 23 | import Network.HTTP.Types.Method |
25 | 24 | import qualified Data.ByteString.Lazy.Char8 as B |
26 | #else | |
27 | import Network.HTTP | |
28 | #endif | |
25 | import Data.Char (toLower) | |
29 | 26 | |
30 | 27 | import Text.ParserCombinators.Parsec |
31 | 28 | |
46 | 43 | , "windMs" |
47 | 44 | , "visibility" |
48 | 45 | , "skyCondition" |
46 | , "skyConditionS" | |
49 | 47 | , "tempC" |
50 | 48 | , "tempF" |
51 | 49 | , "dewPointC" |
182 | 180 | return [WI st ss y m d h w v sk tC tF dC dF rh p] |
183 | 181 | |
184 | 182 | defUrl :: String |
185 | -- "http://weather.noaa.gov/pub/data/observations/metar/decoded/" | |
186 | defUrl = "http://tgftp.nws.noaa.gov/data/observations/metar/decoded/" | |
183 | defUrl = "https://tgftp.nws.noaa.gov/data/observations/metar/decoded/" | |
187 | 184 | |
188 | 185 | stationUrl :: String -> String |
189 | 186 | stationUrl station = defUrl ++ station ++ ".TXT" |
190 | 187 | |
191 | 188 | getData :: String -> IO String |
192 | #ifdef HTTP_CONDUIT | |
193 | 189 | getData station = CE.catch (do |
194 | 190 | manager <- newManager tlsManagerSettings |
195 | request <- parseUrl $ stationUrl station | |
191 | request <- parseUrlThrow $ stationUrl station | |
196 | 192 | res <- httpLbs request manager |
197 | 193 | return $ B.unpack $ responseBody res |
198 | 194 | ) errHandler |
199 | 195 | where errHandler :: CE.SomeException -> IO String |
200 | 196 | errHandler _ = return "<Could not retrieve data>" |
201 | #else | |
202 | getData station = do | |
203 | let request = getRequest (stationUrl station) | |
204 | CE.catch (simpleHTTP request >>= getResponseBody) errHandler | |
205 | where errHandler :: CE.IOException -> IO String | |
206 | errHandler _ = return "<Could not retrieve data>" | |
207 | #endif | |
208 | ||
209 | formatWeather :: [WeatherInfo] -> Monitor String | |
210 | formatWeather [WI st ss y m d h (WindInfo wc wa wm wk wkh wms) v sk tC tF dC dF r p] = | |
197 | ||
198 | formatSk :: Eq p => [(p, p)] -> p -> p | |
199 | formatSk ((a,b):sks) sk = if a == sk then b else formatSk sks sk | |
200 | formatSk [] sk = sk | |
201 | ||
202 | formatWeather :: [(String,String)] -> [WeatherInfo] -> Monitor String | |
203 | formatWeather sks [WI st ss y m d h (WindInfo wc wa wm wk wkh wms) v sk tC tF dC dF r p] = | |
211 | 204 | do cel <- showWithColors show tC |
212 | 205 | far <- showWithColors show tF |
213 | parseTemplate [st, ss, y, m, d, h, wc, wa, wm, wk, wkh, wms, v, sk, cel, far, show dC, show dF, show r , show p ] | |
214 | formatWeather _ = getConfigValue naString | |
206 | let sk' = formatSk sks (map toLower sk) | |
207 | parseTemplate [st, ss, y, m, d, h, wc, wa, wm, wk, wkh | |
208 | , wms, v, sk, sk', cel, far | |
209 | , show dC, show dF, show r , show p ] | |
210 | formatWeather _ _ = getConfigValue naString | |
215 | 211 | |
216 | 212 | runWeather :: [String] -> Monitor String |
217 | runWeather str = | |
218 | do d <- io $ getData $ head str | |
213 | runWeather = runWeather' [] | |
214 | ||
215 | runWeather' :: [(String, String)] -> [String] -> Monitor String | |
216 | runWeather' sks args = | |
217 | do d <- io $ getData $ head args | |
219 | 218 | i <- io $ runP parseData d |
220 | formatWeather i | |
219 | formatWeather sks i | |
221 | 220 | |
222 | 221 | weatherReady :: [String] -> Monitor Bool |
223 | #ifdef HTTP_CONDUIT | |
224 | 222 | weatherReady str = do |
225 | initRequest <- parseUrl $ stationUrl $ head str | |
223 | initRequest <- parseUrlThrow $ stationUrl $ head str | |
226 | 224 | let request = initRequest{method = methodHead} |
227 | 225 | io $ CE.catch ( do |
228 | 226 | manager <- newManager tlsManagerSettings |
234 | 232 | | statusIsServerError status = False |
235 | 233 | | statusIsClientError status = False |
236 | 234 | | otherwise = True |
237 | #else | |
238 | weatherReady str = do | |
239 | let station = head str | |
240 | request = headRequest (stationUrl station) | |
241 | io $ CE.catch (simpleHTTP request >>= checkResult) errHandler | |
242 | where errHandler :: CE.IOException -> IO Bool | |
243 | errHandler _ = return False | |
244 | checkResult result = | |
245 | case result of | |
246 | Left _ -> return False | |
247 | Right response -> | |
248 | case rspCode response of | |
249 | -- Permission or network errors are failures; anything | |
250 | -- else is recoverable. | |
251 | (4, _, _) -> return False | |
252 | (5, _, _) -> return False | |
253 | (_, _, _) -> return True | |
254 | #endif |
2 | 2 | ----------------------------------------------------------------------------- |
3 | 3 | -- | |
4 | 4 | -- Module : Xmobar.Plugins.Monitors |
5 | -- Copyright : (c) 2010, 2011, 2012, 2013, 2017, 2018 Jose Antonio Ortega Ruiz | |
5 | -- Copyright : (c) 2010, 2011, 2012, 2013, 2017, 2018, 2019 Jose Antonio Ortega Ruiz | |
6 | 6 | -- (c) 2007-10 Andrea Rossato |
7 | 7 | -- License : BSD-style (see LICENSE) |
8 | 8 | -- |
33 | 33 | import Xmobar.Plugins.Monitors.ThermalZone |
34 | 34 | import Xmobar.Plugins.Monitors.CpuFreq |
35 | 35 | import Xmobar.Plugins.Monitors.CoreTemp |
36 | import Xmobar.Plugins.Monitors.MultiCoreTemp | |
36 | 37 | import Xmobar.Plugins.Monitors.Disk |
37 | 38 | import Xmobar.Plugins.Monitors.Top |
38 | 39 | import Xmobar.Plugins.Monitors.Uptime |
71 | 72 | | Brightness Args Rate |
72 | 73 | | CpuFreq Args Rate |
73 | 74 | | CoreTemp Args Rate |
75 | | MultiCoreTemp Args Rate | |
74 | 76 | | TopProc Args Rate |
75 | 77 | | TopMem Args Rate |
76 | 78 | | Uptime Args Rate |
77 | 79 | | CatInt Int FilePath Args Rate |
78 | 80 | #ifdef WEATHER |
79 | 81 | | Weather Station Args Rate |
82 | | WeatherX Station SkyConditions Args Rate | |
80 | 83 | #endif |
81 | 84 | #ifdef UVMETER |
82 | 85 | | UVMeter Station Args Rate |
102 | 105 | type Program = String |
103 | 106 | type Alias = String |
104 | 107 | type Station = String |
108 | type SkyConditions = [(String, String)] | |
105 | 109 | type Zone = String |
106 | 110 | type ZoneNo = Int |
107 | 111 | type Interface = String |
111 | 115 | instance Exec Monitors where |
112 | 116 | #ifdef WEATHER |
113 | 117 | alias (Weather s _ _) = s |
118 | alias (WeatherX s _ _ _) = s | |
114 | 119 | #endif |
115 | 120 | alias (Network i _ _) = i |
116 | 121 | alias (DynNetwork _ _) = "dynnetwork" |
128 | 133 | alias (TopProc _ _) = "top" |
129 | 134 | alias (TopMem _ _) = "topmem" |
130 | 135 | alias (CoreTemp _ _) = "coretemp" |
136 | alias (MultiCoreTemp _ _) = "multicoretemp" | |
131 | 137 | alias DiskU {} = "disku" |
132 | 138 | alias DiskIO {} = "diskio" |
133 | 139 | alias (Uptime _ _) = "uptime" |
158 | 164 | start (TopMem a r) = runM a topMemConfig runTopMem r |
159 | 165 | #ifdef WEATHER |
160 | 166 | start (Weather s a r) = runMD (a ++ [s]) weatherConfig runWeather r weatherReady |
167 | start (WeatherX s c a r) = runMD (a ++ [s]) weatherConfig (runWeather' c) r weatherReady | |
161 | 168 | #endif |
162 | 169 | start (Thermal z a r) = runM (a ++ [z]) thermalConfig runThermal r |
163 | 170 | start (ThermalZone z a r) = |
170 | 177 | start (Brightness a r) = runM a brightConfig runBright r |
171 | 178 | start (CpuFreq a r) = runM a cpuFreqConfig runCpuFreq r |
172 | 179 | start (CoreTemp a r) = runM a coreTempConfig runCoreTemp r |
180 | start (MultiCoreTemp a r) = startMultiCoreTemp a r | |
173 | 181 | start (DiskU s a r) = runM a diskUConfig (runDiskU s) r |
174 | 182 | start (DiskIO s a r) = startDiskIO s a r |
175 | 183 | start (Uptime a r) = runM a uptimeConfig runUptime r |
54 | 54 | -> Parser [[(Widget, ColorString, FontIndex, Maybe [Action])]] |
55 | 55 | stringParser c f a = manyTill (allParsers c f a) eof |
56 | 56 | |
57 | -- | Parses a maximal string without color markup. | |
57 | -- | Parses a maximal string without markup. | |
58 | 58 | textParser :: String -> FontIndex -> Maybe [Action] |
59 | 59 | -> Parser [(Widget, ColorString, FontIndex, Maybe [Action])] |
60 | 60 | textParser c f a = do s <- many1 $ |
2 | 2 | ----------------------------------------------------------------------------- |
3 | 3 | -- | |
4 | 4 | -- Module : Xmobar |
5 | -- Copyright : (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018 Jose Antonio Ortega Ruiz | |
5 | -- Copyright : (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2019 Jose Antonio Ortega Ruiz | |
6 | 6 | -- (c) 2007 Andrea Rossato |
7 | 7 | -- License : BSD-style (see LICENSE) |
8 | 8 | -- |
18 | 18 | , xmobarMain |
19 | 19 | , defaultConfig |
20 | 20 | , configFromArgs |
21 | , tenthSeconds | |
21 | 22 | , Runnable (..) |
22 | 23 | , Exec (..) |
23 | 24 | , Command (..) |
38 | 39 | #endif |
39 | 40 | , module Xmobar.Plugins.Monitors |
40 | 41 | , module Xmobar.Plugins.PipeReader |
42 | , module Xmobar.Plugins.MarqueePipeReader | |
41 | 43 | , module Xmobar.Plugins.StdinReader |
42 | 44 | , module Xmobar.Plugins.XMonadLog |
43 | 45 | ) where |
63 | 65 | import Xmobar.Plugins.Monitors |
64 | 66 | import Xmobar.Plugins.PipeReader |
65 | 67 | import Xmobar.Plugins.StdinReader |
68 | import Xmobar.Plugins.MarqueePipeReader | |
66 | 69 | import Xmobar.Plugins.XMonadLog |
67 | 70 | |
68 | 71 | import Xmobar.App.Main(xmobar, xmobarMain, configFromArgs) |
0 | # Compiling with ghc 8.6.3 | |
1 | resolver: lts-13.0 | |
0 | # Compiling with ghc 8.6.4 | |
1 | resolver: lts-13.17 | |
2 | 2 | |
3 | 3 | # To use ghc 4.4 try: |
4 | 4 | # resolver: lts-12.24 |
17 | 17 | # - parsec-numbers-0.1.0 |
18 | 18 | # - libmpd-0.9.0.9 |
19 | 19 | # - alsa-mixer-0.3.0 |
20 | ||
21 | nix: | |
22 | packages: | |
23 | - alsaLib | |
24 | - pkgconfig | |
25 | - wirelesstools | |
26 | - xorg.libX11 | |
27 | - xorg.libXext | |
28 | - xorg.libXft | |
29 | - xorg.libXpm | |
30 | - xorg.libXrandr | |
31 | - xorg.libXScrnSaver | |
32 | - zlib |
57 | 57 | waiterTaskIsRunning <- newEmptyMVar :: IO (MVar ()) |
58 | 58 | waiterTaskIsWaiting <- newEmptyMVar :: IO (MVar ()) |
59 | 59 | |
60 | withMonitorWaiter fifoPath (Just fakeAlsactlPath) $ \waitFunc -> do | |
60 | let outputCallback msg = fail ("Did not expect the output callback to be invoked (message: "++show msg++")") | |
61 | ||
62 | withMonitorWaiter fifoPath (Just fakeAlsactlPath) outputCallback $ \waitFunc -> do | |
61 | 63 | |
62 | 64 | let addToTimeline e = modifyMVar_ timeline (pure . (e :)) |
63 | 65 |
0 | 0 | name: xmobar |
1 | version: 0.29.4 | |
1 | version: 0.30 | |
2 | 2 | homepage: http://xmobar.org |
3 | 3 | synopsis: A Minimalistic Text Based Status Bar |
4 | 4 | description: Xmobar is a minimalistic text based status bar. |
85 | 85 | flag with_weather |
86 | 86 | description: Enable weather plugin. |
87 | 87 | default: True |
88 | ||
89 | flag with_conduit | |
90 | description: Use http-conduits for weather data, used only if with_weather. | |
91 | default: False | |
92 | 88 | |
93 | 89 | library |
94 | 90 | hs-source-dirs: src |
146 | 142 | Xmobar.Plugins.Monitors.Cpu, |
147 | 143 | Xmobar.Plugins.Monitors.Disk, |
148 | 144 | Xmobar.Plugins.Monitors.Mem, |
145 | Xmobar.Plugins.Monitors.MultiCoreTemp, | |
149 | 146 | Xmobar.Plugins.Monitors.MultiCpu, |
150 | 147 | Xmobar.Plugins.Monitors.Net, |
151 | 148 | Xmobar.Plugins.Monitors.Swap, |
250 | 247 | cpp-options: -DXPM |
251 | 248 | |
252 | 249 | if flag(with_weather) || flag(all_extensions) |
253 | build-depends: HTTP >= 4000.2.4 | |
254 | 250 | exposed-modules: Xmobar.Plugins.Monitors.Weather |
255 | 251 | cpp-options: -DWEATHER |
256 | if flag(with_conduit) | |
257 | -- use http-conduit instead of simple-http | |
258 | build-depends: http-conduit, http-types | |
259 | cpp-options: -DHTTP_CONDUIT | |
260 | ||
261 | if flag(with_uvmeter) && flag(with_conduit) | |
252 | build-depends: http-conduit, http-types | |
253 | ||
254 | if flag(with_uvmeter) | |
262 | 255 | exposed-modules: Xmobar.Plugins.Monitors.UVMeter |
263 | 256 | build-depends: http-conduit, http-types |
264 | 257 | cpp-options: -DUVMETER |