Dk75 schedule.module (en)
From Conky PitStop
dk75_schedule.module
| Language | English Français |
Calendar/schedule for One4All project
Dk75 schedule.module-1.2.4.tar.gz
--[[
schedule.module
Displays calendars (current mont and as many previous and next month as you like - additional months are evenly divided betwen previous and next periods) with additional text displayed in every day cell.
Either it could be some short text message or colored background.
Data format of data/schedule-${year}-${month}.txt file (each months with it's own file):
day text
day text
eg.
1 9:00 # some event at 9:00 at first day
2 holiday # holiday event at second day
3 x # colored box at thrid day
See example files in data/ directory.
changelog:
v1.2.4 - (21.06.2012) moving box drawing function to functions part of One4All
v1.2.3 - first public release
--]]
local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M
--[[
###############################################################################
### SETTINGS ###
###############################################################################
--]]
local settings_table = {
{
drawGrid = false, --draw helper grid (true) or don't (false)
horizontal = true, --should graph be horizontaly (true) or verticaly (false) aligned
date_align = 'left', --align of date number: 'left', 'right' or 'center'
schedule_align = 'right', --align of schedule: 'left', 'right' or 'center'
calendar_update = 300, --number of conky updates after which calendar will update
numberOfMonth = 3, --number of month to include in graph
cellSize = 50, --one day cell size both width and height (square cell)
cellGapDivider = 20, --is used to calculate gap between of cels as "cellGap = cellSize / cellGapDivider"
graphGapMultiplier = 3, --is used to calculate gap between of graphs as "graphGap = cellGap * graphGapMultiplier"
corner_rG = 10, --rounding of graph corners in percents
corner_rC = 50, --rounding of cell corners in percents
startX = 0, --upper left corner x-axis start of graph
startY = 0, --upper left corner y-axis start of graph
color_G = 0x000000, --graph shadow color
alpha_G = 0.7, --graph shadow alpha
color_C = 0x00afff, --cell color
alpha_C = 0.5, --cell alpha
color_W = 0x00ff00, --weekday color
color_Sa = 0xffff00, --saturday color
color_Su = 0xff0000, --sunday color
color_M = 0xffffff, --month and separation bar color
color_N = 0xff0000, --current day rim color
alpha_N = 1, --current day rim alpha
-- don't modyfi settings below
sizeW = 0, --don't modyfi - it's no use to set this because it will be rewrited after start
sizeH = 0, --don't modyfi - it's no use to set this because it will be rewrited after start
sizeAll = 0, --don't modyfi - it's no use to set this because it will be rewrited after start
cellGap = 0, --don't modyfi - it's no use to set this because it will be rewrited after start
graphGap = 0, --don't modyfi - it's no use to set this because it will be rewrited after start
_date = os.date('*t'), --don't modyfi
_calendar = {}, --don't modyfi
isMondayFirtsDayOfTheWeek = tonumber(one4all_main.os_capture('locale first_weekday','raw')) - 1, --don't modyfi
},
}
--[[
###############################################################################
### END OF SETTINGS ###
###############################################################################
--]]
function M.errors(t, _errorNo)
local sizeW, sizeH = t.sizeW+t.startX, t.sizeH+t.startY
if t.horizontal then sizeW = t.sizeAll+t.startX else sizeH = t.sizeAll+t.startY end
local _errors = {
"Check size error! Schedule graph " .. sizeW .. "x" .. sizeH .. " is bigger than Conky window " .. conky_window.width .. "x" .. conky_window.height .. " !!!",
"Warning! Can't read one or all schedule text file",
}
print(_errors[_errorNo])
end
function M.check_size(t)
t.cellGap = math.floor(t.cellSize/t.cellGapDivider)
t.graphGap = math.floor(t.cellGap*t.graphGapMultiplier)
t.sizeW = (t.cellSize + t.cellGap) * 7
t.sizeH = math.floor(t.sizeW + t.cellSize * 0.5)
if t.horizontal
then
t.sizeAll = t.sizeW * t.numberOfMonth + t.graphGap * (t.numberOfMonth -1)
--print(t.sizeAll+t.startX, t.sizeH+t.startY)
--print("Cell size: " .. t.cellSize , "Cell gap: " .. t.cellGap , "Size of 1 graph: " .. t.sizeW .. " x " .. t.sizeH, "Graph gap: " .. t.graphGap, "Size: " .. t.sizeAll .. " x " .. t.sizeH)
if t.sizeAll + t.startX > conky_window.width or t.sizeH + t.startY > conky_window.height then return false else return true end
else
t.sizeAll = t.sizeH * t.numberOfMonth + t.graphGap * (t.numberOfMonth -1)
--print(t.sizeAll+t.startY, t.sizeW+t.startX)
--print("Cell size: " .. t.cellSize , "Cell gap: " .. t.cellGap , "Size of 1 graph: " .. t.sizeW .. " x " .. t.sizeH, "Graph gap: " .. t.graphGap, "Size: " .. t.sizeW .. " x " .. t.sizeAll)
if t.sizeAll + t.startY > conky_window.height or t.sizeW + t.startX > conky_window.width then return false else return true end
end
end
function M.setlocale()
local _locale = os.setlocale(nil, 'ctype')
os.setlocale(_locale, 'all')
end
function M.init_calendar(t)
local _date, _tmp, dateMod, dateF, _t, _error = {}, {}, 0, , 0, 0
_date.year, _date.month, _date.day = t._date.year, t._date.month-math.floor(t.numberOfMonth/2), 1
if t.isMondayFirtsDayOfTheWeek == 1
then dateMod, dateF = 0, "%u"
else dateMod, dateF = 1, "%w"
end
for i=1, t.numberOfMonth, 1
do
_t = 0
for j=1, 42, 1
do
if j < os.date(dateF, os.time(_date))+dateMod then _tmp[j] = { day = , schedule = }; _t = j
elseif j == _date.day+_t then _tmp[j] = { day = os.date('%d', os.time(_date)), schedule = }; _date.day = _date.day+1
if _date.day ~= tonumber(os.date('%d', os.time(_date))) then _date.day = _date.day-1 end
else _tmp[j] = { day = , schedule = }
end
end
--print('/data/schedule-' .. _date.year .. "-" .. string.format('%02d', _date.month) .. '.txt')
if io.open(_conky_path .. '/data/schedule-' .. _date.year .. "-" .. string.format('%02d', _date.month) .. '.txt') then
for l in io.lines(_conky_path .. '/data/schedule-' .. _date.year .. "-" .. string.format('%02d', _date.month) .. '.txt') do
local _day, _schedule = l:match '(%S+)%s+(%S+)'
if _day == nil then break end
local j=0
repeat
j=j+1
until _tmp[j].day == string.format('%02d', _day)
_tmp[j].schedule = _schedule
end
else _error=2
end
t._calendar[i]=_tmp
_tmp = {}
_date.day=1
_date.month=_date.month+1
end
return _error
end
function M.align(textAlign, textSize, cellSize, cellGap)
if textAlign == 'center' then return cellGap/2 + cellSize/2 - textSize/2
elseif textAlign == 'left' then
if textSize > cellSize/2 - cellGap*2 then return cellGap*2
else return cellGap/2 + cellSize/2 - textSize end
else
if textSize > cellSize/2 - cellGap*2 then return cellGap/2 + cellSize - textSize - cellGap*2
else return cellGap/2 + cellSize/2 end
end
end
function M.draw_grid(t, modX, modY)
cairo_set_source_rgba(cr, 1, 1, 1, 0.5)
cairo_move_to(cr, t.startX+modX, t.startY+modY)
cairo_line_to(cr, t.startX+modX+t.sizeW, t.startY+modY)
cairo_line_to(cr, t.startX+modX+t.sizeW, t.startY+modY+t.sizeH)
cairo_line_to(cr, t.startX+modX, t.startY+modY+t.sizeH)
cairo_line_to(cr, t.startX+modX, t.startY+modY)
cairo_stroke(cr)
for i=1, 7, 1
do
cairo_move_to(cr, t.startX+modX+(t.cellSize+t.cellGap)*i, t.startY+modY)
cairo_line_to(cr, t.startX+modX+(t.cellSize+t.cellGap)*i, t.startY+modY+t.sizeH)
cairo_move_to(cr, t.startX+modX, t.startY+modY+(t.cellSize+t.cellGap)*i+t.cellSize*0.5)
cairo_line_to(cr, t.startX+modX+t.sizeW, t.startY+modY+(t.cellSize+t.cellGap)*i+t.cellSize*0.5)
cairo_stroke(cr)
end
end
function M.draw_graph(t)
local modX, modY, weekS, dateF = 0, 0, 0, ""
local _date, _week = {}, {}
_date.year = t._date.year
_date.month = t._date.month-math.floor(t.numberOfMonth/2)
_date.day = 1
if t.isMondayFirtsDayOfTheWeek == 1
then weekS, dateF, _week.day, _week.month, _week.year = 1, "%u", 1, 12, 1997
else weekS, dateF, _week.day, _week.month, _week.year = 0, "%w", 7, 12, 1997
end
if t.horizontal then modX = t.sizeW + t.graphGap else modY = t.sizeH + t.graphGap end
for i=0, t.numberOfMonth-1, 1
do
-- draw shadow box and/or grid for every graph
one4all_cairo.draw_box(cr, t.startX+(modX*i), t.startY+(modY*i), t.sizeW, t.sizeH, t.corner_rG, t.color_G, t.alpha_G)
if t.drawGrid then M.draw_grid(t, modX*i, modY*i) end
local extents = cairo_text_extents_t:create() -- initialize text_extents structure (generic, a must be for following functions)
-- print month name
cairo_select_font_face(cr, "DejaVu Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
cairo_set_font_size(cr, t.cellSize/2)
local _text = os.date('%B', os.time(_date))
cairo_text_extents(cr, _text, extents)
cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_M, 1))
cairo_move_to(cr, t.startX+modX*i+t.sizeW/2-extents.width/2, t.startY+modY*i+math.floor(t.cellSize/2)+t.cellGap*2)
cairo_show_text(cr, _text)
cairo_stroke(cr)
_date.month = _date.month+1
--]]
-- print week days names
cairo_select_font_face(cr, "DejaVu Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
cairo_set_font_size(cr, t.cellSize/2.8)
for j=weekS, weekS+6, 1
do
_week.day = j
local _text = os.date('%a', os.time(_week))
cairo_text_extents(cr, _text, extents)
cairo_move_to(cr, t.startX+modX*i+((t.cellSize+t.cellGap)*(j-weekS))+t.cellGap/2+t.cellSize/2-extents.width/2, t.startY+modY*i+t.cellSize+t.cellGap*2)
if j==0 or j==7 then cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_Su, 1))
elseif j==6 then cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_Sa, 1))
else cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_W, 1))
end
cairo_show_text(cr, _text)
cairo_stroke(cr)
end
--]]
-- draw separation bar
local _pat = cairo_pattern_create_linear(0, t.startY+modY*i+t.cellSize*1.5-t.cellGap/2-t.cellSize/5, 0, t.startY+modY*i+t.cellSize*1.5-t.cellGap/2)
cairo_pattern_add_color_stop_rgba(_pat, 0, one4all_cairo.rgb2rgba(0x000000, 0.2))
cairo_pattern_add_color_stop_rgba(_pat, 0.1, one4all_cairo.rgb2rgba(t.color_M, 0.2))
cairo_pattern_add_color_stop_rgba(_pat, 0.3, one4all_cairo.rgb2rgba(t.color_M, 0.7))
cairo_pattern_add_color_stop_rgba(_pat, 0.4, one4all_cairo.rgb2rgba(t.color_M, 0.9))
cairo_pattern_add_color_stop_rgba(_pat, 0.5, one4all_cairo.rgb2rgba(t.color_M, 1))
cairo_pattern_add_color_stop_rgba(_pat, 0.6, one4all_cairo.rgb2rgba(t.color_M, 0.9))
cairo_pattern_add_color_stop_rgba(_pat, 0.7, one4all_cairo.rgb2rgba(t.color_M, 0.7))
cairo_pattern_add_color_stop_rgba(_pat, 0.9, one4all_cairo.rgb2rgba(t.color_M, 0.2))
cairo_pattern_add_color_stop_rgba(_pat, 1, one4all_cairo.rgb2rgba(0x000000, 0.2))
cairo_set_source(cr, _pat)
cairo_move_to(cr, t.startX+modX*i+t.cellGap*4, t.startY+modY*i+t.cellSize*1.5-t.cellGap/2-t.cellSize/10)
cairo_line_to(cr, t.startX+modX*i+t.sizeW-t.cellGap*4, t.startY+modY*i+t.cellSize*1.5-t.cellGap/2-t.cellSize/10)
cairo_set_line_width (cr, t.cellSize/5)
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND)
cairo_stroke(cr)
cairo_pattern_destroy(_pat)
cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT)
cairo_set_line_width (cr, 1)
--]]
-- print schedule
cairo_select_font_face(cr, "DejaVu Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
for j=1, 42, 1 do
if j < 14 and t._calendar[i+1][j].day == nil then break end
local _t_int, _t_frac = math.modf(j/7); if _t_int > 0 and _t_frac == 0 then _t_int = _t_int - 1 end
if t._calendar[i+1][j].schedule == 'x' then
one4all_cairo.draw_box(cr, t.startX+modX*i+(t.cellSize+t.cellGap)*(j-1-_t_int*7)+t.cellGap, t.startY+modY*i+t.cellSize*1.5+(t.cellSize+t.cellGap)*_t_int+t.cellGap*2, t.cellSize-t.cellGap, t.cellSize-t.cellGap, t.corner_rC, t.color_C, t.alpha_C)
elseif t._calendar[i+1][j].schedule ~= nil then
local _text = t._calendar[i+1][j].schedule
local _div = 1
repeat
cairo_set_font_size(cr, (t.cellSize/2.5)/_div)
cairo_text_extents(cr, _text, extents)
_div = _div + 0.2
until extents.width < t.cellSize-t.cellGap*4
local _position = M.align(t.schedule_align, extents.width, t.cellSize, t.cellGap)
cairo_move_to(cr, t.startX+modX*i+(t.cellSize+t.cellGap)*(j-1-_t_int*7)+_position, t.startY+modY*i+t.cellSize*1.5+(t.cellSize+t.cellGap)*_t_int+t.cellGap+t.cellSize/2+extents.height+t.cellGap/2)
cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_M, 1))
cairo_show_text(cr, _text)
cairo_stroke(cr)
end
end
--]]
-- print month days numbers
cairo_select_font_face(cr, "DejaVu Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD)
cairo_set_font_size(cr, t.cellSize/3)
--cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_M, 1))
for j in pairs(t._calendar[i+1])
do
--print("Graph No.: " .. i, "Filed No.: " .. j, "Day: " .. t._calendar[i+1][j].day)
if t._calendar[i+1][j] ~= then
local _t_int, _t_frac = math.modf(j/7); if _t_int > 0 and _t_frac == 0 then _t_int = _t_int - 1 end
local _text = t._calendar[i+1][j].day
cairo_text_extents(cr, _text, extents)
local _position = M.align(t.date_align, extents.width, t.cellSize, t.cellGap)
if ( j-_t_int*7==1 and t.isMondayFirtsDayOfTheWeek~=1 ) or ( j-_t_int*7==7 and t.isMondayFirtsDayOfTheWeek==1 ) then cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_Su, 1))
elseif ( j-_t_int*7==6 and t.isMondayFirtsDayOfTheWeek==1 ) or ( j-_t_int*7==7 and t.isMondayFirtsDayOfTheWeek~=1 ) then cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_Sa, 1))
else cairo_set_source_rgba(cr, one4all_cairo.rgb2rgba(t.color_W, 1))
end
cairo_move_to(cr, t.startX+modX*i+(t.cellSize+t.cellGap)*(j-1-_t_int*7)+_position, t.startY+modY*i+t.cellSize*1.5+(t.cellSize+t.cellGap)*_t_int+t.cellGap+t.cellSize/2-t.cellGap/2)
cairo_show_text(cr, _text)
cairo_stroke(cr)
end
end
--]]
end
-- draw rim
local _nowGraph = math.floor(t.numberOfMonth/2)
local _nowDay = os.date('%d'); --_nowDay = '30'
local _nowCell = 0
repeat
_nowCell=_nowCell+1
until _nowDay == t._calendar[_nowGraph+1][_nowCell].day
local _t_int, _t_frac = math.modf(_nowCell/7); if _t_int > 0 and _t_frac == 0 then _t_int = _t_int - 1 end
one4all_cairo.draw_box(cr, t.startX+modX*_nowGraph+(t.cellSize+t.cellGap)*(_nowCell-1-_t_int*7)+t.cellGap, t.startY+modY*_nowGraph+t.cellSize*1.5+(t.cellSize+t.cellGap)*_t_int+t.cellGap*2, t.cellSize-t.cellGap, t.cellSize-t.cellGap, t.corner_rC, t.color_N, t.alpha_N, true)
--]]
end
function M.schedule(t)
local _error = 0
if not M.check_size(t) then return 1 end
if t._calendar[1] == nil then _error = M.init_calendar(t); end
local _upInt, _upFrac = math.modf(tonumber(conky_parse("${updates}"))/t.calendar_update)
if _upFrac == 0 then t._date = os.date('*t'); _error = M.init_calendar(t); end
M.draw_graph(t)
return _error
end
M.setlocale()
--[[
###############################################################################
### MODULE MAIN LOOP ###
###############################################################################
--]]
function M.main()
for i in pairs(settings_table) do
local _error = M.schedule(settings_table[i])
if _error > 0 then M.errors(settings_table[i], _error); return end
end
end
