Class: Slackware::ChangeLog

Inherits:
Object
  • Object
show all
Defined in:
lib/slackware/changelog.rb,
lib/slackware/changelog/rss.rb

Overview

The class for parsing a Slackware standard ChangeLog.txt

Defined Under Namespace

Classes: Entry, Update

Constant Summary collapse

ABBR_DAYNAMES =

yanked from Date

%w(Sun Mon Tue Wed Thu Fri Sat)
ABBR_MONTHNAMES =
%w(Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec)
RE_DATE =
Regexp.new(/^(#{re_daynames}\s+#{re_monthnames}\s+\d+\s+\d{2}:\d{2}:\d{2}\s\w+\s+\d+)$/)
RE_CHANGELOG_BREAK =

This break has been the same as long as I can find

Regexp.new(/^\+--------------------------\+$/)
RE_PACKAGE_ENTRY =

combine them

Regexp.union(re_package_entry0, re_package_entry1, re_package_entry2)
RE_SECURITY_FIX =

(* Security fix *)

/\(\*\s+security\s+fix\s+\*\)/i
IMAGE_URL =

or maybe “

"http://connie.slackware.com/~msimons/slackware/grfx/shared/bluepiSW.jpg"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file = nil, opts = {}) ⇒ ChangeLog

file can be a path to a file, or a File object opts can include

* :arch      - basically '64' or '32'
* :version   - 13.1, 13.2, current, etc.
* :url       - the URL web link to the ChangeLog.txt
* :image_url - the URL for the loge used in the RSS feed


121
122
123
124
125
# File 'lib/slackware/changelog.rb', line 121

def initialize(file = nil, opts = {})
  @file     = file
  @opts     = opts
  @updates  = Array.new
end

Class Method Details

.open(file) ⇒ Object



168
169
170
# File 'lib/slackware/changelog.rb', line 168

def self::open(file)
  return parse_this_file(file)
end

.parse(file) ⇒ Object

Class method



164
165
166
# File 'lib/slackware/changelog.rb', line 164

def self::parse(file)
  return parse_this_file(file)
end

.parse_this_file(file) ⇒ Object

protected Parse order is something like:

  • if its’ a date match, store the date

  • take change notes until

  • package match on name and action

  • set @security if present

  • take packge notes until

  • next package or entry separator

  • separator creates next change entry



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/slackware/changelog.rb', line 185

def self::parse_this_file(file)
  f_handle = ""
  if file.is_a?(File)
    f_handle = file
  elsif file.is_a?(String)
    if File.exist?(File.expand_path(file))
      f_handle = File.open(File.expand_path(file))
    else
      raise StandardError.new("file not found\n")
    end
  else
    raise StandardError.new("file not found\n")
  end

  # Start our changelog
  changelog = ChangeLog.new(f_handle)
  f_handle.each do |line|
    if (line =~ RE_DATE)
      u = Update.new(Time.parse($1))
      while true
        if (f_handle.eof?)
          break
        end

        # take the next line
        u_line = f_handle.readline
        if (u_line =~ RE_CHANGELOG_BREAK)
          break
        end

        # the intimate iteration
        # +Match+ is more expensive than =~,
        # but ruby-1.8.x is lossing the matched values down below
        # so this works on both ...
        if (match = RE_PACKAGE_ENTRY.match(u_line))
          u_entry = Entry.new()
          # This silly iteration catches the different cases of 
          # which package line, matches which Regexp. WIN
          if match[1].nil?
            if match[4].nil?
              u_entry.package = match[6] unless match[6].nil?
            else
              u_entry.package = match[4]
            end
          else
            u_entry.package = match[1]
          end
          if u_entry.package.include?("/")
            u_entry.package = u_entry.package.split("/")[-1]
          end
          if match[2].nil?
            if match[5].nil?
              u_entry.section = match[7] unless match[7].nil?
            else
              u_entry.section = match[5]
            end
          else
            u_entry.section = match[2]
          end
          # set the action for the item, if it's present
          u_entry.action = match[3] unless match[3].nil?

          # Add this entry to the stack
          u.entries << u_entry
        else
          # if u.entries is empty, then this text is notes 
          # for the upate, else it is notes, for the entry
          if (u.entries.empty?)
            u.notes = u.notes + u_line
          else
            # if this line of the entry security fix, toggle the bool
            if (u_line =~ RE_SECURITY_FIX)
              u.entries[-1].security = true
            end
            u.entries[-1].notes = u.entries[-1].notes + u_line
          end
        end
      end

      # Add this update to the stack
      changelog.updates << u
    end
  end

  # Give them their change set
  return changelog
end

.re_changelog_breakObject



59
# File 'lib/slackware/changelog.rb', line 59

def self::re_changelog_break ; RE_CHANGELOG_BREAK ; end

.re_dateObject

for hacks sake, make these usbable elsewhere



58
# File 'lib/slackware/changelog.rb', line 58

def self::re_date ; RE_DATE ; end

.re_package_entryObject



60
# File 'lib/slackware/changelog.rb', line 60

def self::re_package_entry ; RE_PACKAGE_ENTRY ; end

.re_security_fixObject



61
# File 'lib/slackware/changelog.rb', line 61

def self::re_security_fix ; RE_SECURITY_FIX ; end

Instance Method Details

#entriesObject



130
131
132
# File 'lib/slackware/changelog.rb', line 130

def entries
  @updates.map {|update| update.entries.map {|entry| {:date => update.date, :entry => entry } } }.flatten
end

#fileObject



127
# File 'lib/slackware/changelog.rb', line 127

def file; @file; end

#inspectObject



172
173
174
# File 'lib/slackware/changelog.rb', line 172

def inspect
  "#<%s:0x%x @file=%s, %d @updates, %d @entries>" % [self.class.name, self.object_id.abs, self.file || '""', self.updates.count || 0, self.entries.count || 0]
end

#optsObject



128
# File 'lib/slackware/changelog.rb', line 128

def opts; @opts; end

#opts=(hash) ⇒ Object



148
149
150
151
152
# File 'lib/slackware/changelog.rb', line 148

def opts=(hash)
  if hash.is_a?(Hash)
    @opts = hash
  end
end

#parse(opts = {:file => nil, :data => nil}) ⇒ Object



154
155
156
157
158
159
160
161
# File 'lib/slackware/changelog.rb', line 154

def parse(opts = {:file => nil, :data => nil})
  if not(opts[:file].nil?)
    @updates = parse_this_file(opts[:file]).updates
  elsif not(@file.nil?)
    @updates = parse_this_file(@file).updates
  end
  return self
end

#pkgs_addedObject



139
140
141
# File 'lib/slackware/changelog.rb', line 139

def pkgs_added
  @updates.map {|u| u.entries.map {|e| {:date => u.date, :entry => e } if e.action == "Added" } }.flatten.compact
end

#pkgs_rebuiltObject



145
146
147
# File 'lib/slackware/changelog.rb', line 145

def pkgs_rebuilt
  @updates.map {|u| u.entries.map {|e| {:date => u.date, :entry => e } if e.action == "Rebuilt" } }.flatten.compact
end

#pkgs_removedObject



136
137
138
# File 'lib/slackware/changelog.rb', line 136

def pkgs_removed
  @updates.map {|u| u.entries.map {|e| {:date => u.date, :entry => e } if e.action == "Removed" } }.flatten.compact
end

#pkgs_upgradedObject



142
143
144
# File 'lib/slackware/changelog.rb', line 142

def pkgs_upgraded
  @updates.map {|u| u.entries.map {|e| {:date => u.date, :entry => e } if e.action == "Upgraded" } }.flatten.compact
end

#securityObject



133
134
135
# File 'lib/slackware/changelog.rb', line 133

def security
  @updates.map {|u| u.entries.map {|e| {:date => u.date, :entry => e } if e.security } }.flatten.compact
end

#to_rss(opts = {}) ⇒ Object



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
# File 'lib/slackware/changelog/rss.rb', line 30

def to_rss(opts = {})
  # this way we can use the opts from super,
  # or override for this methods
  opts = @opts.merge(opts)

  version = "2.0" # ["0.9", "1.0", "2.0"]
  content = RSS::Maker.make(version) do |m|
    if (opts[:title])
      m.channel.title = opts[:title]
    else
      added_title = ""
      if opts[:arch]
        added_title = added_title + "slackware#{opts[:arch]}"
      end
      if opts[:version]
        added_title = added_title + "-#{opts[:version]}"
      end
  
      if added_title.empty?
        m.channel.title = "Slackware ChangeLog.txt"
      else
        m.channel.title = "#{added_title} ChangeLog.txt"
      end
    end

    if (opts[:url])
      m.channel.link = "%s#slackagg" % [opts[:url]]
    else
      m.channel.link = "http://www.slackware.com/#slackagg"
    end

    if (opts[:description])
      m.channel.description = opts[:description]
    else
      m.channel.description = "a parsed ChangeLog.txt, is an extendable ChangeLog.txt"
    end

    if opts[:image_url]
      m.channel. = opts[:image_url]
    else
      m.channel. = IMAGE_URL
    end

    if (opts[:noimage])
    else
      image = m.image
      if opts[:image_url]
        image.url = opts[:image_url]
      else
        image.url = IMAGE_URL
      end
      image.title = "Slackware Linux"
      image.width = "144"
      image.height = "144"
    end

    m.items.do_sort = true # sort items by date

    @updates.each {|update|
      i = m.items.new_item
      # Add a plug to the title of the update, if it includes a security fix
      # set this here, so we don't have to .map again down below
      security = update.entries.map {|e| 1 if e.security }.compact.count
      if (security > 0)
        i.title = "%s (* Security fix *)" % [update.date.utc.to_s]
      else
        i.title = update.date.utc.to_s
      end
      if opts[:url]
        i.link = "%s#%s" % [opts[:url], update.date.to_i]
      else
        i.link = "http://slackware.com/#slackagg#%s" % [update.date.to_i]
      end
      i.date = update.date

      i.description = ""
      if (update.entries.count > 0)
        if (security > 0)
          i.description = i.description + "%d new update(s), %d security update(s)\n\n" % [update.entries.count, security]
        else
          i.description = i.description + "%d new update(s)\n\n" % [update.entries.count]
        end
      end
      i.description = i.description + "<pre><blockquote>\n"
      unless (update.notes.empty?)
          i.description = i.description + update.notes + "\n\n"
      end
      if (update.entries.count > 0)
        update.entries.each {|entry|
          if (entry.notes.empty?)
            i.description = i.description + sprintf("%s/%s:\s%s\n",
                                                    entry.section,
                                                    entry.package,
                                                    entry.action)
          else
            i.description = i.description + sprintf("%s/%s:\s%s\n\s\s%s\n",
                                                    entry.section,
                                                    entry.package,
                                                    entry.action,
                                                    entry.notes)
          end
        }
      end
      i.description = i.description + "</blockquote></pre>\n"
      #i.description.gsub!(/\n/, "<br/>\n")
    }
  end
  return content
end

#updatesObject



129
# File 'lib/slackware/changelog.rb', line 129

def updates; @updates; end