My i3 configurations and scripts.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

i3status.php 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. <?php
  2. class Attribute
  3. {
  4. protected $full_text;
  5. protected $color;
  6. protected $separator = true;
  7. const NORMAL = '#B3FF6C';
  8. const WARNING = '#FF6836';
  9. const CRITICAL = '#FF474A';
  10. const INFO = '#E9F1FF';
  11. const DATE = '#98A6C7';
  12. const MUSIC = '#C3D4FF';
  13. public function __construct($full_text, $color = null, $separator = true)
  14. {
  15. $this->full_text = $full_text;
  16. $this->separator = $separator;
  17. if (null === $color) {
  18. $color = self::NORMAL;
  19. }
  20. $this->color = $color;
  21. }
  22. public function setFullText($full_text)
  23. {
  24. $this->full_text = $full_text;
  25. return $this;
  26. }
  27. public function getFullText()
  28. {
  29. return $this->full_text;
  30. }
  31. public function setColor($color)
  32. {
  33. $this->color = $color;
  34. return $this;
  35. }
  36. public function getColor()
  37. {
  38. return $this->color;
  39. }
  40. public function setSeparator($separator)
  41. {
  42. $this->separator = $separator;
  43. return $this;
  44. }
  45. public function getSeparator()
  46. {
  47. return $this->separator;
  48. }
  49. }
  50. class Element
  51. {
  52. public $attributes = null;
  53. public function __construct()
  54. {
  55. $this->attributes = array();
  56. }
  57. public function setAttributes(array $attributes)
  58. {
  59. $this->attributes = $attributes;
  60. return $this;
  61. }
  62. public function getAttributes()
  63. {
  64. return $this->attributes;
  65. }
  66. public function addAttribute(Attribute $a)
  67. {
  68. $this->attributes[] = $a;
  69. }
  70. }
  71. class i3Bar
  72. {
  73. protected $elements = null;
  74. public function __construct()
  75. {
  76. $this->protected = array();
  77. }
  78. public function setElements(array $elements)
  79. {
  80. $this->elements = $elements;
  81. return $this;
  82. }
  83. public function getElements()
  84. {
  85. return $this->elements;
  86. }
  87. public function addElement($e)
  88. {
  89. if (!empty($e)) {
  90. $this->elements[] = $e;
  91. }
  92. return $this;
  93. }
  94. public function addElementIfNotEmtpy($e)
  95. {
  96. if (empty($e)) {
  97. return $this;
  98. }
  99. return $this->addElement($e);
  100. }
  101. public function __toString()
  102. {
  103. $render = ',[';
  104. foreach ($this->getElements() as $element) {
  105. $attributes = $element->getAttributes();
  106. if (!is_array($attributes)) {
  107. $attributes = array($attributes);
  108. }
  109. if (empty($attributes)) {
  110. continue;
  111. }
  112. $attrs = array();
  113. foreach ($attributes as $attr) {
  114. $attr_render = '{';
  115. if (!$attr->getSeparator()) {
  116. $attr_render .= sprintf('"full_text": "%s",', $attr->getFullText());
  117. $attr_render .= '"separator": false,';
  118. $attr_render .= '"separator_block_width": 0,';
  119. } else {
  120. $attr_render .= sprintf('"full_text": " %s ",', $attr->getFullText());
  121. $attr_render .= '"separator": true,';
  122. $attr_render .= '"separator_block_width": 15,';
  123. }
  124. $attr_render .= sprintf('"color": "%s"', $attr->getColor());
  125. $attr_render .= '}';
  126. $attrs[] = $attr_render;
  127. }
  128. $render .= count($element) > 1 ? '[' : '';
  129. $render .= implode(',', $attrs).',';
  130. $render .= count($element) > 1 ? ']' : '';
  131. }
  132. $render .= ']';
  133. $render = str_replace(',]', ']', $render)."\n";
  134. return $render;
  135. }
  136. }
  137. /**
  138. * IPS.
  139. */
  140. function get_the_ips($ifaces = array())
  141. {
  142. $element = new Element();
  143. foreach ($ifaces as $iface) {
  144. preg_match('`inet ([^\s]+)`', shell_exec('ip addr show '.escapeshellcmd($iface)), $inet);
  145. if ($inet) {
  146. $element->addAttribute(new Attribute('['.$iface.'] '.$inet[1], Attribute::INFO));
  147. }
  148. }
  149. return $element;
  150. }
  151. /**
  152. * BANDWITH.
  153. */
  154. function get_the_bandwith($ifaces = array())
  155. {
  156. $element = new Element();
  157. foreach ($ifaces as $iface) {
  158. preg_match('`inet ([^\s]+)`', shell_exec('ip addr show '.escapeshellcmd($iface)), $inet);
  159. if ($inet) {
  160. $bwidth = explode(' ', preg_replace('/ +/', ' ', trim(shell_exec('ifstat -i '.escapeshellcmd($iface).' 1 1 | tail -n 1'))));
  161. //$dstats = trim(shell_exec('/sbin/ifconfig '.escapeshellcmd($iface).' | grep bytes | sed \'s/[()]//g\' | awk \'{print $3"Mo↓ "$7"Mo↑"}\''));
  162. //$ips[] = '['.$iface.'] '.$bwidth[0].'Ko/s↓ '.$bwidth[1].'Ko/s↑ ('.$dstats.')';
  163. $element->addAttribute(new Attribute('['.$iface.'] '.$bwidth[0].'Ko/s↓ '.$bwidth[1].'Ko/s↑', Attribute::INFO));
  164. }
  165. }
  166. return $element;
  167. }
  168. /**
  169. * SENSORS.
  170. */
  171. function get_sensors()
  172. {
  173. $sensors = array();
  174. preg_match_all('/^([^:]+): +\+([0-9.]+)°C +\(high = \+([0-9.]+)°C, crit = \+([0-9.]+)°C\)/iU', shell_exec('sensors | grep "°C"'), $datas, PREG_SET_ORDER);
  175. var_dump($datas);
  176. foreach ($datas as $data) {
  177. }
  178. return $sensors;
  179. }
  180. function get_sensor($item)
  181. {
  182. get_sensors();
  183. }
  184. /**
  185. * MOUNT.
  186. */
  187. function get_the_mount_space_used($mount_point, $limits = array(70, 90))
  188. {
  189. $element = new Element();
  190. $mount_point = ' '.$mount_point.'$';
  191. $mount = shell_exec('df -h | egrep '.escapeshellcmd($mount_point).' | head -n 1');
  192. if ($mount) {
  193. list($dev, $size, $used, $free, $usedP, $point) = explode(' ', preg_replace('/\s+/', ' ', $mount));
  194. $pourcent = intval($usedP);
  195. if ($pourcent < $limits[0]) {
  196. $color = Attribute::NORMAL;
  197. } elseif ($pourcent < $limits[1]) {
  198. $color = Attribute::WARNING;
  199. } else {
  200. $color = Attribute::CRITICAL;
  201. }
  202. $element->addAttribute(new Attribute('['.$point.'] '.$usedP, $color));
  203. }
  204. return $element;
  205. }
  206. /**
  207. * DATE.
  208. */
  209. function get_the_date()
  210. {
  211. $element = new Element();
  212. $element->addAttribute(new Attribute(date('H:i:s'), Attribute::DATE));
  213. $element->addAttribute(new Attribute(date('d/m/Y'), Attribute::DATE));
  214. return $element;
  215. }
  216. /**
  217. * ACPI.
  218. */
  219. function get_the_acpi()
  220. {
  221. $element = new Element();
  222. $acpi = shell_exec('acpi');
  223. if (!preg_match('`Discharging`', $acpi)) {
  224. preg_match('`([0-9]+%)`', $acpi, $values);
  225. if (!empty($values)) {
  226. $charging = $values[1];
  227. if ($charging < 20) {
  228. $color = Attribute::CRITICAL;
  229. } elseif ($charging < 50) {
  230. $color = Attribute::WARNING;
  231. } else {
  232. $color = Attribute::NORMAL;
  233. }
  234. $charging .= '↑';
  235. $element->addAttribute(new Attribute($charging, $color));
  236. }
  237. return $element;
  238. }
  239. preg_match('`([0-9]+%), ([0-9]+:[0-9]+)`', $acpi, $values);
  240. if ($values[1] < 20) {
  241. $color = Attribute::CRITICAL;
  242. } elseif ($values[1] < 50) {
  243. $color = Attribute::WARNING;
  244. } else {
  245. $color = Attribute::INFO;
  246. }
  247. $charging = $values[1].'↓';
  248. $times = str_replace(':', 'h', $values[2]);
  249. $element->addAttribute(new Attribute(implode(' ', array($charging, $times)), $color));
  250. return $element;
  251. }
  252. /**
  253. * MUSIC.
  254. */
  255. function get_the_master_volume()
  256. {
  257. $element = new Element();
  258. $volume = shell_exec('amixer get Master | grep Mono:');
  259. if ($volume) {
  260. preg_match('/\[([0-9%]+)\]/', $volume, $mach);
  261. if (isset($mach[1])) {
  262. $element->addAttribute(new Attribute($mach[1].' ♪', Attribute::MUSIC));
  263. }
  264. }
  265. return $element;
  266. }
  267. function get_the_public_ip($ipv6 = false)
  268. {
  269. $element = new Element();
  270. $memcache = new Memcached();
  271. $key = $ipv6 ? 'ipv6' : 'ipv4';
  272. $cache = 60 * 5;
  273. $memcache->addServer('localhost', 11211);
  274. $ip = $memcache->get($key);
  275. if (empty($ip)) {
  276. $ip = trim(shell_exec('wget -O - -q '.($ipv6 ? '-6' : '').' ip.deblan.org | head -n 1 | cut -c1-50'));
  277. if ($ip === '192.168.0.254') {
  278. $ip = trim(shell_exec('wget -O - -q '.($ipv6 ? '-6' : '').' "https://api.ipify.org/?format=text" | head -n 1 | cut -c1-50'));
  279. } elseif (empty($ip)) {
  280. $ip = '?';
  281. }
  282. $memcache->set($key, '[wan] '.$ip, $cache);
  283. }
  284. $memcache->quit();
  285. $element->addAttribute(new Attribute($ip, Attribute::INFO));
  286. return $element;
  287. }
  288. function get_the_public_ipv4()
  289. {
  290. return get_the_public_ip();
  291. }
  292. function get_the_public_ipv6()
  293. {
  294. return get_the_public_ip(true);
  295. }
  296. function get_spotify_metadata()
  297. {
  298. $status = trim(shell_exec('playerctl -p spotify status'));
  299. //if (!in_array($status, ['Playing', 'Paused'])) {
  300. if (!in_array($status, ['Playing'])) {
  301. return null;
  302. }
  303. // $status = str_replace(
  304. // ['Playing', 'Paused'],
  305. // ['▮▮', '▶'],
  306. // $status
  307. // );
  308. $cleanup = function($d) {
  309. $string = trim(str_replace(['"', "'"], ' ', $d));
  310. if (mb_strlen($string) > 15) {
  311. $string = substr($string, 0, 15).'…';
  312. }
  313. return $string;
  314. };
  315. $title = $cleanup(shell_exec('playerctl -p spotify metadata xesam:title'));
  316. $artist = $cleanup(shell_exec('playerctl -p spotify metadata xesam:artist'));
  317. $label = sprintf('%s – %s', $title, $artist);
  318. $element = new Element();
  319. $element->addAttribute(new Attribute($label, Attribute::MUSIC));
  320. return $element;
  321. }
  322. $bar = new i3Bar();
  323. $bar
  324. ->addElement(get_the_bandwith(array('eth0', 'eth1', 'wlan0', 'easytether0')))
  325. ->addElement(get_the_ips(array('eth0', 'eth1', 'wlan0', 'easytether0')))
  326. ->addElement(get_the_public_ipv4())
  327. ->addElement(get_the_mount_space_used('/'))
  328. ->addElement(get_the_mount_space_used('/home', array(80, 90)))
  329. ->addElement(get_the_mount_space_used('/share'))
  330. ->addElement(get_the_mount_space_used('/secured'))
  331. ->addElementIfNotEmtpy(get_spotify_metadata())
  332. ->addElement(get_the_master_volume())
  333. ->addElement(get_the_date())
  334. ->addElement(get_the_acpi())
  335. ;
  336. echo $bar;