Оригинальные настройки conky я взял отсюда. В этот пакет, кроме собственно конфигураций окон, входят шрифты для отображения простого текста и погодных символов. К сожалению, в мае этого года окно weather_date перестало показывать погоду. Как выяснилось, это окно использует yahooapis, а Yahoo изменил свой API как раз в это время. В общем, пришлось переписать это окно для новых yahooapis, а заодно улучшить производительность за счет уменьшения вызовов процессов-фильтров, познакомиться с замечательным парсером JSON jq и перевести настройки в новый формат с помощью скрипта convert.lua, который поставляется вместе с обновленным conky.
На следующей картинке показано, как выглядит окно weather_date на моих рабочем и домашнем компьютерах.
Запускать conky с окном weather_date нужно так:
conky -c ~/.grayscale/conkyrc/weather_date
А это сам скрипт weather_date.
conky.config = {
--###############
--###############PERFORMANCE_SETTINGS
--###############
update_interval = 5,
total_run_times = 0,
net_avg_samples = 2,
imlib_cache_size = 0,
double_buffer = true,
no_buffers = true,
--###############
--###############TEXT_SETTINGS
--###############
use_xft = true,
font = 'GE Inspira:bold:pixelsize=12',
xftalpha = 0.1,
override_utf8_locale = true,
text_buffer_size = 512,
--###############
--###############WINDOW_SPECIFICATIONS
--###############
background = true,
own_window = true,
own_window_transparent = true,
own_window_type = 'normal',
own_window_class = 'conky-semi',
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
own_window_argb_visual = true,
own_window_argb_value = 0,
draw_outline = false,
--# Window border
draw_borders = false,
pad_percents = 0,
border_inner_margin = 4,
top_name_width = 10,
use_spacer = 'right',
--#Size and position
alignment = 'top_left',
gap_x = 1600,
gap_y = 58,
minimum_width = 0, minimum_height = 0,
maximum_width = 240,
--###############
--###############GRAPHICS_SETTINGS
--###############
draw_shades = false,
default_shade_color = '#292421',
short_units = true,
--#Default Colors
default_color = '#efefef',
default_shade_color = '#1d1d1d',
--#Color Title
color1 = '#bcbcbc',
color2 = '#00d787',
color3 = '#00d787',
};
conky.text = [[
#################
#################DATE & TIME
#################
${voffset 10}${font GE Inspira:pixelsize=50}${color1}${time %H:%M}\
${voffset -20}${offset 5}${font GE Inspira:pixelsize=25}${color2}${time %d}\
${voffset -15}${font GE Inspira:pixelsize=20}${color1}${time %b}${time %Y}\
${voffset 35}${offset -105}${font GE Inspira:pixelsize=22}${color1}${time %A}\
${color}${font}
${voffset 5}${color3}${hr 2}${color}\
################
################DOWNLOADING WEATHER INFO AND SAVING IT AS ~/.cache/weather.json
################
${execi 1800 nm-online -t 60 && curl -s \
-G 'http://query.yahooapis.com/v1/public/yql?format=json' \
--data-urlencode 'q=select * from weather.forecast where woeid in \
(select woeid from geo.places(1) where text="Saint-Petersburg, Russia") \
and u="c"' -o ~/.cache/weather.json}
################MAIN WEATHER IMAGE
${voffset -10}${offset 20}${font conkyweather:size=140}${color1}\
${execi 1800 grep "^$(jq -r '.query.results.channel.item.condition.code' \
~/.cache/weather.json) =" ~/.grayscale/data/compare | cut -d " " -f3}\
${color}${font}
################WEATHER CONDITIONS
${alignc 10}${font GE Inspira:bold:pixelsize=15}${color2}\
${execi 1800 jq -r '.query.results.channel.item.condition.text' \
~/.cache/weather.json}${color}${font}
##############EXTRACTING CURRENT/HIGH TEMP IN DEGREE CELSIUS
${offset 30}${font GE Inspira:pixelsize=50}${color3}\
${execi 1800 jq -r '.query.results.channel.item.condition.temp' \
~/.cache/weather.json}°C/${font GE Inspira:pixelsize=30}\
${color3}${execi 1800 jq -r '.query.results.channel.item.forecast[0].high' \
~/.cache/weather.json}°C\
${color}${font}\
#################
#################EXTRACTING LOCATION
#################
${voffset 16}${offset 16}${font GE Inspira:bold:pixelsize=20}${color1}\
${execi 1800 jq -j '.query.results.channel.location | .city + ", ", .country' \
~/.cache/weather.json}${color}${font}
${color3}${hr 2}${color}\
#################
#################EXTRACTING WEATHER INFO
#################
##PRESSURE HUMIDITY
${voffset 5}${font GE Inspira:bold:pixelsize=12}${color2}\
Pressure : ${color1}\
${execi 1800 jq -r '.query.results.channel.atmosphere.pressure' \
~/.cache/weather.json}mb\
${alignr -16}${font GE Inspira:bold:pixelsize=12}${color2}\
Humidity : ${color1}\
${execi 1800 jq -r '.query.results.channel.atmosphere.humidity' \
~/.cache/weather.json}%\
${color}${font}
##SUNRISE SUNSET
${font GE Inspira:bold:pixelsize=12}${color2}\
Sunrise : ${color1}\
${execi 1800 jq -r '.query.results.channel.astronomy.sunrise' \
~/.cache/weather.json}\
${alignr -16}${font GE Inspira:bold:pixelsize=12}${color2}\
Sunset : ${color1}\
${execi 1800 jq -r '.query.results.channel.astronomy.sunset' \
~/.cache/weather.json}${color}${font}
##WIND VISIBILITY
${font GE Inspira:bold:pixelsize=12}${color2}\
Wind : ${color1}${execi 1800 jq -r '.query.results.channel.wind.speed' \
~/.cache/weather.json}km/hr\
${alignr -16}${font GE Inspira:bold:pixelsize=12}${color2}\
Visibility : ${color1}\
${execi 1800 jq -r '.query.results.channel.atmosphere.visibility' \
~/.cache/weather.json}km${color}${font}
${color3}${hr 2}${color}\
#################
#################WEATHER FORECAST IMAGES FOR NEXT 2 DAYS
#################
${voffset 10}${font conkyweather:size=70}${color1}\
${execi 1800 grep "^$(jq -r '.query.results.channel.item.forecast[1].code' \
~/.cache/weather.json) =" ~/.grayscale/data/compare | cut -d " " -f3}\
${tab 72}${font conkyweather:size=70}${color1}\
${execi 1800 grep "^$(jq -r '.query.results.channel.item.forecast[2].code' \
~/.cache/weather.json) =" ~/.grayscale/data/compare | cut -d " " -f3}\
${color}${font}\
#################
#################EXTRACTING LOW/HIGH TEMP IN DEGREE CELSIUS FOR NEXT 2 DAYS
#################
${font GE Inspira:bold:pixelsize=15}${color2}\
${execi 1800 jq -r '.query.results.channel.item.forecast[1].day' \
~/.cache/weather.json} : ${font GE Inspira:bold:pixelsize=15}${color1}\
${execi 1800 jq -r '.query.results.channel.item.forecast[1].low' \
~/.cache/weather.json}°/${font GE Inspira:bold:pixelsize=15}${color1}\
${execi 1800 jq -r '.query.results.channel.item.forecast[1].high' \
~/.cache/weather.json}°\
${alignr -16}${font GE Inspira:bold:pixelsize=15}${color2}\
${execi 1800 jq -r '.query.results.channel.item.forecast[2].day' \
~/.cache/weather.json} : ${font GE Inspira:bold:pixelsize=15}${color1}\
${execi 1800 jq -r '.query.results.channel.item.forecast[2].low' \
~/.cache/weather.json}°/${font GE Inspira:bold:pixelsize=15}${color1}\
${execi 1800 jq -r '.query.results.channel.item.forecast[2].high' \
~/.cache/weather.json}°${color}${font}
${voffset 5}${color3}${hr 2}${color}\
#################
#################CALENDER DISPLAY
#################
${voffset 10}${font nimbus mono L:bold:size=12}${color1}\
${execpi 1800 DJS=`date +%_d`; cal | \
sed -e s/"\(^\|[^0-9]\)$DJS"'\b'/'\1${color2}'"$DJS"'$color'/ -e s/^/' '/}
]];
Внутри conky.config находятся настройки геометрии окна, объявляются различные цвета и т.п. Собственно содержимое окна описано внутри conky.text. В параграфе, озаглавленном как DOWNLOADING WEATHER …, каждые полчаса (1800 секунд) с помощью execi и curl, после предварительной проверки доступности сети командой nm-online, выполняется запрос на query.yahooapis.com в формате YQL (Yahoo! Query Language). Ответ от Yahoo сохраняется в файле ~/.cache/weather.json. Обратите внимание на то, что данная команда execi ничего не выводит на экран, то есть фактически в данном случае conky работает как cron!
Я выбрал формат вывода JSON потому, что он легко и непринужденно парсится прямо из командной строки командой jq, которая позволяет задавать довольно сложные фильтры для поиска данных, предоставляя своеобразный язык запросов, который очень подробно, с примерами, описан в man jq. Все оставшиеся параграфы внутри conky.text вплоть до вывода календаря вызывают jq для поиска значений определенных погодных категорий внутри файла ~/.cache/weather.json. Например, внутри параграфа EXTRACTING LOCATION выполняется запрос jq -j '.query.results.channel.location | .city + ", ", .country' ~/.cache/weather.json
, который выводит значения city и country, находящиеся в пути /query/results/channel/location структуры JSON и выводит их в одной строке (опция -j
).
Поскольку jq работает из командной строки, имеется возможность выводить погодные условия прямо на терминал! Например, погоду на завтра можно вывести командой
jq '.query.results.channel.item.forecast[1]' ~/.cache/weather.json
{
"code": "12",
"date": "07 Jul 2016",
"day": "Thu",
"high": "17",
"low": "12",
"text": "Rain"
}
При этом вывод в терминале будет синтаксически подсвечен!
А теперь о выводе информации из cmus. Cmus — это аудиоплеер для терминала. В оригинальном пакете была представлена поддержка плеера clementine, но я им не пользуюсь. Информация из clementine выводилась в окне net_hdd с помощью execpi 2 ~/.grayscale/data/clementine
, скрипт clementine в директории ~/.grayscale/data/ был написан на perl. Сначала я написал аналогичный скрипт cmus, тоже на perl, но в новом conky большое количество проблем заставило переписать его на lua и загружать в conky командой lua_load.
Вот так выглядит информация из cmus, когда он запущен.
Для того, чтобы это заработало, в net_hdd, предварительно обработанном скриптом convert.lua, внутрь conky.config нужно добавить строку
lua_load = '~/.grayscale/data/cmus.lua',
Внутрь conky.text, вместо настроек для clementine, нужно добавить строки
################
################CMUS_DISPLAY
################
${voffset 5}${offset 22}\
${font GE Inspira:bold:pixelsize=15}${color2}CMUS${voffset 2}\
${offset 5}${color3}${hr 2}${color}${font}
${if_running cmus}${lua_parse cmus}${else}${voffset 46}${endif}
Обратите внимание, что в случае, когда cmus не запущен, в окно net_hdd выводится пустой вертикальный сдвиг высотой 46 пикселей: это сделано для того, чтобы окно не мерцало при запуске и закрытии cmus. Величина сдвига была определена экспериментально: она должна точно соответствовать высоте совокупной информации из cmus, когда он запущен, выводимой conky. Кроме того, стоит отметить, что lua_parse, в отличие от execpi, не имеет собственной настройки интервала обновления данных, а следовательно скорость обновления данных определяется системной настройкой окна update_interval внутри conky.config.
Скрипт cmus.lua в директории ~/.grayscale/data/ выглядит так.
function conky_echo(a)
return a
end
function conky_cmus()
local artist = 'N/A';
local title = 'N/A';
local album = 'N/A';
local progress = 0;
local pos = 0;
local length = 0;
local status = '';
local color1 = 'bcbcbc';
local color2 = 'ffa300';
local color3 = 'ffff5f';
f = assert( io.popen( 'cmus-remote -Q' ) ) or os.exit( 1 )
for line in f:lines() do
local v = string.match( line, '^status%s*(.*)' )
if v ~= nil and v ~= '' and v ~= 'playing' then
status = ' [' .. v .. ']'; goto next
end
v = string.match( line, '^duration%s*(.*)' )
if v ~= nil and v ~= '' then length = tonumber( v ); goto next end
v = string.match( line, '^position%s*(.*)' )
if v ~= nil and v ~= '' then pos = tonumber( v ); goto next end
v = string.match( line, '^tag album%s*(.*)' )
if v ~= nil and v ~= '' then album = v; goto next end
v = string.match( line, '^tag artist%s*(.*)' )
if v ~= nil and v ~= '' then artist = v; goto next end
v = string.match( line, '^tag title%s*(.*)' )
if v ~= nil and v ~= '' then title = v; goto next end
::next::
end
f:close()
if pos > 0 and length > 0 then
progress = math.floor( 100 * pos / length )
end
return '${voffset 5}${offset 6}${font StyleBats:size=10}${color ' ..
color1 .. '}k${voffset -2}${offset 3}${color ' .. color2 ..
'}${font}Title: ${color ' .. color3 .. '}${alignr}' .. title ..
'${color ' .. color2 .. '}' .. status ..
'\n${offset 6}${font StyleBats:size=10}${color ' .. color1 ..
'}k${voffset -2}${offset 3}${color ' .. color2 ..
'}${font}Artist: ${color ' .. color3 .. '}${alignr}' .. artist ..
'\n${offset 6}${font StyleBats:size=10}${color ' .. color1 ..
'}k${voffset -2}${offset 3}${color ' .. color2 ..
'}${font}Album: ${color ' .. color3 .. '}${alignr}' .. album ..
'${color ' .. color1 .. '}${font}' ..
'\n${voffset 1}${offset 8}${lua_bar echo ' .. progress .. '}'
end
Прошу меня простить, если что-то здесь сделано неизящно или неэффективно — это моя первая программа на lua :)