#!/usr/bin/env lua -- [[[[*<= Version '3.3.3+D20261012T123109' =>*]]]] local MYDIR = "/home/fuxoft/work/web/fuxoft.cz/vyplody/premiery/" local SERIALIZE = assert(dofile("/home/fuxoft/work/web/private/lib/serialize2.lua")) local function next_day(date) local sec = os.time{year=date.y, month=date.m, day=date.d, hour=12} local next = os.date("*t", sec + 24*60*60) return {y=next.year, m=next.month, d=next.day} end local function date_to_string(date) return string.format("%04d%02d%02d", date.y, date.m, date.d) end function utf8char(int) int = tonumber(int) --print(int) if int > 0x7ff then return("?char?") end int=math.min(0x7ff,int) local b2 = int%0x40 + 0x80 local b1 = math.floor(int / 0x40) + 0xc0 return string.char(b1,b2) end function each(table,func) for i,obj in pairs(table) do func(obj) end end function length(table) local len = 0 for _,_ in pairs(table) do len = len + 1 end return len end function strip_spaces(str) return str:match("^%s*(.-)%s*$") or str end function convert(tbl) local out = {} for i, event in ipairs(tbl) do local str = table.concat({event.datum.d, event.datum.m, event.datum.y, table.concat(event.detaily, "/"), event.misto, event.nazev}, "_") local key = event.nazev.." ("..event.datum.d.."."..event.datum.m.."."..event.datum.y..")" out[key] = str end return out end function dump(tbl) for k,v in pairs(tbl) do print(k) end end function exe(str) print("Executing: "..str) assert(os.execute(str)) end local tmpdir="/tmp/fffilm_premiery/" local fprefix = "*-20??" os.execute("rm -r "..tmpdir.."*") os.execute("rmdir "..tmpdir) exe("mkdir "..tmpdir) exe("libreoffice --headless --convert-to ods /home/fuxoft/Downloads/"..fprefix..".xlsx --outdir "..tmpdir) --exe("unoconvert /home/fuxoft/Downloads/*-20??.xlsx "..tmpdir.."ods.ods") exe("unzip -qq -d "..tmpdir.." "..tmpdir..fprefix..".ods content.xml") local fd = assert(io.open(tmpdir.."content.xml")) local prem = fd:read("*a") fd:close() local skrtnute = {} for styletxt in prem:gmatch("") do if styletxt:match('style:text%-line%-through%-style="solid"') then local style_id = assert(styletxt:match('style style:name="(.-)"')) assert(#style_id >= 2) assert(not skrtnute[style_id]) skrtnute[style_id] = true -- print("skrtnuty "..style_id) end end local films = {} for row in string.gmatch(prem,'(.-)') do print("----------------------------------") print(row) print("------------------") row = row:gsub("()",function(str) --opening tag or whole (empty) col if not (str:match("/>$")) then --non-empty column return str end --column is empty. Check repeats local repeats = str:match('table:number%-columns%-repeated="(%d+)"') if not repeats then repeats = "1" end --print (repeats) repeats = tonumber(repeats) assert(repeats >= 1) if repeats > 9 then repeats = 9 end local empties = {} for i = 1, repeats do table.insert(empties, "") end return table.concat(empties) end) --print(row) local coln = 0 local f = {} local skrtnuty = false for style in row:gmatch('style%-name="(.-)"') do --print(style) if skrtnute[style] then --print("Skrtnuty styl",style) skrtnuty = true end end for col in string.gmatch(row,'.-') do --print (col) col = col:gsub ("", "") local colval = col:match(".*") if colval then colval = colval:gsub("&","&") colval = colval:gsub(""",'"') colval = colval:gsub("<.->","") colval = colval:gsub(" *"," ") colval = colval:gsub("^ *","") colval = colval:gsub(" *$","") end --[[ for str in col:gmatch(">([^<].-)<") do if not str:match("%d%dT%d%d:%d%d:%d%d") then colval = str end end]] --[[ if colval then colval = colval:gsub(".*>","") else colval = false end ]] local repeats = col:match('table:number%-columns%-repeated="(%d+)"') if not repeats then repeats = 1 else repeats = tonumber(repeats) assert(repeats > 1) assert(colval, "if there are repeats, column should not be empty here") if repeats> 9 then repeats = 9 end end coln = coln+repeats --DUMP film data --[x[ --print("Col "..coln..": "..col) --print("Parsed as:") --print(colval) --print() --]] for i = 1, repeats do table.insert(f,colval or false) end end --[[ Format k 21.2.2014: 1 - kód: nil / a.o. / fest / akce 2 - datum: dd- mm- yy 3 - Distributor 4 - Poskytovatel licence 5 - Orig. název 6 - ČR název 7 - úprava: tit / dab / ČR... 8 - DCP3D 9 - DCP2D 10 - DVD / BluRay: "ano" 11 - IMAX 12 - 4DX (jen u nových, u ostatních, chybí sloupec!!!) 13 - 35mm kopie 14 - Poznámka Format zari 2024: 10 - DVD / bluray / MP4 13 - poznámka ]] --print(#f.." fields") if (f[5] or f[6]) then local date = f[2] or "99-99-13" --"nema datum" if (tonumber(date) or 0) > 40000 then --41837 - 17.7.2014 - os.date(fmt..., 60*60*24*16268) date = os.date("%d %m %y",(tonumber(date) - (41837-16268))*60*60*24) --print("fixed date: "..date) end if not skrtnuty then local day,month,year = (date):match("(%d%d)%D+(%d%d)%D+(%d%d)") if year then --Date is OK --Pred rokem 2014 byl jiny format, chybel sloupec 4DX a byli navstevnici! if year >= "14" and not(f[1]=="akce" or f[1]=="fest") then f[2] = "20"..year.."-"..month.."-"..day assert(#f[2]==10) assert(#f >= 6, "got only "..#f.." fields for "..tostring(f[5])) -------------We've got valid item! local f2={kod=f[1],datum=f[2],distr=f[3],origdistr=f[4],orignazev=f[5], nazev=f[6],jazyk=f[7],dcp3d=f[8], dcp2d=f[9],format=f[10],imax=f[11],dx=f[12],pozn=f[13]} table.insert(films, f2) for k,v in pairs(f2) do if v then --print(k.."="..tostring(v)) end end end else --print("Date not OK, ignoring: "..tostring(date).." - "..tostring(f[5])) end else --print("skrtnuty: "..tostring(f[5])) end end --io.read("*l") --press any key end local newEvents = {} for i,film in ipairs(films) do local date0 = film.datum local y, m, d = string.match(date0, "(.+)%-(.+)%-(.+)") local date = {y=tonumber(y), m = tonumber(m), d = tonumber(d)} assert(date.y > 2010) if film.nazev == "" then film.nazev = nil end if film.nazev and #film.nazev<2 then for i=1, #film.nazev do local chr = film.nazev:sub(i,i) print(string.byte(chr),chr) end error("Nazev prilis kratky - "..#film.nazev) end if film.orignazev == "" then film.orignazev = nil end if film.orignazev and #film.orignazev<2 then for i=1, #film.orignazev do local chr = film.orignazev:sub(i,i) print(string.byte(chr),chr) end error("Orignazev prilis kratky") end local title = film.nazev or film.orignazev if film.orignazev and (film.orignazev ~= title) then title = title .. ' [' .. film.orignazev .. ']' end local location = '' if film.distr then location = 'Distributor: '..film.distr end local content = {} local function add(str) table.insert(content, str) end if film.live then add("Přímý přenos") end --[[ if film.kod then add("Kód: "..film.kod) end]] if film.jazyk then add('Jazyková verze: '..film.jazyk) end if film.dcp2d then add('DCP 2D kopie: '..film.dcp2d) end if film.dcp3d then add('DCP 3D kopie: '..film.dcp3d) end if film.imax then add('IMAX kopie: '..film.imax) end if film.dx then add('4DX kopie: '..film.dx) end if film.format then add("Formát: "..film.format) end if film.origdistr then add('Původní distributor: '..film.origdistr) end if film.pozn then add("Poznámka: "..film.pozn) end local event = {datum=date,misto=location,detaily=content,nazev=title} print("==============") print(title) print(location) print(date.y, date.m, date.d) print(table.concat (content, "/-/")) if event.datum.y >= 2021 then table.insert(newEvents,event) end end --os.exit() --***** table.sort(newEvents, function(x,y) return x.datum.y*10000 + x.datum.m*100 + x.datum.d < y.datum.y*10000 + y.datum.m*100 + y.datum.d end) for i,ev in ipairs(newEvents) do --print(i);ev:dump() end --print(#newEvents.." new events") assert(#newEvents > 100, "Less than 100 events...???") local previous = dofile(MYDIR.."database.lua") previous = convert(previous) local current = convert(newEvents) local exported = SERIALIZE.serialize2{data = newEvents, pretty = true, include_return = true} local fd = assert(io.open(MYDIR.."database.lua", "w")) fd:write(exported) fd:close() --print(exported) --os.exit() local fd = assert(io.open(MYDIR.."premiery.ics", "w")) local function line(str) if #str < 75 then local write = str..string.char(13)..string.char(10) io.write(write) fd:write(write) return end local split = 75 while true do split = split - 1 local chr = string.sub(str, split, split) if chr >= " " and chr <= "z" then break end if split < 3 then error("cannot split line for ICS: "..str) end end line(string.sub(str, 1, split)) line(" "..string.sub(str, split + 1)) end local time = os.time() line("BEGIN:VCALENDAR") line("PRODID:Fuxoft premiery export") line("VERSION:2.0") line("CALSCALE:GREGORIAN") line("METHOD:PUBLISH") line("X-WR-CALNAME:České filmové premiéry") line("X-WR-TIMEZONE:UTC") line("X-WR-CALDESC:Generováno automaticky z dat na www.ufd.cz. Navštivte stránku www.fuxoft.cz/vyplody/premiery pro další informace o tomto kalendáři. Poslední update: "..os.date()) for i, event in ipairs(newEvents) do line("BEGIN:VEVENT") line("SUMMARY:"..event.nazev) line("LOCATION:"..event.misto) line("DESCRIPTION:"..table.concat(event.detaily, "\\n")) line("DTSTART;VALUE=DATE:"..date_to_string(event.datum)) line("DTEND;VALUE=DATE:"..date_to_string(next_day(event.datum))) line("UID:"..time.."x"..i) line("DTSTAMP:20010101T130000Z") line("END:VEVENT") end line("END:VCALENDAR") fd:close() local remove = {} for k,v in pairs(previous) do if current[k] == v then table.insert(remove, k) end end for i, k in ipairs(remove) do current[k] = nil previous[k] = nil end print("\nOdstranene premiery: ") dump(previous) print("\nNove premiery: ") dump(current) print("\nExportováno celkem "..#newEvents)