From 51ef51bbe3b741a76d1d44b8ce8c1d8a07427e1f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 10 Oct 2023 21:10:19 +0200 Subject: Updates for Ramaskrik 2023 - Reorg, create lib dir and move room-schedule and events there - Add .ics template to generate program as an iCalendar stream. - Add some info to html template, and instructions to html template. - Add footer to html template, with timestamp for when the view was generated. - Fix bug that messed up the layout if the input data was not already sorted. - Update readme with usage instructions. --- ramaskrik-program.rb | 106 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 30 deletions(-) mode change 100644 => 100755 ramaskrik-program.rb (limited to 'ramaskrik-program.rb') diff --git a/ramaskrik-program.rb b/ramaskrik-program.rb old mode 100644 new mode 100755 index 3c56edc..5dfe5d5 --- a/ramaskrik-program.rb +++ b/ramaskrik-program.rb @@ -1,3 +1,5 @@ +#!/usr/bin/env ruby + # Ramaskrik Program Schedule plotter. # Copyright (C) 2018 Harald Eilertsen # @@ -14,42 +16,26 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +$LOAD_PATH << File.join(File.dirname( __FILE__ ), "lib") + require 'date' +require 'delegate' require 'erb' +require 'events' +require 'json' +require 'scrapers/ramaskrik' require 'nokogiri' require 'open-uri' -require 'room-schedule' +#require 'room-schedule' require 'uri' -class Movie - attr_reader :title, :link, :start_time, :end_time, :venue - - def initialize(node) - @title = node.css("h4").text.strip - @link = URI.join("https://ramaskrik.no", node.css("h4 a").attribute('href').value) - @start_time = DateTime.parse(node.css(".date").attribute('title').value) - @end_time = DateTime.parse(@start_time.strftime('%F') + node.css(".prgtype-endTime").text.strip.sub(/\w+/, '')) - @end_time += 1 if @end_time < @start_time - @venue = node.css(".place").text.strip - end - - def to_s - "#{title} #{start_time} - #{end_time}, #{venue}" - end -end - -def scrape_program - doc = Nokogiri::HTML(open("https://ramaskrik.no/program/")) - doc.css(".kultur-type-movie").map { |movie| Movie.new(movie) } -end - -def generate_graphs - days = scrape_program.group_by { |movie| movie.start_time.strftime("%A %d.%m.%Y") } - days.map do |d, movies| - rooms = movies.group_by { |m| m.venue }.delete_if { |t, _| t == "Ramaskrik" } +def generate_graphs(events) + days = events.group_by { |event| event.start_time.strftime("%A %d.%m.%Y") } + days.map do |day, events| + rooms = events.group_by { |e| e.venue } graph = SVG::Graph::RoomSchedule.new({ - graph_title: d, + graph_title: day, show_graph_title: true, show_x_guidelines: true, width: 1280, @@ -67,6 +53,66 @@ def generate_graphs end end -t = ERB.new(IO.read("index.html.erb")) -IO.write("index.html", t.result(binding)) +class EventDecorator < SimpleDelegator + attr_reader :offset + attr_reader :height + + def calc_offsets(time_offset) + @offset = (start_time - time_offset).to_i / 50 + @height = duration / 50; + start_time + duration + end +end + +class SortedEventList + attr_reader :venues + attr_reader :events + attr_reader :start_time + attr_reader :end_time + + def initialize(events) + @venues = events.map{ |e| e.venue }.uniq + + @events = events + .sort{ |a,b| a.start_time - b.start_time } + .map{ |e| EventDecorator.new(e) } + + @start_time = @events.first.start_time - (@events.first.start_time.min * 60) + + @events.group_by{|e| e.venue}.each do |venue, events| + time_offset = start_time + time_end = start_time + events.each do |event| + time_end = event.calc_offsets(time_offset) + end + + @end_time = time_end if @end_time.nil? || @end_time < time_end + end + end +end + +def import_events_from_json(input) + JSON + .parse(input) + .map{ |obj| Events::Event.new(obj) } + .group_by{ |e| e.date } +end + +def make_sorted_event_lists_by_date(events_by_date) + new_list = {} + events_by_date.each do |date, events| + new_list[date] = SortedEventList.new(events) + end + + new_list +end + +title = "Ramaskrik 2023 - Program" + +eventlist = make_sorted_event_lists_by_date(import_events_from_json(IO.read(ARGV[0]))) + +t_html = ERB.new(IO.read("index.html.erb"), trim_mode: '>') +IO.write("index.html", t_html.result(binding)) +t_ics = ERB.new(IO.read("program.ics.erb"), trim_mode: '<>') +IO.write("program.ics", t_ics.result(binding).gsub(/\n/, "\r\n")) -- cgit v1.2.3