]> git.pld-linux.org Git - packages/cvsspam.git/blob - cvsspam-branch.diff
- updated
[packages/cvsspam.git] / cvsspam-branch.diff
1 Index: cvsspam.conf
2 ===================================================================
3 --- cvsspam.conf        (.../tags/RELEASE-0_2_12)       (revision 265)
4 +++ cvsspam.conf        (.../trunk)     (revision 265)
5 @@ -34,11 +34,19 @@
6  #
7  #     When $jiraURL is given, text of the form 'project-1234' will be linked
8  #   to this issue in JIRA.
9 +#
10 +#     When $xplannerStoryURL, $xplannerIterationURL and $xplannerProjectURL are
11 +#   given, text of the form XS1234 will be linked to XPlanner stories; text of
12 +#   the form XI1234 will be linked to XPlanner iterations; and text of the form
13 +#   XP1234 will be linked to XPlanner projects.
14  
15  #$bugzillaURL = "http://bugzilla.mozilla.org/show_bug.cgi?id=%s"
16  
17  #$jiraURL = "http://jira.atlassian.com/secure/ViewIssue.jspa?key=%s"
18  
19 +#$xplannerStoryURL = "http://www.example.com/xplanner/do/view/userstory?oid=%s"
20 +#$xplannerIterationURL = "http://www.example.com/xplanner/do/view/iteration?oid=%s"
21 +#$xplannerProjectURL = "http://www.example.com/xplanner/do/view/project?oid=%s"
22  
23  # Link to Wiki systems
24  # 
25 @@ -125,6 +133,15 @@
26  #$diff_ignore_keywords = true
27  
28  
29 +# cvsdiff whitespace ignoring               (Default: show whitespace-only changes)
30 +#
31 +#   Whitespace-only changes can distract from the rest of a diff. Set this
32 +#   value to true to exclude changes in the amount of whitespace (adds the -b
33 +#   option to cvs diff).
34 +
35 +$diff_ignore_whitespace = true
36 +
37 +
38  # $no_removed_file_diff and $no_added_file_diff
39  #
40  #     Set both these options, and emails will only include diffs for files
41 @@ -177,3 +194,13 @@
42  #   them happy, you can say $files_in_subject = true here.
43  
44  #$files_in_subject = false
45 +
46 +
47 +
48 +# Email size limit                                        (Default: around 2MB)
49 +#
50 +#     When large changes are committed, large CVSspam emails can result.  Here
51 +#   you can set the size of email that CVSspam is not allowed to append any
52 +#   more diffs onto.  Specify the number of bytes.
53 +
54 +#$mail_size_limit = 2097152
55 Index: collect_diffs.rb
56 ===================================================================
57 --- collect_diffs.rb    (.../tags/RELEASE-0_2_12)       (revision 265)
58 +++ collect_diffs.rb    (.../trunk)     (revision 265)
59 @@ -27,6 +27,13 @@
60  $dirtemplate = "#cvsspam.#{Process.getpgrp}.#{Process.uid}"
61  
62  def find_data_dir
63 +  if $from_address
64 +    safe_from = make_fromaddr_safe_for_filename($from_address)
65 +    Dir["#{$tmpdir}/#{$dirtemplate}.#{safe_from}-*"].each do |dir|
66 +      stat = File.stat(dir)
67 +      return dir if stat.owned?
68 +    end
69 +  end
70    Dir["#{$tmpdir}/#{$dirtemplate}-*"].each do |dir|
71      stat = File.stat(dir)
72      return dir if stat.owned?
73 @@ -35,6 +42,14 @@
74  end
75  
76  
77 +# transform any special / unexpected characters appearing in the argument to
78 +# --from so that they will not cause problems if the value is inserted into
79 +# a file or directory name
80 +def make_fromaddr_safe_for_filename(addr)
81 +  addr.gsub(/[^a-zA-Z0-1.,_-]/, "_")
82 +end
83 +
84 +
85  def blah(msg)
86    if $debug
87      $stderr.puts "collect_diffs.rb: #{msg}"
88 @@ -129,7 +144,14 @@
89    changes = Array.new
90    i = 0
91    while i < cvs_info.length
92 -    changes << ChangeInfo.new(cvs_info[i], cvs_info[i+=1], cvs_info[i+=1])
93 +    change_file = cvs_info[i]
94 +    # It's been reported,
95 +    # http://lists.badgers-in-foil.co.uk/pipermail/cvsspam-devel/2005-September/000380.html
96 +    # that sometimes the second revision number that CVS gives us contains a
97 +    # trailing newline character, so we strip ws from these values before use,
98 +    change_from = cvs_info[i+=1].strip
99 +    change_to = cvs_info[i+=1].strip
100 +    changes << ChangeInfo.new(change_file, change_from, change_to)
101      i+=1
102    end
103    return changes
104 @@ -222,6 +244,7 @@
105  
106        diff_cmd = Array.new << $cvs_prog << "-nq" << "diff" << "-Nu"
107        diff_cmd << "-kk" if $diff_ignore_keywords
108 +      diff_cmd << "-b" if $diff_ignore_whitespace
109  
110        if change.isAddition
111          file.write "#A "
112 @@ -333,9 +356,11 @@
113  end
114  
115  $config = nil
116 +$from_address = nil
117  $cvs_prog = "cvs"
118  $debug = false
119  $diff_ignore_keywords = false
120 +$diff_ignore_whitespace = false
121  $task_keywords = []
122  
123  unless ENV.has_key?('CVSROOT')
124 @@ -387,6 +412,7 @@
125    end
126    $config = arg if opt=="--config"
127    $debug = true if opt == "--debug"
128 +  $from_address = arg if opt == "--from"
129  end
130  
131  blah("CVSROOT is #{ENV['CVSROOT']}")
132 Index: record_lastdir.rb
133 ===================================================================
134 --- record_lastdir.rb   (.../tags/RELEASE-0_2_12)       (revision 265)
135 +++ record_lastdir.rb   (.../trunk)     (revision 265)
136 @@ -4,7 +4,6 @@
137  #   http://www.badgers-in-foil.co.uk/projects/cvsspam/
138  # Copyright (c) David Holroyd
139  
140 -$repositorydir = ARGV.shift
141  
142  $tmpdir = ENV["TMPDIR"] || "/tmp"
143  
144 @@ -19,6 +18,36 @@
145    nil
146  end
147  
148 +
149 +# transform any special / unexpected characters appearing in the argument to
150 +# --from so that they will not cause problems if the value is inserted into
151 +# a file or directory name
152 +def make_fromaddr_safe_for_filename(addr)
153 +  addr.gsub(/[^a-zA-Z0-1.,_-]/, "_")
154 +end
155 +
156 +# Option processing doesn't use GetoptLong (for the moment) bacause arguments
157 +# given to this script by CVS include the names of committed files.  It
158 +# seems quite possible that one of those file names could begin with a '-'
159 +# and therefore be treated by GetoptLong as a value which requires processing.
160 +# This would probably result in an error.
161 +#
162 +# [That could be worked around by placing a '--' option (which tells GetoptLong
163 +# to stop processing option arguments) at the very end of the arguments to
164 +# record_lastdir.rb in commitinfo, but that's very easily forgotten, and isn't
165 +# really backwards compatable with the behaviour of older CVSspam releases.]
166 +if ARGV.first == "--from"
167 +  # we could, of course, be tricked, if the first committed file in the list
168 +  # happened to be named '--from' :S
169 +
170 +  # drop the "--from"
171 +  ARGV.shift
172 +  # and use the value which was given following the option,
173 +  $dirtemplate << "." << make_fromaddr_safe_for_filename(ARGV.shift)
174 +end
175 +
176 +$repositorydir = ARGV.shift
177 +
178  $datadir = find_data_dir()
179  
180  if $datadir==nil
181 Index: project.xml
182 ===================================================================
183 Index: CREDITS
184 ===================================================================
185 --- CREDITS     (.../tags/RELEASE-0_2_12)       (revision 265)
186 +++ CREDITS     (.../trunk)     (revision 265)
187 @@ -29,3 +29,10 @@
188    Elan Ruusamäe
189    Steve Fox
190    Christopher Petro
191 +  Robin Getz
192 +  Glen Starrett
193 +  Jonathan Rafkind
194 +  Ryan Dlugosz
195 +  Steve Woodcock
196 +  Andy Selle
197 +  Charles Duffy
198 Index: cvsspam-doc.xml
199 ===================================================================
200 --- cvsspam-doc.xml     (.../tags/RELEASE-0_2_12)       (revision 265)
201 +++ cvsspam-doc.xml     (.../trunk)     (revision 265)
202 @@ -452,6 +452,23 @@
203  </screen></informalexample>
204        </para>
205    </section>
206 +
207 +  <section>
208 +    <title>RT</title>
209 +
210 +    <para>For Gforge, when a CVS log comment contains text like <userinput>Fix
211 +    for Bug [#123]</userinput>, or <userinput>Task [T456] ...</userinput>, the
212 +    text "[#123]" or "[T456]" will become a hyper-link to that Gforge page in
213 +    the generated email.  The format [#<replaceable>nnn</replaceable>] and
214 +    [T<replaceable>nnn</replaceable>] is taken from the existing plugin for
215 +    Gforge called cvstracker.</para>
216 +
217 +    <para>To enable, give your Gforge's URL in CVSspam's configuration file:
218 +<informalexample><screen>$gforgeBugURL = "http://gforge.org/tracker/index.php?func=detail&amp;aid=%s"
219 +$gforgeTaskURL = "http://gforge.org/pm/task.php?func=detailtask&amp;project_task_id=%s"</screen></informalexample>
220 +    The marker %s tells CVSspam where in the URL to put the bugId from the
221 +    log message.</para>
222 +  </section>
223  </section>
224  
225  <section><title>CVS Web Frontends</title>
226 Index: cvsspam.rb
227 ===================================================================
228 --- cvsspam.rb  (.../tags/RELEASE-0_2_12)       (revision 265)
229 +++ cvsspam.rb  (.../trunk)     (revision 265)
230 @@ -20,6 +20,7 @@
231  
232  $version = "0.2.12"
233  
234 +require 'time'
235  
236  $maxSubjectLength = 200
237  $maxLinesPerDiff = 1000
238 @@ -35,10 +36,6 @@
239    a<b ? a : b
240  end
241  
242 -# NB must ensure the time is UTC
243 -# (the Ruby Time object's strftime() doesn't supply a numeric timezone)
244 -DATE_HEADER_FORMAT = "%a, %d %b %Y %H:%M:%S +0000"
245 -
246  # Perform (possibly) multiple global substitutions on a string.
247  # the regexps given as keys must not use capturing subexpressions '(...)'
248  class MultiSub
249 @@ -48,7 +45,7 @@
250      @mash = Array.new
251      expr = nil
252      hash.each do |key,val|
253 -      if expr == nil ; expr="(" else expr<<"|(" end
254 +      if expr == nil ; expr="(" else expr << "|(" end
255        expr << key << ")"
256        @mash << val
257      end
258 @@ -116,6 +113,8 @@
259    UNDERSCORE = chr("_")
260    SPACE = chr(" ")
261    TAB = chr("\t")
262 +  HOOK = chr("?")
263 +  EQUALS = chr("=")
264  
265    # encode a header value according to the RFC-2047 quoted-printable spec,
266    # allowing non-ASCII characters to appear in header values, and wrapping
267 @@ -137,8 +136,8 @@
268    # return a string representing the given character-code in quoted-printable
269    # format
270    def quoted_encode_char(b)
271 -    if b>126 || b==UNDERSCORE || b==TAB
272 -      sprintf("=%02x", b)
273 +    if b>126 || b==UNDERSCORE || b==TAB || b==HOOK || b==EQUALS
274 +      sprintf("=%02X", b)
275      elsif b == SPACE
276        "_"
277      else
278 @@ -163,8 +162,9 @@
279  
280    # gives a string starting "=?", and including a charset specification, that
281    # marks the start of a quoted-printable character sequence
282 -  def marker_start_quoted
283 -    "=?#{@charset}?#{@encoding}?"
284 +  def marker_start_quoted(charset=nil)
285 +    charset = @charset if charset.nil?
286 +    "=?#{charset}?#{@encoding}?"
287    end
288  
289    # test to see of the given string contains non-ASCII characters
290 @@ -388,6 +388,7 @@
291  class FileEntry
292    def initialize(path)
293      @path = path
294 +    @fromVer = @toVer = nil
295      @lineAdditions = @lineRemovals = 0
296      @repository = Repository.get(path)
297      @repository.merge_common_prefix(basedir())
298 @@ -533,6 +534,14 @@
299  # TODO: consolidate these into a nicer framework,
300  mailSub = proc { |match| "<a href=\"mailto:#{match}\">#{match}</a>" }
301  urlSub = proc { |match| "<a href=\"#{match}\">#{match}</a>" }
302 +gforgeTaskSub = proc { |match|
303 +  match =~ /([0-9]+)/
304 +  "<a href=\"#{$gforgeTaskURL.sub(/%s/, $1)}\">#{match}</a>"
305 +}
306 +gforgeBugSub = proc { |match|
307 +  match =~ /([0-9]+)/
308 +  "<a href=\"#{$gforgeBugURL.sub(/%s/, $1)}\">#{match}</a>"
309 +}
310  bugzillaSub = proc { |match|
311    match =~ /([0-9]+)/
312    "<a href=\"#{$bugzillaURL.sub(/%s/, $1)}\">#{match}</a>"
313 @@ -544,11 +553,27 @@
314    match =~ /([0-9]+)/
315    "<a href=\"#{$ticketURL.sub(/%s/, $1)}\">#{match}</a>"
316  }
317 +issueSub = proc { |match|
318 +  match =~ /([0-9]+)/
319 +  "<a href=\"#{$issueURL.sub(/%s/, $1)}\">#{match}</a>"
320 +}
321  wikiSub = proc { |match| 
322 -  match =~ /\[\[(.*)\]\]/
323 +  match =~ /\[\[(.*?)\]\]/
324    raw = $1
325    "<a href=\"#{$wikiURL.sub(/%s/, urlEncode(raw))}\">[[#{raw}]]</a>"
326  }
327 +xplannerIterationSub = proc { |match|
328 +  match =~ /([0-9]+)/
329 +  "<a href=\"#{$xplannerIterationURL.sub(/%s/, $1)}\">#{match}</a>"
330 +}
331 +xplannerProjectSub = proc { |match|
332 +  match =~ /([0-9]+)/
333 +  "<a href=\"#{$xplannerProjectURL.sub(/%s/, $1)}\">#{match}</a>"
334 +}
335 +xplannerStorySub = proc { |match|
336 +  match =~ /([0-9]+)/
337 +  "<a href=\"#{$xplannerStoryURL.sub(/%s/, $1)}\">#{match}</a>"
338 +}
339  commentSubstitutions = {
340                 '(?:mailto:)?[\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+\b' => mailSub,
341                 '\b(?:http|https|ftp):[^ \t\n<>"]+[\w/]' => urlSub
342 @@ -670,6 +695,12 @@
343    def diff(file)
344      '-&gt;'
345    end
346 +
347 +  # may be overridden by subclasses that are able to make a hyperlink to a
348 +  # history log for a file
349 +  def log(file)
350 +    ''
351 +  end
352  end
353  
354  # Superclass for objects that can link to CVS frontends on the web (ViewCVS,
355 @@ -710,6 +741,14 @@
356      "<a href=\"#{diff_url(file)}\">#{super(file)}</a>"
357    end
358  
359 +  def log(file)
360 +    link = log_url(file)
361 +    if link
362 +      return "<span id=\"info\">(<a href=\"#{link}\">log</a>)</span>"
363 +    end
364 +    return nil
365 +  end
366 +
367   protected
368    def add_repo(url)
369      if @repository_name
370 @@ -722,6 +761,10 @@
371        url
372      end
373    end
374 +
375 +  def log_url(file)
376 +    nil
377 +  end
378  end
379  
380  # Link to ViewCVS
381 @@ -745,6 +788,15 @@
382    def diff_url(file)
383      add_repo("#{@base_url}#{urlEncode(file.path)}.diff?r1=#{file.fromVer}&amp;r2=#{file.toVer}")
384    end
385 +
386 +  def log_url(file)
387 +    if file.toVer
388 +      log_anchor = "#rev#{file.toVer}"
389 +    else
390 +      log_anchor = ""
391 +    end
392 +    add_repo("#{@base_url}#{urlEncode(file.path)}#{log_anchor}")
393 +  end
394  end
395  
396  # Link to Chora, from the Horde framework
397 @@ -767,9 +819,9 @@
398  class CVSwebFrontend < WebFrontend
399    def path_url(path, tag)
400      if tag == nil
401 -      add_repo(@base_url + urlEncode(path))
402 +      add_repo(@base_url + urlEncode(path) + "/")
403      else
404 -      add_repo("#{@base_url}#{urlEncode(path)}?only_with_tag=#{urlEncode(tag)}")
405 +      add_repo("#{@base_url}#{urlEncode(path)}/?only_with_tag=#{urlEncode(tag)}")
406      end
407    end
408  
409 @@ -780,9 +832,45 @@
410    def diff_url(file)
411      add_repo("#{@base_url}#{urlEncode(file.path)}.diff?r1=text&amp;tr1=#{file.fromVer}&amp;r2=text&amp;tr2=#{file.toVer}&amp;f=h")
412    end
413 +
414 +  protected
415 +
416 +  def log_url(file)
417 +    if file.toVer
418 +      log_anchor = "#rev#{file.toVer}"
419 +    else
420 +      log_anchor = ""
421 +    end
422 +    add_repo("#{@base_url}#{urlEncode(file.path)}#{log_anchor}")
423 +  end
424  end
425  
426 +# Link to Trac
427 +class TracFrontend < WebFrontend
428 +  def path_url(path, tag)
429 +    add_repo("#{@base_url}browser/#{urlEncode(path)}")
430 +  end
431  
432 +  def version_url(path, version)
433 +    add_repo("#{@base_url}browser/#{urlEncode(path)}?rev=#{version}")
434 +  end
435 +
436 +  def diff_url(file)
437 +    add_repo("#{@base_url}changeset/#{file.toVer}")
438 +  end
439 +
440 +  protected
441 +
442 +  def log_url(file)
443 +    if file.toVer
444 +      log_anchor = "?rev=#{file.toVer}"
445 +    else
446 +      log_anchor = ""
447 +    end
448 +    add_repo("#{@base_url}log/#{urlEncode(file.path)}#{log_anchor}")
449 +  end
450 +end
451 +
452  # in need of refactoring...
453  
454  # Note when LogReader finds record of a file that was added in this commit
455 @@ -958,7 +1046,7 @@
456      end
457      shift(nil)
458      if @truncatedLineCount>0
459 -      println("<strong class=\"error\" title=\"#{@truncatedLineCount} lines truncated at column #{$maxDiffLineLength}\">[Note: Some over-long lines of diff output only partialy shown]</strong>")
460 +      println("<strong class=\"error\" title=\"#{@truncatedLineCount} lines truncated at column #{$maxDiffLineLength}\">[Note: Some over-long lines of diff output only partially shown]</strong>")
461      end
462    end
463  
464 @@ -1181,7 +1269,7 @@
465  
466  # an RFC 822 email address
467  class EmailAddress
468 -  def initialize(text)
469 +  def initialize(text, charset=nil)
470      if text =~ /^\s*([^<]+?)\s*<\s*([^>]+?)\s*>\s*$/
471        @personal_name = $1
472        @address = $2
473 @@ -1189,9 +1277,10 @@
474        @personal_name = nil
475        @address = text
476      end
477 +    @charset=charset
478    end
479  
480 -  attr_accessor :personal_name, :address
481 +  attr_accessor :personal_name, :address, :charset
482  
483    def has_personal_name?
484      return !@personal_name.nil?
485 @@ -1222,7 +1311,7 @@
486    # rfc2047 encode the word, if it contains non-ASCII characters
487    def encode_word(word)
488      if $encoder.requires_rfc2047?(word)
489 -      encoded = $encoder.marker_start_quoted
490 +      encoded = $encoder.marker_start_quoted(@charset)
491        $encoder.each_char_encoded(word) do |code|
492         encoded << code
493        end
494 @@ -1237,6 +1326,7 @@
495  cvsroot_dir = "#{ENV['CVSROOT']}/CVSROOT"
496  $config = "#{cvsroot_dir}/cvsspam.conf"
497  $users_file = "#{cvsroot_dir}/users"
498 +$users_file_charset = nil
499  
500  $debug = false
501  $recipients = Array.new
502 @@ -1245,14 +1335,21 @@
503  $no_removed_file_diff = false
504  $no_added_file_diff = false
505  $no_diff = false
506 -$task_keywords = ['TODO', 'FIXME']
507 +$task_keywords = ['TODO', 'FIXME', 'FIXIT', 'todo']
508  $bugzillaURL = nil
509 +$gforgeBugURL = nil
510 +$gforgeTaskURL = nil
511  $wikiURL = nil
512  $jiraURL = nil
513  $ticketURL = nil
514 +$issueURL = nil
515  $viewcvsURL = nil
516 +$xplannerIterationURL = nil
517 +$xplannerProjectURL = nil
518 +$xplannerStoryURL = nil
519  $choraURL = nil
520  $cvswebURL = nil
521 +$tracURL = nil
522  $from_address = nil
523  $subjectPrefix = nil
524  $files_in_subject = false;
525 @@ -1261,6 +1358,7 @@
526  # 2MiB limit on attached diffs,
527  $mail_size_limit = 1024 * 1024 * 2
528  $arg_charset = nil
529 +$cvsroot_email_header = false
530  
531  require 'getoptlong'
532  
533 @@ -1321,6 +1419,8 @@
534    blah("Config file '#{$config}' not found, ignoring")
535  end
536  
537 +blah("Users file: '#{$users_file}'")
538 +
539  unless $arg_charset.nil?
540    $charset = $arg_charset
541  end
542 @@ -1337,6 +1437,9 @@
543  elsif $cvswebURL !=nil
544    $cvswebURL << "/" unless $cvswebURL =~ /\/$/
545    $frontend = CVSwebFrontend.new($cvswebURL)
546 +elsif $tracURL !=nil
547 +  $tracURL << "/" unless $tracURL =~ /\/$/
548 +  $frontend = TracFrontend.new($tracURL)
549  else
550    $frontend = NoFrontend.new
551  end
552 @@ -1353,17 +1456,35 @@
553  
554  
555  if $bugzillaURL != nil
556 -  commentSubstitutions['\b[Bb][Uu][Gg]\s*#?[0-9]+'] = bugzillaSub
557 +  commentSubstitutions['\b[Bb](?:[Uu][Gg])?\s*[#:]?\s*\[?[0-9]+\]?'] = bugzillaSub
558  end
559 +if $gforgeBugURL != nil
560 +  commentSubstitutions['\B\[#[0-9]+\]'] = gforgeBugSub
561 +end
562 +if $gforgeTaskURL != nil
563 +  commentSubstitutions['\B\[[Tt][0-9]+\]'] = gforgeTaskSub
564 +end
565  if $jiraURL != nil
566    commentSubstitutions['\b[a-zA-Z]+-[0-9]+\b'] = jiraSub
567  end
568  if $ticketURL != nil
569    commentSubstitutions['\b[Tt][Ii][Cc][Kk][Ee][Tt]\s*#?[0-9]+\b'] = ticketSub
570  end
571 +if $issueURL != nil
572 +  commentSubstitutions['\b[Ii][Ss][Ss][Uu][Ee]\s*#?[0-9]+\b'] = issueSub
573 +end
574  if $wikiURL != nil
575    commentSubstitutions['\[\[.+\]\]'] = wikiSub
576  end
577 +if $xplannerIterationURL != nil
578 +  commentSubstitutions['\bXI\[?[0-9]+\]?'] = xplannerIterationSub
579 +end
580 +if $xplannerProjectURL != nil
581 +  commentSubstitutions['\bXP\[?[0-9]+\]?'] = xplannerProjectSub
582 +end
583 +if $xplannerStoryURL != nil
584 +  commentSubstitutions['\bXS\[?[0-9]+\]?'] = xplannerStorySub
585 +end
586  $commentEncoder = MultiSub.new(commentSubstitutions)
587  
588  
589 @@ -1546,11 +1667,14 @@
590      elsif file.removal?
591        name = "<span id=\"removed\">#{name}</span>"
592      end
593 +    mail.print("<td>")
594      if file.has_diff?
595 -      mail.print("<td><tt>#{prefix}<a href=\"#file#{file_count}\">#{name}</a></tt></td>")
596 +      mail.print("<tt>#{prefix}<a href=\"#file#{file_count}\">#{name}</a></tt>")
597      else
598 -      mail.print("<td><tt>#{prefix}#{name}</tt></td>")
599 +      mail.print("<tt>#{prefix}#{name}</tt>")
600      end
601 +    mail.print(" #{$frontend.log(file)}")
602 +    mail.print("</td>")
603      if file.isEmpty
604        mail.print("<td colspan=\"2\" align=\"center\"><small id=\"info\">[empty]</small></td>")
605      elsif file.isBinary
606 @@ -1667,12 +1791,13 @@
607  # CVSROOT/users file, if the file exists.  The argument is returned unchanged
608  # if no alias is found.
609  def sender_alias(email)
610 +  blah("Lookup '#{email}' from users file")
611    if File.exists?($users_file)
612      File.open($users_file) do |io|
613        io.each_line do |line|
614          if line =~ /^([^:]+)\s*:\s*(['"]?)([^\n\r]+)(\2)/
615            if email.address == $1
616 -            return EmailAddress.new($3)
617 +            return EmailAddress.new($3, $users_file_charset)
618            end
619          end
620        end
621 @@ -1686,6 +1811,8 @@
622  # sensible header formatting, and for ensuring that the body is seperated
623  # from the message headers by a blank line (as it is required to be).
624  class MailContext
625 +  ENCODE_HEADERS = ["Subject", "X-CVSspam-Module-Path"]
626 +
627    def initialize(io)
628      @done_headers = false
629      @io = io
630 @@ -1695,8 +1822,8 @@
631    # called
632    def header(name, value)
633      raise "headers already commited" if @done_headers
634 -    if name == "Subject"
635 -      $encoder.encode_header(@io, "Subject", value)
636 +    if ENCODE_HEADERS.include?(name)
637 +      $encoder.encode_header(@io, name, value)
638      else
639        @io.puts("#{name}: #{value}")
640      end
641 @@ -1769,7 +1896,7 @@
642        ctx.header("To", recipients.map{|addr| addr.encoded}.join(','))
643        blah("Mail From: <#{from}>")
644        ctx.header("From", from.encoded) if from
645 -      ctx.header("Date", Time.now.utc.strftime(DATE_HEADER_FORMAT))
646 +      ctx.header("Date", Time.now.rfc2822)
647        yield ctx
648      end
649    end
650 @@ -1800,10 +1927,10 @@
651    return unless $fileEntries.length == 1
652    file = $fileEntries[0]
653    name = zap_header_special_chars(file.path)
654 -  unless file.fromVer == "NONE"
655 +  if file.fromVer
656      mail.header("References", make_msg_id("#{name}.#{file.fromVer}", $hostname))
657    end
658 -  unless file.toVer == "NONE"
659 +  if file.toVer
660      mail.header("Message-ID", make_msg_id("#{name}.#{file.toVer}", $hostname))
661    end
662  end
663 @@ -1834,6 +1961,14 @@
664      end
665    end
666    mail.header("X-Mailer", "CVSspam #{$version} <http://www.badgers-in-foil.co.uk/projects/cvsspam/>")
667 +  if $cvsroot_email_header
668 +    mod = '/'
669 +    if Repository.count == 1
670 +      rep = Repository.array.first
671 +      mod << rep.common_prefix
672 +    end
673 +    mail.header("X-CVSspam-Module-Path", mod)
674 +  end
675  
676    mail.body do |body|
677      make_html_email(body)
This page took 0.105439 seconds and 4 git commands to generate.