summaryrefslogtreecommitdiff
blob: 379ab2a8e3c0a195c5afc1705681fe2e97b9f826 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
require 'yaml'
require 'date'
require 'singleton'

# Stores notices and caches them in memory.
# Automatically refreshes the cache after CACHE_SECONDS seconds.
class NoticeStore
  include Singleton
  CACHE_SECONDS = 600
  attr_reader :load_date

  def initialize
    update!
  end

  def update!
    @notices = []

    Dir.glob('data/notices/*.txt') do |file|
      begin
        @notices << Notice.from_file(file)
      rescue => e
        $stderr.puts 'Invalid notice (%s): %s' % [e.message, file]
      end
    end

    @notices.sort! { |a, b| b['created_at'] <=> a['created_at'] }

    @load_date = DateTime.now
  end

  def notices
    update?
    @notices
  end

  def visible_notices
    notices.select do |notice|
      is_active = notice['active']
      is_active &= notice['expire_at'] >= DateTime.now if notice.has_key? 'expire_at'
      is_active &= notice['created_at'] <= DateTime.now if notice.has_key? 'created_at'

      is_active
    end

  end

  def active_notices
    notices.select do |notice|
      is_active = notice['active']
      is_active &= notice['expire_at'] >= DateTime.now if notice.has_key? 'expire_at'
      is_active &= notice['created_at'] <= DateTime.now if notice.has_key? 'created_at'
      is_active &= notice['starts_at'] <= DateTime.now if notice.has_key? 'starts_at'

      is_active
    end
  end

  def notice_affects_service(notice, service)
      return (notice.has_key? 'affects' and not notice['affects'].nil? and notice['affects'].include? service)
  end

  def active_notices_for(service)
    active_notices.select do |notice|
      notice_affects_service(notice, service)
    end
  end

  def visible_notices_for(service)
    visible_notices.select do |notice|
      notice_affects_service(notice, service)
    end
  end

  def notice(id)
    notices.each do |notice|
      return notice if notice['id'] == id
    end

    nil
  end

  private
  def update?
    if ((DateTime.now - @load_date) * 60 * 60 * 24).to_i > CACHE_SECONDS
      update!
    end
  end
end

class Notice
  def self.from_file(filename)
    content = File.read(filename)
    metadata = YAML.load(content) || {}
    metadata['updated_at'] = File.mtime(filename)
    description = 'missing description'
    description_splitpos = nil

    lines = content.split("\n").map { |l| l.strip }
    if lines[0] == '---' and lines.grep('---').length() >= 2
        description_splitpos = 2
    elsif lines.grep('---').length() >= 1
        description_splitpos = 1
    else
        description_splitpos = 0
    end

    description = content.split('---')[description_splitpos].strip
    new(File.basename(filename, '.txt'), metadata, description)
  end

  def [](what)
    if @metadata.has_key? what
      @metadata[what]
    else
      nil
    end
  end

  def has_key?(what)
    @metadata.has_key? what
  end

  def get_content
    @content
  end

  def url
    MY_URL + 'notice/' + @metadata['id']
  end

  private
  def initialize(id, metadata, content)
    @metadata = metadata

    %w[created_at eta expire_at starts_at].each do |key|
      @metadata[key] = DateTime.parse(@metadata[key]) if @metadata.has_key? key
    end

    @metadata['id'] = id
    @content = content
  end
end