pidgin2adium 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.autotest ADDED
@@ -0,0 +1,9 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ at.add_mapping(/ext\/.*\/(.*)\.[ch]/) do |_, m|
3
+ ["test/test_#{m[1]}_extn.rb"]
4
+ end
5
+ end
6
+
7
+ Autotest.add_hook :run_command do |at|
8
+ system "rake compile"
9
+ end
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ === 3.0.0 / 2010-01-31
2
+ * balance_tags.rb is now a C extension (Pidgin2Adium.balance_tags_c)
3
+ - the pure-ruby mixin balance_tags (without the trailing "_c") is gone
4
+ * Better handling of command-line arguments
5
+ * Format time zones offsets correctly (e.g. "+0500", not "+-0500")
6
+ * Write Yahoo! and Jabber logs to correct directories (#27710)
7
+ * Better matching of regexes against time strings
8
+ * Better documentation
9
+
1
10
  === 2.0.2 / 2009-12-18
2
11
  * Much better documentation (more of it, and higher quality too!)
3
12
  * Allow user-provided output dir at commandline
data/Manifest.txt CHANGED
@@ -1,10 +1,18 @@
1
+ .autotest
1
2
  History.txt
2
3
  Manifest.txt
3
4
  README.rdoc
4
5
  Rakefile.rb
5
6
  bin/pidgin2adium
7
+ ext/balance_tags_c/balance_tags_c.c
8
+ ext/balance_tags_c/extconf.rb
6
9
  lib/pidgin2adium.rb
7
- lib/pidgin2adium/balance_tags.rb
8
10
  lib/pidgin2adium/log_converter.rb
9
11
  lib/pidgin2adium/log_file.rb
10
12
  lib/pidgin2adium/log_parser.rb
13
+ script/console
14
+ script/destroy
15
+ script/generate
16
+ tasks/extconf.rake
17
+ tasks/extconf/balance_tags_c.rake
18
+ test/test_balance_tags_c_extn.rb
data/README.rdoc CHANGED
@@ -37,10 +37,7 @@ Or:
37
37
  $ pidgin2adium -i pidgin-logs -a gabe,gabeb-w,gbw
38
38
 
39
39
  ===Example (using library)
40
- The library style allows you to parse a log file and get back a
41
- LogFile[link:classes/Pidgin2Adium/LogFile.html] instance for easy reading, manipulation, etc.
42
- You can also create log files yourself using Pidgin2Adium.parse_and_generate[link:classes/Pidgin2Adium.html#M000006].
43
- For batch processing, use LogConverter[link:classes/Pidgin2Adium/LogConverter.html].
40
+ The library style allows you to parse a log file and get back a LogFile[link:classes/Pidgin2Adium/LogFile.html] instance for easy reading, manipulation, etc. If you don't need to do anything with the individual messages, use Pidgin2Adium.parse[link:classes/Pidgin2Adium.html#M000002].
44
41
 
45
42
  require 'pidgin2adium'
46
43
  logfile = Pidgin2Adium.parse("/path/to/log/file.html", "gabe,gbw,gabeb-w")
@@ -81,15 +78,17 @@ For batch processing, use LogConverter[link:classes/Pidgin2Adium/LogConverter.ht
81
78
  puts "Successfully wrote out log file!"
82
79
  puts "Path to output file: #{success}"
83
80
  end
84
- # This deletes search indexes to Adium re-indexes the new chat logs.
85
- # Not automatically called after log_file.write_out()
86
- # If you're converting >1 log, call it after converting all of them, since
87
- # it takes up a tiny bit of processing power.
81
+ # This deletes search indexes so Adium re-indexes the new chat logs.
82
+ # It is not automatically called after log_file.write_out()
83
+ # Call it after converting all the logs, since it takes up a bit of
84
+ # processing power.
88
85
  Pidgin2Adium.delete_search_indexes()
89
86
  end
90
87
 
91
88
  ===Example 2 (using library)
92
- If you want to output the logfile to an output dir instead of just parsing it, use Pidgin2Adium.parse_and_generate:
89
+ If you want to parse the file and write it out instead of just parsing it, use Pidgin2Adium.parse_and_generate.
90
+
91
+ Note: For batch processing, use LogConverter[link:classes/Pidgin2Adium/LogConverter.html].
93
92
 
94
93
  require 'pidgin2adium'
95
94
  # Both options are optional; without :output_dir, writes to Adium log dir
data/Rakefile.rb CHANGED
@@ -18,12 +18,23 @@ $hoe = Hoe.spec 'pidgin2adium' do
18
18
  #self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
19
19
  self.rubyforge_name = self.name # this is default value
20
20
  # self.extra_deps = [['activesupport','>= 2.0.2']]
21
+
22
+ self.spec_extras[:extensions] = "ext/balance_tags_c/extconf.rb"
23
+ end
24
+
25
+ $hoe.spec.rdoc_options = %w{--main README.rdoc}
26
+
27
+ # Use hanna RDoc template, if available
28
+ begin
29
+ gem "hanna"
30
+ $hoe.spec.rdoc_options << '-T hanna'
31
+ rescue GEM::LoadError
32
+ # hanna not installed, continue
21
33
  end
22
- # Use hanna RDoc template
23
- $hoe.spec.rdoc_options = %w{--main README.rdoc -T hanna}
24
34
 
25
35
  require 'newgem/tasks'
26
36
  Dir['tasks/**/*.rake'].each { |t| load t }
37
+ task :postrelease => [:publish_docs, :announce]
27
38
 
28
39
  # TODO - want other tests/tasks run by default? Add them to the list
29
40
  # remove_task :default
data/bin/pidgin2adium CHANGED
@@ -32,7 +32,7 @@ oparser = OptionParser.new do |opts|
32
32
  "is you. Whitespace and case do not matter.") do |aliases|
33
33
  options[:aliases] = aliases
34
34
  end
35
- opts.on('-o', '--out [OUT_DIR]',
35
+ opts.on('-o', '--out OUT_DIR',
36
36
  'The top-level directory under which to',
37
37
  'store the logs (each in its own folder',
38
38
  'by screen name).',
@@ -0,0 +1,198 @@
1
+ /*
2
+ * Balances tags of string using a modified stack. Returns a balanced string.
3
+ *
4
+ * From Wordpress's formatting.php and rewritten in C by
5
+ * Gabe Berke-Williams, 2010.
6
+ *
7
+ * Original Author:: Leonard Lin <leonard@acm.org>
8
+ * License:: GPL v2.0
9
+ * Copyright:: November 4, 2001
10
+ */
11
+
12
+ #include <ruby.h>
13
+
14
+ #ifndef RARRAY_PTR
15
+ #define RARRAY_PTR(arr) RARRAY(arr)->ptr
16
+ #endif
17
+
18
+ #ifndef RSTRING_LEN
19
+ #define RSTRING_LEN(str) RSTRING(str)->len
20
+ #endif
21
+
22
+ VALUE balance_tags_c(VALUE, VALUE);
23
+ static VALUE mP2A;
24
+
25
+ /*
26
+ * call-seq: Pidgin2Adium.balance_tags_c(text) => text with balanced HTML tags
27
+ *
28
+ * Balances tags of _text_. Returns modified text.
29
+ */
30
+ VALUE balance_tags_c(VALUE mod, VALUE text){
31
+ if( TYPE(text) != T_STRING ){
32
+ rb_raise(rb_eArgError, "bad argument to balance_tags_c, String only please.");
33
+ }
34
+ VALUE tagstack = rb_ary_new2(1);
35
+ int stacksize = 0;
36
+ VALUE tagqueue = rb_str_new2("");
37
+ VALUE ZERO = INT2FIX(0),
38
+ ONE = INT2FIX(1);
39
+ VALUE newtext = rb_str_new2("");
40
+ // Known single-entity/self-closing tags
41
+ VALUE single_tags = rb_ary_new3(5,
42
+ rb_str_new2("br"),
43
+ rb_str_new2("hr"),
44
+ rb_str_new2("img"),
45
+ rb_str_new2("input"),
46
+ rb_str_new2("meta"));
47
+ // Tags that can be immediately nested within themselves
48
+ VALUE nestable_tags = rb_ary_new3(4,
49
+ rb_str_new2("blockquote"),
50
+ rb_str_new2("div"),
51
+ rb_str_new2("span"),
52
+ rb_str_new2("font"));
53
+ // 1: tagname, with possible leading "/"
54
+ // 2: attributes
55
+ VALUE tag_regex = rb_reg_regcomp(rb_str_new2("<(\\/?\\w*)\\s*([^>]*)>"));
56
+ VALUE pos; // position in text
57
+ VALUE match;
58
+ VALUE tag;
59
+ VALUE attributes;
60
+ VALUE t; // loop variable when iterating over tagstack at end of while loop
61
+ int matchlen;
62
+ int done = 0;
63
+ int j, k, i; // loop counters
64
+
65
+ // WP bug fix for comments - in case you REALLY meant to type '< !--'
66
+ rb_funcall(text, rb_intern("gsub!"), 2,
67
+ rb_str_new2("< !--"),
68
+ rb_str_new2("< !--"));
69
+
70
+ // WP bug fix for LOVE <3 (and other situations with '<' before a number)
71
+ rb_funcall(text, rb_intern("gsub!"), 2,
72
+ rb_reg_regcomp(rb_str_new2("<([0-9]{1})")),
73
+ rb_str_new2("&lt;\\1"));
74
+
75
+ pos = rb_funcall(text, rb_intern("=~"), 1, tag_regex);
76
+ done = (pos == Qnil);
77
+ while ( ! done ){
78
+ rb_str_concat(newtext, tagqueue);
79
+ match = rb_funcall(text, rb_intern("match"), 1, tag_regex);
80
+ tag = rb_funcall(rb_reg_nth_match(1, match), rb_intern("downcase"), 0);
81
+ attributes = rb_reg_nth_match(2, match);
82
+
83
+ matchlen = NUM2INT(rb_funcall(rb_reg_nth_match(0, match), rb_intern("size"), 0));
84
+
85
+ // clear the shifter
86
+ tagqueue = rb_str_new2("");
87
+ // Pop or Push
88
+ if (0 == rb_str_cmp(rb_str_substr(tag, 0, 1), rb_str_new2("/"))){ // End Tag
89
+ rb_funcall(tag, rb_intern("slice!"), 2, ZERO, ONE);
90
+ // if too many closing tags
91
+ if(stacksize <= 0){
92
+ tag = rb_str_new2("");
93
+ //or close to be safe: tag = '/' << tag
94
+ } else if (0 == rb_str_cmp(RARRAY_PTR(tagstack)[stacksize - 1], tag)){
95
+ // found closing tag
96
+ // if stacktop value == tag close value then pop
97
+ // Close Tag
98
+ tag = rb_str_append(rb_str_new2("</"), tag);
99
+ rb_str_concat(tag, rb_str_new2(">"));
100
+ // Pop
101
+ rb_ary_pop(tagstack);
102
+ stacksize--;
103
+ } else { // closing tag not at top, search for it
104
+ for(j=stacksize-1; j>=0; j--){
105
+ if(0 == rb_str_cmp(RARRAY_PTR(tagstack)[j], tag) ){
106
+ // add tag to tagqueue
107
+ for(k = stacksize-1;k>=j;k--){
108
+ rb_str_concat(tagqueue, rb_str_new2("</"));
109
+ rb_str_concat(tagqueue, rb_ary_pop(tagstack));
110
+ rb_str_concat(tagqueue, rb_str_new2(">"));
111
+ stacksize--;
112
+ }
113
+ break;
114
+ }
115
+ }
116
+ tag = rb_str_new2("");
117
+ }
118
+ } else {
119
+ // Begin Tag
120
+
121
+ // Tag Cleaning
122
+
123
+ if( ( RSTRING_LEN(attributes) > 0 && // test length before rb_str_substr
124
+ (0 == rb_str_cmp(rb_str_substr(attributes, -1, 1), rb_str_new2("/"))) ) ||
125
+ (0 == rb_str_cmp(tag, rb_str_new2(""))) ){
126
+ // If: self-closing or '', don't do anything.
127
+ } else if ( rb_ary_includes(single_tags, tag) ) {
128
+ // ElseIf: it's a known single-entity tag but it doesn't close itself, do so
129
+ rb_str_concat(attributes, rb_str_new2("/"));
130
+ } else {
131
+ // Push the tag onto the stack
132
+ // If the top of the stack is the same as the tag we want
133
+ // to push, close previous tag
134
+ if ( (stacksize > 0) &&
135
+ (Qfalse == rb_ary_includes(nestable_tags, tag)) &&
136
+ (0 == rb_str_cmp(rb_ary_entry(tagstack, stacksize - 1), tag))){
137
+ tagqueue = rb_str_new2("</");
138
+ rb_str_concat(tagqueue, rb_ary_pop(tagstack));
139
+ rb_str_concat(tagqueue, rb_str_new2(">"));
140
+ stacksize--;
141
+ }
142
+ rb_ary_push(tagstack, tag);
143
+ stacksize++;
144
+ }
145
+
146
+ // Attributes
147
+ if( 0 != rb_str_cmp(attributes, rb_str_new2("")) ){
148
+ attributes = rb_str_plus(rb_str_new2(" "), attributes);
149
+ }
150
+ tag = rb_str_plus(rb_str_new2("<"), tag);
151
+ rb_str_concat(tag, attributes);
152
+ rb_str_concat(tag, rb_str_new2(">"));
153
+ //If already queuing a close tag, then put this tag on, too
154
+ if( RSTRING_LEN(tagqueue) > 0 ){
155
+ rb_str_concat(tagqueue, tag);
156
+ tag = rb_str_new2("");
157
+ }
158
+ }
159
+ rb_str_concat(newtext,
160
+ rb_str_plus(rb_str_substr(text, 0, pos-1), tag));
161
+ text = rb_str_substr(text,
162
+ NUM2INT(pos)+matchlen,
163
+ RSTRING_LEN(text) - (NUM2INT(pos)+matchlen));
164
+ pos = rb_funcall(text, rb_intern("=~"), 1, tag_regex);
165
+ done = (pos == Qnil);
166
+ }
167
+
168
+ // Clear Tag Queue
169
+ rb_str_concat(newtext, tagqueue);
170
+
171
+ // Add Remaining text
172
+ rb_str_concat(newtext, text);
173
+
174
+ i = NUM2INT(rb_funcall(tagstack, rb_intern("length"), 0)) - 1;
175
+ // Empty Stack
176
+ for(; i >= 0; i--){
177
+ // Add remaining tags to close
178
+ t = RARRAY_PTR(tagstack)[i];
179
+ rb_str_concat(newtext, rb_str_new2("</"));
180
+ rb_str_concat(newtext, t);
181
+ rb_str_concat(newtext, rb_str_new2(">"));
182
+ }
183
+
184
+ // WP fix for the bug with HTML comments
185
+ rb_funcall(newtext, rb_intern("gsub!"), 2,
186
+ rb_str_new2("< !--"),
187
+ rb_str_new2("<!--"));
188
+ rb_funcall(newtext, rb_intern("gsub!"), 2,
189
+ rb_str_new2("< !--"),
190
+ rb_str_new2("< !--"));
191
+
192
+ return newtext;
193
+ }
194
+
195
+ void Init_balance_tags_c(){
196
+ mP2A = rb_define_module("Pidgin2Adium");
197
+ rb_define_module_function(mP2A, "balance_tags_c", balance_tags_c, 1);
198
+ }
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("balance_tags_c")
4
+ create_makefile("balance_tags_c")
data/lib/pidgin2adium.rb CHANGED
@@ -14,7 +14,7 @@ module Pidgin2Adium
14
14
  ADIUM_LOG_DIR = File.expand_path('~/Library/Application Support/Adium 2.0/Users/Default/Logs/') << '/'
15
15
  # These files/directories show up in Dir.entries()
16
16
  BAD_DIRS = %w{. .. .DS_Store Thumbs.db .system}
17
- VERSION = "2.0.2"
17
+ VERSION = "3.0.0"
18
18
  # For displaying after we finish converting
19
19
  @@oops_messages = []
20
20
  @@error_messages = []
@@ -38,6 +38,7 @@ module Pidgin2Adium
38
38
  module_function :log_msg, :oops, :error
39
39
  #######################
40
40
 
41
+ # Parses the provided log.
41
42
  # Returns a LogFile instance or false if an error occurred.
42
43
  def parse(logfile_path, my_aliases)
43
44
  logfile_path = File.expand_path(logfile_path)
@@ -54,7 +55,8 @@ module Pidgin2Adium
54
55
 
55
56
  return parser.parse()
56
57
  end
57
-
58
+
59
+ # Parses the provided log and writes out the log in Adium format.
58
60
  # Returns the path to the converted log, false if an error occurred, or
59
61
  # Pidgin2Adium::FILE_EXISTS if file already exists AND opts[:overwrite] =
60
62
  # false.
@@ -26,12 +26,12 @@ module Pidgin2Adium
26
26
  # key is for Pidgin, value is for Adium
27
27
  # Just used for <service>.<screenname> in directory structure
28
28
  service_name_map = {'aim' => 'AIM',
29
- 'jabber' =>'jabber',
29
+ 'jabber' =>'Jabber',
30
30
  'gtalk'=> 'GTalk',
31
31
  'icq' => 'ICQ',
32
32
  'qq' => 'QQ',
33
33
  'msn' => 'MSN',
34
- 'yahoo' => 'Yahoo'}
34
+ 'yahoo' => 'Yahoo!'}
35
35
 
36
36
  @service = service_name_map[service.downcase]
37
37
  end
@@ -7,7 +7,7 @@
7
7
  require 'parsedate'
8
8
  require 'time' # for Time.zone_offset
9
9
 
10
- require 'pidgin2adium/balance_tags'
10
+ require 'balance_tags_c'
11
11
  require 'pidgin2adium/log_file'
12
12
 
13
13
  module Pidgin2Adium
@@ -42,12 +42,12 @@ module Pidgin2Adium
42
42
  # Time regexes must be set before pre_parse().
43
43
  # "4/18/2007 11:02:00 AM" => %w{4, 18, 2007, 11, 02, 00, AM}
44
44
  # ONLY used (if at all) in first line of chat ("Conversation with...at...")
45
- @time_regex_first_line = %r{(\d{1,2})/(\d{1,2})/(\d{4}) (\d{1,2}):(\d{2}):(\d{2}) ([AP]M)}
45
+ @time_regex_first_line = %r{^(\d{1,2})/(\d{1,2})/(\d{4}) (\d{1,2}):(\d{2}):(\d{2}) ([AP]M)$}
46
46
  # "2007-04-17 12:33:13" => %w{2007, 04, 17, 12, 33, 13}
47
- @time_regex = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/
47
+ @time_regex = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/
48
48
  # sometimes a line in a chat doesn't have a full timestamp
49
49
  # "04:22:05 AM" => %w{04 22 05 AM}
50
- @minimal_time_regex = /(\d{1,2}):(\d{2}):(\d{2})( [AP]M)?/
50
+ @minimal_time_regex = /^(\d{1,2}):(\d{2}):(\d{2})( [AP]M)?$/
51
51
 
52
52
  # Whether or not the first line is parseable.
53
53
  @first_line_is_valid = true
@@ -90,10 +90,10 @@ module Pidgin2Adium
90
90
  /(.+) is offering to send file/,
91
91
  /^Transfer of file .+ complete$/,
92
92
  /Error reading|writing|accessing .+: .+/,
93
- /You cancelled the transfer of/,
93
+ /You cancell?ed the transfer of/,
94
94
  /File transfer cancelled/,
95
- /(.+) cancelled the transfer of/,
96
- /(.+) cancelled the file transfer/,
95
+ /(.+?) cancell?ed the transfer of/,
96
+ /(.+?) cancelled the file transfer/,
97
97
  # Direct IM - actual (dis)connect events are their own types
98
98
  /^Attempting to connect to (.+) at .+ for Direct IM\./,
99
99
  /^Asking (.+) to connect to us at .+ for Direct IM\./,
@@ -106,9 +106,6 @@ module Pidgin2Adium
106
106
  /^Conflicting Key Received!$/,
107
107
  /^Error in decryption- asking for resend\.\.\.$/,
108
108
  /^Making new key pair\.\.\.$/,
109
- # file transfer
110
- /You canceled the transfer of/,
111
- /(.+?) canceled the transfer of/,
112
109
  # sending errors
113
110
  /^Last outgoing message not received properly- resetting$/,
114
111
  /Resending\.\.\./,
@@ -178,9 +175,8 @@ module Pidgin2Adium
178
175
  if tz_match and tz_match[1]
179
176
  tz_offset = tz_match[1]
180
177
  else
181
- zone = Time.local(Time.new.year).zone
182
178
  # "-0500" (3d rather than 2d to allow for "+")
183
- tz_offset = sprintf('+%03d00', Time.zone_offset(zone) / 3600)
179
+ tz_offset = sprintf('%+03d00', Time.zone_offset(Time.now.zone) / 3600)
184
180
  end
185
181
  return tz_offset
186
182
  end
@@ -255,7 +251,7 @@ module Pidgin2Adium
255
251
  user_SN = first_line_match[3].downcase.tr(' ', '')
256
252
  partner_SN = first_line_match[1]
257
253
  pidgin_chat_time_start = first_line_match[2]
258
- basic_time_info = case @first_line
254
+ basic_time_info = case pidgin_chat_time_start
259
255
  when @time_regex: [$1.to_i, $2.to_i, $3.to_i]
260
256
  when @time_regex_first_line: [$3.to_i, $1.to_i, $2.to_i]
261
257
  end
@@ -488,18 +484,15 @@ module Pidgin2Adium
488
484
 
489
485
  styleparts = style.split(/; ?/)
490
486
  styleparts.map! do |p|
491
- if p =~ /^color/
492
- # Regarding the bit with the ">", sometimes this happens:
493
- # <span style="color: #000000>today;">today was busy</span>
494
- # Then p = "color: #000000>today"
495
- # Or it can end in ">;", with no text before the semicolon.
496
- # So remove the ">" and anything following it.
497
-
498
- # Use regex instead of string, to account for funky ">" stuff
499
- if p =~ /color: #000000/
487
+ if p[0,5] == 'color'
488
+ if p.include?('color: #000000')
500
489
  next
501
490
  elsif p =~ /(color: #[0-9a-fA-F]{6})(>.*)?/
502
- # Keep the color but remove the bit after it
491
+ # Regarding the bit with the ">", sometimes this happens:
492
+ # <span style="color: #000000>today;">today was busy</span>
493
+ # Then p = "color: #000000>today"
494
+ # Or it can end in ">;", with no text before the semicolon.
495
+ # So keep the color but remove the ">" and anything following it.
503
496
  next($1)
504
497
  end
505
498
  else
@@ -546,7 +539,6 @@ module Pidgin2Adium
546
539
  # Basic message with body text (as opposed to pure status messages, which
547
540
  # have no body).
548
541
  class XMLMessage < Message
549
- include Pidgin2Adium
550
542
  def initialize(sender, time, buddy_alias, body)
551
543
  super(sender, time, buddy_alias)
552
544
  @body = body
@@ -571,7 +563,7 @@ module Pidgin2Adium
571
563
  normalize_body_entities!()
572
564
  # Fix mismatched tags. Yes, it's faster to do it per-message
573
565
  # than all at once.
574
- @body = balance_tags(@body)
566
+ @body = Pidgin2Adium.balance_tags_c(@body)
575
567
  if @buddy_alias[0,3] == '***'
576
568
  # "***<alias>" is what pidgin sets as the alias for a /me action
577
569
  @buddy_alias.slice!(0,3)
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/p2a.rb'}"
9
+ puts "Loading p2a gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,13 @@
1
+ namespace :extconf do
2
+ desc "Compiles the Ruby extension"
3
+ task :compile
4
+ end
5
+
6
+ task :compile => "extconf:compile"
7
+
8
+ task :test => :compile
9
+
10
+ BIN = "*.{bundle,jar,so,obj,pdb,lib,def,exp}"
11
+ $hoe.clean_globs |= ["ext/**/#{BIN}", "lib/**/#{BIN}", 'ext/**/Makefile']
12
+ $hoe.spec.require_paths = Dir['{lib,ext/*}']
13
+ $hoe.spec.extensions = FileList["ext/**/extconf.rb"].to_a
@@ -0,0 +1,43 @@
1
+ namespace :extconf do
2
+ extension = File.basename(__FILE__, '.rake')
3
+
4
+ ext = "ext/#{extension}"
5
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
6
+ ext_files = FileList[
7
+ "#{ext}/*.c",
8
+ "#{ext}/*.h",
9
+ "#{ext}/*.rl",
10
+ "#{ext}/extconf.rb",
11
+ "#{ext}/Makefile",
12
+ # "lib"
13
+ ]
14
+
15
+
16
+ task :compile => extension do
17
+ if Dir.glob("**/#{extension}.{o,so,dll}").length == 0
18
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
19
+ STDERR.puts "Gem actually failed to build. Your system is"
20
+ STDERR.puts "NOT configured properly to build #{GEM_NAME}."
21
+ STDERR.puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
22
+ exit(1)
23
+ end
24
+ end
25
+
26
+ desc "Builds just the #{extension} extension"
27
+ task extension.to_sym => ["#{ext}/Makefile", ext_so ]
28
+
29
+ file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
30
+ Dir.chdir(ext) do ruby "extconf.rb" end
31
+ end
32
+
33
+ file ext_so => ext_files do
34
+ Dir.chdir(ext) do
35
+ sh(PLATFORM =~ /win32/ ? 'nmake' : 'make') do |ok, res|
36
+ if !ok
37
+ require "fileutils"
38
+ FileUtils.rm Dir.glob('*.{so,o,dll,bundle}')
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+
3
+ $:.unshift File.dirname(__FILE__) + "/../ext/balance_tags_c"
4
+ require "balance_tags_c.so"
5
+
6
+ class TestBalanceTagsCExtn < Test::Unit::TestCase
7
+ def test_truth
8
+ assert true
9
+ end
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pidgin2adium
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabe B-W
@@ -9,9 +9,29 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-18 00:00:00 -08:00
12
+ date: 2010-01-31 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rubyforge
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: gemcutter
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.0
34
+ version:
15
35
  - !ruby/object:Gem::Dependency
16
36
  name: hoe
17
37
  type: :development
@@ -20,7 +40,7 @@ dependencies:
20
40
  requirements:
21
41
  - - ">="
22
42
  - !ruby/object:Gem::Version
23
- version: 2.4.0
43
+ version: 2.5.0
24
44
  version:
25
45
  description: |-
26
46
  Pidgin2Adium is a fast, easy way to convert Pidgin (formerly gaim) logs to the
@@ -30,23 +50,31 @@ email:
30
50
  - pidgin2adium@brandeis.edu
31
51
  executables:
32
52
  - pidgin2adium
33
- extensions: []
34
-
53
+ extensions:
54
+ - ext/balance_tags_c/extconf.rb
35
55
  extra_rdoc_files:
36
56
  - History.txt
37
57
  - Manifest.txt
38
58
  - README.rdoc
39
59
  files:
60
+ - .autotest
40
61
  - History.txt
41
62
  - Manifest.txt
42
63
  - README.rdoc
43
64
  - Rakefile.rb
44
65
  - bin/pidgin2adium
66
+ - ext/balance_tags_c/balance_tags_c.c
67
+ - ext/balance_tags_c/extconf.rb
45
68
  - lib/pidgin2adium.rb
46
- - lib/pidgin2adium/balance_tags.rb
47
69
  - lib/pidgin2adium/log_converter.rb
48
70
  - lib/pidgin2adium/log_file.rb
49
71
  - lib/pidgin2adium/log_parser.rb
72
+ - script/console
73
+ - script/destroy
74
+ - script/generate
75
+ - tasks/extconf.rake
76
+ - tasks/extconf/balance_tags_c.rake
77
+ - test/test_balance_tags_c_extn.rb
50
78
  has_rdoc: true
51
79
  homepage: http://rubyforge.org/projects/pidgin2adium/
52
80
  licenses: []
@@ -55,10 +83,10 @@ post_install_message:
55
83
  rdoc_options:
56
84
  - --main
57
85
  - README.rdoc
58
- - -T
59
- - hanna
86
+ - -T hanna
60
87
  require_paths:
61
88
  - lib
89
+ - ext/balance_tags_c
62
90
  required_ruby_version: !ruby/object:Gem::Requirement
63
91
  requirements:
64
92
  - - ">="
@@ -78,5 +106,5 @@ rubygems_version: 1.3.5
78
106
  signing_key:
79
107
  specification_version: 3
80
108
  summary: Pidgin2Adium is a fast, easy way to convert Pidgin (formerly gaim) logs to the Adium format
81
- test_files: []
82
-
109
+ test_files:
110
+ - test/test_balance_tags_c_extn.rb
@@ -1,118 +0,0 @@
1
- module Pidgin2Adium
2
- # Balances tags of string using a modified stack. Returns a balanced
3
- # string, but also affects the text passed into it!
4
- # Use text = balance_tags(text).
5
-
6
- # From Wordpress's formatting.php; rewritten in Ruby by Gabe
7
- # Berke-Williams, 2009.
8
- # Author:: Leonard Lin <leonard@acm.org>
9
- # License:: GPL v2.0
10
- # Copyright:: November 4, 2001
11
- def balance_tags( text )
12
- tagstack = []
13
- stacksize = 0
14
- tagqueue = ''
15
- newtext = ''
16
- single_tags = %w{br hr img input meta} # Known single-entity/self-closing tags
17
- #nestable_tags = %w{blockquote div span} # Tags that can be immediately nested within themselves
18
- nestable_tags = %w{blockquote div span font} # Tags that can be immediately nested within themselves
19
- # 1: tagname, with possible leading "/"
20
- # 2: attributes
21
- tag_regex = /<(\/?\w*)\s*([^>]*)>/
22
-
23
- # WP bug fix for comments - in case you REALLY meant to type '< !--'
24
- text.gsub!('< !--', '< !--')
25
-
26
- # WP bug fix for LOVE <3 (and other situations with '<' before a number)
27
- text.gsub!(/<([0-9]{1})/, '&lt;\1')
28
-
29
- while ( pos = (text =~ tag_regex) )
30
- newtext << tagqueue
31
- tag = $1.downcase
32
- attributes = $2
33
- matchlen = $~[0].size
34
-
35
- # clear the shifter
36
- tagqueue = ''
37
- # Pop or Push
38
- if (tag[0,1] == "/") # End Tag
39
- tag.slice!(0,1)
40
- # if too many closing tags
41
- if(stacksize <= 0)
42
- tag = ''
43
- #or close to be safe: tag = '/' << tag
44
- elsif (tagstack[stacksize - 1] == tag) # found closing tag
45
- # if stacktop value == tag close value then pop
46
- tag = '</' << tag << '>' # Close Tag
47
- # Pop
48
- tagstack.pop
49
- stacksize -= 1
50
- else # closing tag not at top, search for it
51
- (stacksize-1).downto(0) do |j|
52
- if (tagstack[j] == tag)
53
- # add tag to tagqueue
54
- ss = stacksize - 1
55
- ss.downto(j) do |k|
56
- tagqueue << '</' << tagstack.pop << '>'
57
- stacksize -= 1
58
- end
59
- break
60
- end
61
- end
62
- tag = ''
63
- end
64
- else
65
- # Begin Tag
66
-
67
- # Tag Cleaning
68
- if( (attributes[-1,1] == '/') || (tag == '') )
69
- # If: self-closing or '', don't do anything.
70
- elsif ( single_tags.include?(tag) )
71
- # ElseIf: it's a known single-entity tag but it doesn't close itself, do so
72
- attributes << '/'
73
- else
74
- # Push the tag onto the stack
75
- # If the top of the stack is the same as the tag we want to push, close previous tag
76
- if ((stacksize > 0) &&
77
- ! nestable_tags.include?(tag) &&
78
- (tagstack[stacksize - 1] == tag))
79
- tagqueue = '</' << tagstack.pop << '>'
80
- stacksize -= 1
81
- end
82
- tagstack.push(tag)
83
- stacksize += 1
84
- end
85
-
86
- # Attributes
87
- if(attributes != '')
88
- attributes = ' ' << attributes
89
- end
90
- tag = '<' << tag << attributes << '>'
91
- #If already queuing a close tag, then put this tag on, too
92
- if (tagqueue)
93
- tagqueue << tag
94
- tag = ''
95
- end
96
- end
97
- newtext << text[0,pos] << tag
98
- text = text[pos+matchlen, text.length - (pos+matchlen)]
99
- end
100
-
101
- # Clear Tag Queue
102
- newtext << tagqueue
103
-
104
- # Add Remaining text
105
- newtext << text
106
-
107
- # Empty Stack
108
- tagstack.reverse_each do |t|
109
- newtext << '</' << t << '>' # Add remaining tags to close
110
- end
111
-
112
- # WP fix for the bug with HTML comments
113
- newtext.gsub!("< !--", "<!--")
114
- newtext.gsub!("< !--", "< !--")
115
-
116
- return newtext
117
- end
118
- end