now.lua 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env lua
  2. --[[
  3. -- Copyright (c) 2013-2016 Marcus Rohrmoser, http://purl.mro.name/recorder
  4. --
  5. -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
  6. -- associated documentation files (the "Software"), to deal in the Software without restriction,
  7. -- including without limitation the rights to use, copy, modify, merge, publish, distribute,
  8. -- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
  9. -- furnished to do so, subject to the following conditions:
  10. --
  11. -- The above copyright notice and this permission notice shall be included in all copies or
  12. -- substantial portions of the Software.
  13. --
  14. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
  15. -- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
  17. -- OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. -- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. --
  20. -- MIT License http://opensource.org/licenses/MIT
  21. ]]
  22. -- ensure Recorder.lua (next to this file) is found:
  23. package.path = arg[0]:gsub('/[^/]+/?$', '') .. '/?.lua;' .. package.path
  24. require('Recorder')
  25. Recorder.chdir2app_root( arg[0] )
  26. -- prepare, extract GET parameters:
  27. local params = {}
  28. local qs = os.getenv('QUERY_STRING')
  29. if qs then for k,v in qs:gmatch('([^?&=]+)=([^&]*)') do
  30. params[k:unescape_url_param()] = v:unescape_url_param()
  31. end end
  32. -- guess station from GET params or url:
  33. local station_name = nil
  34. if not station_name and params.station then station_name = params.station end
  35. if not station_name and params.uri then station_name = params.uri:match('stations/([^/]+)') end
  36. local fmt_date_rfc1123_2utc = '!' .. '%a, %d %b %Y %H:%M:%S GMT'
  37. local t = parse_iso8601( params.t ) or os.time()
  38. if station_name then
  39. -- redirect to one dedicated station/broadcast
  40. local st = Station.from_id( station_name )
  41. if not st then
  42. http_400_bad_request('Unknown station \'', station_name, '\'. Give me either\n', '- GET param station=...\n', '- GET param uri=...\n', '- a referer\n\n')
  43. end
  44. local bc = st:broadcast_now(t, true, false)
  45. if bc then
  46. -- RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
  47. http_303_see_other('../stations/' .. bc.id:escape_url() .. '', nil, os.date(fmt_date_rfc1123_2utc, bc:dtend()))
  48. else
  49. http_400_bad_request('Ouch, cannot find current broadcast for station: \'', station_name, '\'')
  50. end
  51. else
  52. -- list all stations' current broadcasts
  53. local xml = {
  54. '<?xml version="1.0" encoding="UTF-8"?>',
  55. '<?xml-stylesheet type="text/xsl" href="../assets/broadcasts2html-now.xslt"?>',
  56. '<!-- unorthodox relative namespace to enable http://www.w3.org/TR/grddl-tests/#sq2 without a central server -->',
  57. '<broadcasts xml:lang="de" xmlns="../assets/2013/radio-pi.rdf">',
  58. }
  59. local file_mod = 0
  60. for _,st in orderedPairs(Station.each()) do
  61. local bc = st:broadcast_now(t, true, false)
  62. if bc then
  63. file_mod = math.max(file_mod, bc:modified(), bc:dtstart())
  64. bc:to_xml(xml)
  65. end
  66. end
  67. table.insert( xml, '</broadcasts>' )
  68. local head = {
  69. ['Content-Type'] = 'text/xml',
  70. ['Last-Modified'] = os.date(fmt_date_rfc1123_2utc, file_mod),
  71. ['Expires'] = os.date(fmt_date_rfc1123_2utc, os.time() + 10),
  72. }
  73. file_mod = os.time(os.date('!*t', file_mod))
  74. local ifmod = parse_date_rfc1123( os.getenv('HTTP_IF_MODIFIED_SINCE'), 0 )
  75. if file_mod > ifmod then
  76. http_200_ok(head, table.concat(xml, "\n") )
  77. else
  78. http_304_unmodified(head)
  79. end
  80. end