Mercurial > prosody-modules
comparison mod_firewall/conditions.lib.lua @ 968:f3b0ddeebd9d
mod_firewall/conditions: Add DAY and TIME conditions
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sat, 06 Apr 2013 14:03:10 +0100 |
| parents | d4e24fb289c0 |
| children | 53e158e44a44 |
comparison
equal
deleted
inserted
replaced
| 967:a88f33fe6970 | 968:f3b0ddeebd9d |
|---|---|
| 107 | 107 |
| 108 function condition_handlers.TO_ADMIN_OF(host) | 108 function condition_handlers.TO_ADMIN_OF(host) |
| 109 return ("is_admin(bare_to, %s)"):format(host ~= "*" and host or nil), { "is_admin", "bare_to" }; | 109 return ("is_admin(bare_to, %s)"):format(host ~= "*" and host or nil), { "is_admin", "bare_to" }; |
| 110 end | 110 end |
| 111 | 111 |
| 112 local day_numbers = { sun = 0, mon = 2, tue = 3, wed = 4, thu = 5, fri = 6, sat = 7 }; | |
| 113 | |
| 114 local function current_time_check(op, hour, minute) | |
| 115 hour, minute = tonumber(hour), tonumber(minute); | |
| 116 local s = ""; | |
| 117 local adj_op = op == "<" and "<" or ">="; -- Start time inclusive, end time exclusive | |
| 118 if minute == 0 then | |
| 119 return "(current_hour"..adj_op..hour..")"; | |
| 120 else | |
| 121 return "((current_hour"..op..hour..") or (current_hour == "..hour.." and current_minute"..adj_op..minute.."))"; | |
| 122 end | |
| 123 end | |
| 124 | |
| 125 local function resolve_day_number(day_name) | |
| 126 return assert(day_numbers[day_name:sub(1,3):lower()], "Unknown day name: "..day_name); | |
| 127 end | |
| 128 | |
| 129 function condition_handlers.DAY(days) | |
| 130 local conditions = {}; | |
| 131 for day_range in days:gmatch("[^,]+") do | |
| 132 local day_start, day_end = day_range:match("(%a+)%s*%-%s*(%a+)"); | |
| 133 if day_start and day_end then | |
| 134 local day_start_num, day_end_num = resolve_day_number(day_start), resolve_day_number(day_end); | |
| 135 local op = "and"; | |
| 136 if day_end_num < day_start_num then | |
| 137 op = "or"; | |
| 138 end | |
| 139 table.insert(conditions, ("current_day >= %d %s current_day <= %d"):format(day_start_num, op, day_end_num)); | |
| 140 elseif day_range:match("%a") then | |
| 141 local day = resolve_day_number(day_range:match("%a+")); | |
| 142 table.insert(conditions, "current_day == "..day); | |
| 143 else | |
| 144 error("Unable to parse day/day range: "..day_range); | |
| 145 end | |
| 146 end | |
| 147 assert(#conditions>0, "Expected a list of days or day ranges"); | |
| 148 return "("..table.concat(conditions, ") or (")..")", { "time:day" }; | |
| 149 end | |
| 150 | |
| 151 function condition_handlers.TIME(ranges) | |
| 152 local conditions = {}; | |
| 153 for range in ranges:gmatch("([^,]+)") do | |
| 154 local clause = {}; | |
| 155 range = range:lower() | |
| 156 :gsub("(%d+):?(%d*) *am", function (h, m) return tostring(tonumber(h)%12)..":"..(tonumber(m) or "00"); end) | |
| 157 :gsub("(%d+):?(%d*) *pm", function (h, m) return tostring(tonumber(h)%12+12)..":"..(tonumber(m) or "00"); end); | |
| 158 local start_hour, start_minute = range:match("(%d+):(%d+) *%-"); | |
| 159 local end_hour, end_minute = range:match("%- *(%d+):(%d+)"); | |
| 160 local op = tonumber(start_hour) > tonumber(end_hour) and " or " or " and "; | |
| 161 if start_hour and end_hour then | |
| 162 table.insert(clause, current_time_check(">", start_hour, start_minute)); | |
| 163 table.insert(clause, current_time_check("<", end_hour, end_minute)); | |
| 164 end | |
| 165 if #clause == 0 then | |
| 166 error("Unable to parse time range: "..range); | |
| 167 end | |
| 168 table.insert(conditions, "("..table.concat(clause, " "..op.." ")..")"); | |
| 169 end | |
| 170 return table.concat(conditions, " or "), { "time:hour,min" }; | |
| 171 end | |
| 172 | |
| 112 return condition_handlers; | 173 return condition_handlers; |
