<commit_before># stdlib
require 'pathname'
require 'date'
require 'rss'
require 'json'
# gem
require 'icalendar'


class Eventkalender
  # Parser class can be used to parse dokuwiki table and return events in multiple formats.
  #
  # @example Create parser to parse voc wiki events page.
  #   parser = Eventkalender::Parser.new
  #   parser.events #=>  [#<Eventkalender::Event:0x00000002a49f78 … ]
  #
  # @example Convert date String into Date object.
  #   Eventkalender::Parser.date('23-12-2014') #=> #<Date: 2014-12-23 ((2457015j,0s,0n),+0s,2299161j)>
  #
  # @!attribute [r] events_table
  #   @return [Nokogiri::XML::Element] Contains scraped event table.
  # @!attribute [r] timestamp
  #   @return [Time] Last scraping time.
  class Parser

    attr_reader :events_table, :timestamp

    # Parsed content from dokuwiki page and returned Hash with events.
    #
    # @example Scrape events
    #   parser.events(true) #=> [#<Eventkalender::Event:0x0000000332e300 @name=…, …]
    #
    # @param force_scraping [Boolean] to force scraping
    # @return [Array] scraped events
    def events(force_scraping = false)
      # Get events table from web page scraper or from instance variable
      if @events_table.nil? || @timestamp - 20.minutes.ago < 0 || force_scraping
        @events_table = Eventkalender::Scraper.scrape!
        @timestamp    = Time.now
      end

      # Events inside table are separated in rows.
      event_rows = @events_table.search('./tr')

      # HACK: Ugly workaround for unknown xpath matching problems.
      #       If clause is only needed for rspec and webmock.
      if event_rows.count == 0
        event_rows = @events_table.search('./*/tr')
      end

      # Iterate over all rows and create ical events for every event.
      events = event_rows.map do |row|
        # Skip headlines
        next if row.search('./td').empty?

        to_event(row)
      end

      # Remove nil objects
      events.compact
    end

    # Converts string into event object.
    #
    # @param table_row [Nokogiri::XML::Element] that should be converted to an event
    # @return [Event] event
    def to_event(table_row)
      # Search all cols in event row.
      raw_event = table_row.search('./td')
      # Create new ical object and return it
      Eventkalender::Event.new.tap { |e|
        # Add more information to ical object.
        e.name        = raw_event[0].text       # Event name
        e.location    = raw_event[1].text       # Event location
        e.start_date  = self.class.date(raw_event[2].text) # Start date
        e.end_date    = self.class.date(raw_event[3].text) # End date + 1 day to have last day also complete
        e.description = raw_event[5].text       # URL
        e.streaming   = raw_event[7].text       # Is streaming planed?

        url_path = raw_event[0].xpath('./a[@href]')[0]['href']
        e.short_name  = /^.*\/(.*)$/.match(url_path)[1]
        e.wiki_path   = url_path
      }
    end

    # Converts array with events into ical calendar.
    #
    # @param events [Array<Event>, #events] to convert to an ical calender
    # @return [Icalendar::Calendar] converted events
    def to_ical_calendar(events = self.events)
      # Create new ical calendar
      calendar = Icalendar::Calendar.new
      # Setting time zone
      calendar.timezone { timezone_id = 'Europe/Berlin' }
      # Add every object in array to new created calendar
      events.each { |event| calendar.add(event.to_ical) }

      calendar
    end

    # Converts events array to plain text.<commit_msg>parser: fixed timezone definition in ical calender<commit_after># stdlib
require 'pathname'
require 'date'
require 'rss'
require 'json'
# gem
require 'icalendar'


class Eventkalender
  # Parser class can be used to parse dokuwiki table and return events in multiple formats.
  #
  # @example Create parser to parse voc wiki events page.
  #   parser = Eventkalender::Parser.new
  #   parser.events #=>  [#<Eventkalender::Event:0x00000002a49f78 … ]
  #
  # @example Convert date String into Date object.
  #   Eventkalender::Parser.date('23-12-2014') #=> #<Date: 2014-12-23 ((2457015j,0s,0n),+0s,2299161j)>
  #
  # @!attribute [r] events_table
  #   @return [Nokogiri::XML::Element] Contains scraped event table.
  # @!attribute [r] timestamp
  #   @return [Time] Last scraping time.
  class Parser

    attr_reader :events_table, :timestamp

    # Parsed content from dokuwiki page and returned Hash with events.
    #
    # @example Scrape events
    #   parser.events(true) #=> [#<Eventkalender::Event:0x0000000332e300 @name=…, …]
    #
    # @param force_scraping [Boolean] to force scraping
    # @return [Array] scraped events
    def events(force_scraping = false)
      # Get events table from web page scraper or from instance variable
      if @events_table.nil? || @timestamp - 20.minutes.ago < 0 || force_scraping
        @events_table = Eventkalender::Scraper.scrape!
        @timestamp    = Time.now
      end

      # Events inside table are separated in rows.
      event_rows = @events_table.search('./tr')

      # HACK: Ugly workaround for unknown xpath matching problems.
      #       If clause is only needed for rspec and webmock.
      if event_rows.count == 0
        event_rows = @events_table.search('./*/tr')
      end

      # Iterate over all rows and create ical events for every event.
      events = event_rows.map do |row|
        # Skip headlines
        next if row.search('./td').empty?

        to_event(row)
      end

      # Remove nil objects
      events.compact
    end

    # Converts string into event object.
    #
    # @param table_row [Nokogiri::XML::Element] that should be converted to an event
    # @return [Event] event
    def to_event(table_row)
      # Search all cols in event row.
      raw_event = table_row.search('./td')
      # Create new ical object and return it
      Eventkalender::Event.new.tap { |e|
        # Add more information to ical object.
        e.name        = raw_event[0].text       # Event name
        e.location    = raw_event[1].text       # Event location
        e.start_date  = self.class.date(raw_event[2].text) # Start date
        e.end_date    = self.class.date(raw_event[3].text) # End date + 1 day to have last day also complete
        e.description = raw_event[5].text       # URL
        e.streaming   = raw_event[7].text       # Is streaming planed?

        url_path = raw_event[0].xpath('./a[@href]')[0]['href']
        e.short_name  = /^.*\/(.*)$/.match(url_path)[1]
        e.wiki_path   = url_path
      }
    end

    # Converts array with events into ical calendar.
    #
    # @param events [Array<Event>, #events] to convert to an ical calender
    # @return [Icalendar::Calendar] converted events
    def to_ical_calendar(events = self.events)
      # Create new ical calendar
      calendar = Icalendar::Calendar.new
      # Setting time zone
      calendar.timezone { |t| t.tzid = 'Europe/Berlin' }
      # Add every object in array to new created calendar
      events.each { |event| calendar.add(event.to_ical) }

      calendar
    end

    # Converts events array to plain text.
{'fraction_non_alphanumeric': 0.10601398601398601, 'fraction_numerical': 0.0206993006993007, 'mean_word_length': 2.6466088730239674, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4794232', 'n_tokens_mistral': 2319, 'n_tokens_neox': 2190, 'n_words': 658}