splam 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data.tar.gz.sig +2 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +24 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README +53 -0
  6. data/Rakefile +14 -0
  7. data/gem-public_cert.pem +20 -0
  8. data/lib/splam.rb +124 -0
  9. data/lib/splam/rule.rb +73 -0
  10. data/lib/splam/rules.rb +2 -0
  11. data/lib/splam/rules/arms_race.rb +24 -0
  12. data/lib/splam/rules/bad_words.rb +46 -0
  13. data/lib/splam/rules/bbcode.rb +12 -0
  14. data/lib/splam/rules/chinese.rb +26 -0
  15. data/lib/splam/rules/fuzz.rb +20 -0
  16. data/lib/splam/rules/good_words.rb +19 -0
  17. data/lib/splam/rules/href.rb +55 -0
  18. data/lib/splam/rules/html.rb +12 -0
  19. data/lib/splam/rules/line_length.rb +26 -0
  20. data/lib/splam/rules/punctuation.rb +14 -0
  21. data/lib/splam/rules/russian.rb +15 -0
  22. data/lib/splam/rules/word_length.rb +32 -0
  23. data/splam.gemspec +12 -0
  24. data/test/fixtures/comment/ham/api-1.txt +1 -0
  25. data/test/fixtures/comment/ham/api-2.txt +7 -0
  26. data/test/fixtures/comment/ham/api-3.txt +3 -0
  27. data/test/fixtures/comment/ham/api-4.txt +1 -0
  28. data/test/fixtures/comment/ham/api-5.txt +7 -0
  29. data/test/fixtures/comment/ham/api.txt +5 -0
  30. data/test/fixtures/comment/ham/api_bug.txt +16 -0
  31. data/test/fixtures/comment/ham/backtrace.txt +79 -0
  32. data/test/fixtures/comment/ham/epic.txt +35 -0
  33. data/test/fixtures/comment/ham/epic_warehouse.txt +92 -0
  34. data/test/fixtures/comment/ham/extra_fields.txt +25 -0
  35. data/test/fixtures/comment/ham/feedlinks.txt +13 -0
  36. data/test/fixtures/comment/ham/github.txt +5 -0
  37. data/test/fixtures/comment/ham/hub.txt +10 -0
  38. data/test/fixtures/comment/ham/mario.txt +19 -0
  39. data/test/fixtures/comment/ham/mylyn.txt +10 -0
  40. data/test/fixtures/comment/ham/omg_thanks_again_finally_warehouse.txt +30 -0
  41. data/test/fixtures/comment/ham/omg_thanks_again_warehouse.txt +17 -0
  42. data/test/fixtures/comment/ham/problem.txt +7 -0
  43. data/test/fixtures/comment/ham/sample_html.txt +3 -0
  44. data/test/fixtures/comment/ham/short_reply.txt +3 -0
  45. data/test/fixtures/comment/ham/tags.txt +11 -0
  46. data/test/fixtures/comment/ham/thanks_warehouse.txt +15 -0
  47. data/test/fixtures/comment/ham/thx.txt +5 -0
  48. data/test/fixtures/comment/spam/125_spam-12420.txt +6 -0
  49. data/test/fixtures/comment/spam/40_pharmacia.txt +1 -0
  50. data/test/fixtures/comment/spam/amazon.txt +51 -0
  51. data/test/fixtures/comment/spam/bluebichen.txt +1 -0
  52. data/test/fixtures/comment/spam/boobz.txt +3 -0
  53. data/test/fixtures/comment/spam/buffy.txt +1 -0
  54. data/test/fixtures/comment/spam/chinese.txt +19 -0
  55. data/test/fixtures/comment/spam/comment_bbc.txt +1 -0
  56. data/test/fixtures/comment/spam/comment_cnn.txt +1 -0
  57. data/test/fixtures/comment/spam/comment_randi.txt +1 -0
  58. data/test/fixtures/comment/spam/comment_wordy.txt +1 -0
  59. data/test/fixtures/comment/spam/consent.txt +1 -0
  60. data/test/fixtures/comment/spam/december.txt +1 -0
  61. data/test/fixtures/comment/spam/digital_rights.txt +1 -0
  62. data/test/fixtures/comment/spam/dyed_wool.txt +1 -0
  63. data/test/fixtures/comment/spam/hairbrush_sex.txt +119 -0
  64. data/test/fixtures/comment/spam/handbag.txt +5 -0
  65. data/test/fixtures/comment/spam/inqius.txt +5 -0
  66. data/test/fixtures/comment/spam/kidneys.txt +1 -0
  67. data/test/fixtures/comment/spam/madonna.txt +3 -0
  68. data/test/fixtures/comment/spam/make_plans.txt +3 -0
  69. data/test/fixtures/comment/spam/oem.txt +130 -0
  70. data/test/fixtures/comment/spam/oem2.txt +130 -0
  71. data/test/fixtures/comment/spam/oem_intl.txt +131 -0
  72. data/test/fixtures/comment/spam/omg_sex.txt +26 -0
  73. data/test/fixtures/comment/spam/ottersex.txt +1 -0
  74. data/test/fixtures/comment/spam/pdwkb.txt +1 -0
  75. data/test/fixtures/comment/spam/pr0n.txt +320 -0
  76. data/test/fixtures/comment/spam/property.txt +448 -0
  77. data/test/fixtures/comment/spam/pyromancy.txt +1 -0
  78. data/test/fixtures/comment/spam/rapid.txt +10 -0
  79. data/test/fixtures/comment/spam/russki.txt +5 -0
  80. data/test/fixtures/comment/spam/russki2.txt +2 -0
  81. data/test/fixtures/comment/spam/shipping.txt +3 -0
  82. data/test/fixtures/comment/spam/short_n_sweet.txt +1 -0
  83. data/test/fixtures/comment/spam/spam-13232.txt +15 -0
  84. data/test/fixtures/comment/spam/spam-13518.txt +3 -0
  85. data/test/fixtures/comment/spam/spam-13519.txt +3 -0
  86. data/test/fixtures/comment/spam/spam-13520.txt +3 -0
  87. data/test/fixtures/comment/spam/spam-13521.txt +3 -0
  88. data/test/fixtures/comment/spam/spam-13982.txt +10 -0
  89. data/test/fixtures/comment/spam/spam-14178.txt +1 -0
  90. data/test/fixtures/comment/spam/spam-14447.txt +4 -0
  91. data/test/fixtures/comment/spam/spam-14718.txt +4 -0
  92. data/test/fixtures/comment/spam/spam0113081.txt +1 -0
  93. data/test/fixtures/comment/spam/tk.txt +4 -0
  94. data/test/fixtures/comment/spam/troubles.txt +2 -0
  95. data/test/fixtures/comment/spam/url_only_idiot.txt +1 -0
  96. data/test/fixtures/comment/spam/webcam.txt +3 -0
  97. data/test/splam_rule_test.rb +20 -0
  98. data/test/splam_test.rb +102 -0
  99. data/test/test_helper.rb +8 -0
  100. metadata +183 -0
  101. metadata.gz.sig +2 -0
@@ -0,0 +1,20 @@
1
+ class Splam::Rules::Fuzz < Splam::Rule
2
+ class << self
3
+ attr_accessor :bad_word_score
4
+ end
5
+
6
+ self.bad_word_score = 10
7
+
8
+ def run
9
+ patterns = [/^(\d[a-z])/, /(\d[a-z][A-Z]\w+)/, /(\b\w+\d\.txt)/, /(;\d+;)/ ]
10
+ matches = 0
11
+ patterns.each do |pattern|
12
+ results = @body.scan(pattern)
13
+ if results && results.size > 0
14
+ add_score((self.class.bad_word_score * results.size), "bad pattern match: '#{$1}'")
15
+ end
16
+ matches += results.size
17
+ end
18
+ add_score matches.size ** 4, "Aggregate number of bad patterns was #{matches}." if matches > 1
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ class Splam::Rules::GoodWords < Splam::Rule
2
+
3
+ def run
4
+ good_words = [ /I\'having a problem/, ]
5
+ good_words |= %w( lighthouse activereload warehouse install eclipse settings assigned user ticket tickets token api number query request)
6
+ good_words |= %w( browser feed firefox safari skitch vendor rails action_controller railties )
7
+ good_words |= %w( redirect login diff dreamhost setup subversion git wildcard domain subdomain ssh database )
8
+ good_words |= %w( project billing tags description comment milestone saving happening feature mac implement report)
9
+ good_words |= %w( rss notification subscribe calendar chart note task gantt search service ownership application communicate )
10
+ good_words |= %w( pattern template web integer status xml activereload html state page)
11
+ good_words << "project management"
12
+ good_words << "/usr/local/lib" << "gems"
13
+
14
+ body = @body.downcase
15
+ good_words.each { |rule|
16
+ add_score -5 * body.scan(rule).size, "relevant word match: #{rule}"
17
+ }
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ # This plugin checks for links in the text, and adds scores for having many links,
2
+ # and
3
+ class Splam::Rules::Href < Splam::Rule
4
+
5
+ def run
6
+ # add_score 3 * @body.scan("href=http").size, "Shitty html 'href=http'" # 3 points for shitty html
7
+ add_score 15 * @body.scan(/href\=\s*http/).size, "Shitty html 'href=http'" # 15 points for shitty html
8
+ add_score 15 * @body.scan(/href\="\s+http/).size, "Shitty html 'href=\" http'" # 15 points for shitty html
9
+ add_score 50 * @body.scan(/\A<a.*?<\/a>\Z/).size, "Single link post'" # 50 points for shitty
10
+
11
+ link_count = @body.scan("http://").size
12
+ add_score 1 * link_count, "Matched 'http://'" # 1 point per link
13
+ add_score 50, "More than 10 links" if link_count > 10 # more than 10 links? spam.
14
+ add_score 100, "More than 20 links" if link_count > 20 # more than 20 links? definitely spam.
15
+ add_score 1000, "More than 50 links" if link_count > 50 # more than 20 links? definitely spam.
16
+
17
+ # Modify these scores to weight certain problematic domains.
18
+ # You may need to modify these for your application
19
+ suspicious_top_level_domains = {
20
+ 'ru' => 20, # Russian? spammer.
21
+ 'cn' => 20, # Chinese? spammer.
22
+ 'us' => 8, # .us ? possibly spam
23
+ 'it' => 5,
24
+ 'tk' => 20,
25
+ 'pl' => 8,
26
+ 'info' => 20,
27
+ 'biz' => 40 # no-one uses these for reals
28
+ }
29
+ suspicious_sites = {
30
+ 'cnn' => 10, # Honestly, who links to CNN?
31
+ 'bbc' => 10
32
+ }
33
+
34
+ tokens = @body.split(" ")
35
+ if tokens[-1] =~ /^http:\/\//
36
+ add_score 10, "Text ends in a http token"
37
+ add_score 50, "Text ends in a http token and only has one token" if link_count == 1
38
+ end
39
+
40
+ @body.scan(/http:\/\/(.*?)[\/\]?]/) do |match|
41
+ # $stderr.puts "checking #{match}"
42
+ if domain = match.to_s.split(".")
43
+ tld = domain[-1]
44
+
45
+ if found = suspicious_top_level_domains[tld]
46
+ add_score found, "Suspicious top-level domain: '#{tld}'"
47
+ end
48
+
49
+ if found = suspicious_sites[domain[-2]]
50
+ add_score found, "Suspicious hostname: '#{domain[-2]}'"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,12 @@
1
+ class Splam::Rules::Html < Splam::Rule
2
+
3
+ def run
4
+ # you get points for having lots of links
5
+ add_score @body.scan(/\<[abi]/).size, "Lots of <a> <b> or <i> links"
6
+
7
+ # stupid fools!
8
+ add_score 5 * @body.scan(/<a[^>]*><b>/).size, "<b> inside an <a>"
9
+
10
+ add_score(200, "Entire body is an HTML tag") if @body =~ /^[<][^>]*[>]$/
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ class Splam::Rules::LineLength < Splam::Rule
2
+
3
+ def name
4
+ "Line length"
5
+ end
6
+
7
+ # Penalize long line lengths.
8
+ def run
9
+ lines = @body.split("\n")
10
+ lines.each do |line|
11
+ next if line =~ /\A\s{4,}/ # ignore code blocks
12
+
13
+ multiplier = (lines.size == 1) ? 10 : 1 # one line? fail.
14
+
15
+
16
+ # 1 point for each 40 chars in a line.
17
+ hits = (line.size / 40) * multiplier
18
+ add_score hits, "lines over 40 chars"
19
+
20
+ # 2 more points if line is longer than 80
21
+ hits = (line.size / 80) * 2 * multiplier
22
+ add_score hits, "lines over 80 chars"
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ class Splam::Rules::Punctuation < Splam::Rule
2
+
3
+ def run
4
+ punctuation = @body.scan(/[.,] /)
5
+ add_score 10, "Text has no punctuation" if punctuation.size == 0
6
+
7
+ @body.split(/[.,]/).each do |sentence|
8
+ words = sentence.split(" ")
9
+ # long sentence, add a point.
10
+ add_score 1, "Sentence has more than 10 words" if words.size > 10
11
+ add_score 10, "Sentence has more than 30 words" if words.size > 30
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ class Splam::Rules::Russian < Splam::Rule
2
+
3
+ def run
4
+ banned_words =[ # various russian characters
5
+ "\320\241", "\320\220", "\320\234", "\320\257", "\320\233", "\320\243",
6
+ "с", "м", "о", "т", "р", "е", "т", "ь", "п", "о", "р", "н", "о", "р", "л", "и", "к"
7
+ # unicode char
8
+ # "\320"
9
+ ]
10
+ banned_words.each do |word|
11
+ hits = (3 * @body.scan("#{word}").size) # 1 point for every banned word
12
+ add_score hits, "Suspicious character '#{word}'"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ class Splam::Rules::WordLength < Splam::Rule
2
+
3
+ # Basic array functions
4
+ def sum(arr)
5
+ arr.inject {|sum,x| sum + x }
6
+ end
7
+
8
+ def average(arr)
9
+ sum(arr) / arr.size
10
+ end
11
+
12
+ def median(arr)
13
+ a2 = arr.sort
14
+ a2[arr.size / 2] unless arr.empty?
15
+ end
16
+
17
+ def run
18
+ words = []
19
+ words = @body.split(/\s/).map do |word|
20
+ word.size
21
+ end
22
+ words.delete_if { |w| w =~ /^http\:\/\//}
23
+
24
+ # Only count word lengths over 10
25
+ if words.size > 5
26
+ add_score 20, "Average word length over 5" if average(words) > 5
27
+ add_score 50, "Average word length over 10" if average(words) > 10
28
+ add_score 10, "Median word length over 5" if median(words) > 5
29
+ add_score 50, "Median word length over 10" if median(words) > 10
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ name = "splam"
2
+
3
+ Gem::Specification.new name, "0.1.0" do |s|
4
+ s.summary = "Run any kind of code in parallel processes"
5
+ s.authors = ["ENTP"]
6
+ s.email = "ENTP@example.com"
7
+ s.homepage = "http://github.com/grosser/#{name}"
8
+ s.files = `git ls-files`.split("\n")
9
+ s.license = "MIT"
10
+ s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem")
11
+ s.cert_chain = ["gem-public_cert.pem"]
12
+ end
@@ -0,0 +1 @@
1
+ "This":http://activereload.lighthouseapp.com/projects/44-lighthouse-users/tickets.xml?q=state%3Aopen&page=2 doesn't work for you? Sending ?page=2 should work fine. It's basically an XML version of the html page. Try it without the .xml extension, and it should match the xml feed.
@@ -0,0 +1,7 @@
1
+ Rick -
2
+
3
+ Thanks again. I, after wrestling with a case of dyslexia, got it to work with you suggestion. I wasn't encoding the colon for some reason. Idiot me.
4
+
5
+ I'm probably going to put together a little 'dummies guide' for the API once I get done with this projects, because I think it would help others who might have had some similar initial glitches.
6
+
7
+ THANKS for a great product!
@@ -0,0 +1,3 @@
1
+ Rick, is there a way to get all data without making requests page-by-page. If not, is there a way to get the total number of items?
2
+
3
+ Thanks.
@@ -0,0 +1 @@
1
+ +1 on the no-pagination request. Thanks!
@@ -0,0 +1,7 @@
1
+ While no-pagination would be nice I can understand why it exists. If you have 100s of tickets then you're going to have an absolutely huge XML file to generate and load. The easy way to work through is:
2
+
3
+ if (number of tickets on page == 30) {
4
+ get next page
5
+ } else {
6
+ got all tickets
7
+ }
@@ -0,0 +1,5 @@
1
+ Hey guys. So after a long night, I could finally get the API to do what I need to. But I can't seem to access anything past the first 30 tickets.
2
+
3
+ http://xxx.lighthouseapp.com/projects/xxx/tickets.xml?q=state:open
4
+
5
+ I've tried adding ?page=1 then 2 then 3, but I can't seem to get anything but the first original 30 tickets. I know there are 65 tickets that match that request. Any suggestions?
@@ -0,0 +1,16 @@
1
+ I get this error message when changing the milestone on a ticket and then saving it:
2
+
3
+ ActiveResource::ServerError (Failed with 500 Internal Server Error):
4
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/connection.rb:173:in `handle_response'
5
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/connection.rb:144:in `request'
6
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/connection.rb:121:in `put'
7
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/base.rb:929:in `update'
8
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/base.rb:779:in `save_without_validation'
9
+ /usr/local/lib/ruby/gems/1.8/gems/activeresource-2.1.0/lib/active_resource/validations.rb:262:in `save_without_tags'
10
+ /lib/lighthouse.rb:181:in `save'
11
+
12
+ A few days ago this wasn't happening - and now it happens even through ./script/console
13
+
14
+ Any thoughts or ideas?
15
+
16
+ Thanks
@@ -0,0 +1,79 @@
1
+ Hey guys,
2
+
3
+ Installed 1.1.1 and upon clicking the "Hooks" button, I get the following error:
4
+
5
+ [code]Processing HooksController#index (for 192.168.1.85 at 2007-10-15 11:08:32) [GET]
6
+ Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGFzaHsABjoKQHVzZWR7AA%3D%3D--fbec10b5ed11e70564577d7f46ee0f5f6a40f597
7
+ Parameters: {"action"=>"index", "controller"=>"hooks"}
8
+ Rendering template within layouts/application
9
+ Rendering hooks/index
10
+
11
+ [code]ActionView::TemplateError (undefined method `repo' for nil:NilClass) on line #2 of app/views/hooks/_hook.html.erb:
12
+ 1: <li id="hook-<%= hook.plugin_name %>" class="listitem">
13
+ 2: <% remote_sheet_form_for :hook, hook.properties, :url => hooks_path(:name => hook.plugin_name),
14
+ 3: :trigger => "hooknew-#{hook.plugin_name}", :html => {:id => "hooksheet-#{hook.plugin_name}", :style => 'display:none'} do |s| %>
15
+ 4: <h2>Add <%= hook.title %> Instance</h2>
16
+ 5: <%= s.text_field "Label:", :label %>
17
+
18
+ lib/warehouse/hooks/base.rb:12:in `initialize'
19
+ lib/warehouse/hooks/base.rb:17:in `new'
20
+ lib/warehouse/hooks/base.rb:17:in `properties'
21
+ app/views/hooks/_hook.html.erb:2:in `_run_erb_47app47views47hooks47_hook46html46erb'
22
+ vendor/rails/actionpack/lib/action_view/base.rb:377:in `send'
23
+ vendor/rails/actionpack/lib/action_view/base.rb:377:in `compile_and_render_template'
24
+ vendor/rails/actionpack/lib/action_view/base.rb:353:in `render_template'
25
+ vendor/rails/actionpack/lib/action_view/base.rb:303:in `render_file'
26
+ vendor/rails/actionpack/lib/action_view/base.rb:318:in `render'
27
+ vendor/rails/actionpack/lib/action_view/partials.rb:117:in `render_partial'
28
+ vendor/rails/actionpack/lib/action_controller/benchmarking.rb:30:in `benchmark'
29
+ vendor/rails/actionpack/lib/action_view/partials.rb:116:in `render_partial'
30
+ vendor/rails/actionpack/lib/action_view/partials.rb:143:in `render_partial_collection'
31
+ vendor/plugins/expiring_attr_reader/lib/expiring_attr_reader.rb:32:in `each_with_index'
32
+ vendor/rails/actionpack/lib/action_view/partials.rb:141:in `each'
33
+ vendor/rails/actionpack/lib/action_view/partials.rb:141:in `each_with_index'
34
+ vendor/rails/actionpack/lib/action_view/partials.rb:141:in `render_partial_collection'
35
+ vendor/rails/actionpack/lib/action_view/base.rb:337:in `render'
36
+ app/views/hooks/index.html.erb:4:in `_run_erb_47app47views47hooks47index46html46erb'
37
+ vendor/rails/actionpack/lib/action_view/base.rb:377:in `send'
38
+ vendor/rails/actionpack/lib/action_view/base.rb:377:in `compile_and_render_template'
39
+ vendor/rails/actionpack/lib/action_view/base.rb:353:in `render_template'
40
+ vendor/rails/actionpack/lib/action_view/base.rb:303:in `render_file'
41
+ vendor/rails/actionpack/lib/action_controller/base.rb:1070:in `render_for_file'
42
+ vendor/rails/actionpack/lib/action_controller/base.rb:797:in `render_with_no_layout'
43
+ vendor/rails/actionpack/lib/action_controller/layout.rb:261:in `render_without_benchmark'
44
+ vendor/rails/actionpack/lib/action_controller/benchmarking.rb:51:in `render'
45
+ /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
46
+ vendor/rails/actionpack/lib/action_controller/benchmarking.rb:51:in `render'
47
+ vendor/rails/actionpack/lib/action_controller/base.rb:1125:in `perform_action_without_filters'
48
+ vendor/rails/actionpack/lib/action_controller/filters.rb:697:in `call_filters'
49
+ vendor/rails/actionpack/lib/action_controller/filters.rb:723:in `run_before_filters'
50
+ app/controllers/application.rb:174:in `set_context'
51
+ vendor/plugins/active_record_context/lib/technoweenie/active_record_context.rb:40:in `with_context'
52
+ app/controllers/application.rb:173:in `set_context'
53
+ vendor/rails/actionpack/lib/action_controller/filters.rb:471:in `send!'
54
+ vendor/rails/actionpack/lib/action_controller/filters.rb:471:in `call'
55
+ vendor/rails/actionpack/lib/action_controller/filters.rb:720:in `run_before_filters'
56
+ vendor/rails/actionpack/lib/action_controller/filters.rb:695:in `call_filters'
57
+ vendor/rails/actionpack/lib/action_controller/filters.rb:689:in `perform_action_without_benchmark'
58
+ vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
59
+ /usr/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
60
+ vendor/rails/actionpack/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
61
+ vendor/rails/actionpack/lib/action_controller/rescue.rb:175:in `perform_action_without_caching'
62
+ vendor/rails/actionpack/lib/action_controller/caching.rb:670:in `perform_action'
63
+ vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in `cache'
64
+ vendor/rails/activerecord/lib/active_record/query_cache.rb:8:in `cache'
65
+ vendor/rails/actionpack/lib/action_controller/caching.rb:669:in `perform_action'
66
+ vendor/rails/actionpack/lib/action_controller/base.rb:517:in `send'
67
+ vendor/rails/actionpack/lib/action_controller/base.rb:517:in `process_without_filters'
68
+ vendor/rails/actionpack/lib/action_controller/filters.rb:685:in `process_without_session_management_support'
69
+ vendor/rails/actionpack/lib/action_controller/session_management.rb:123:in `process'
70
+ vendor/rails/actionpack/lib/action_controller/base.rb:377:in `process'
71
+ vendor/rails/actionpack/lib/action_controller/dispatcher.rb:170:in `handle_request'
72
+ vendor/rails/actionpack/lib/action_controller/dispatcher.rb:114:in `dispatch'
73
+ vendor/rails/actionpack/lib/action_controller/dispatcher.rb:125:in `dispatch_cgi'
74
+ vendor/rails/actionpack/lib/action_controller/dispatcher.rb:9:in `dispatch'
75
+ /opt/lsws/fcgi-bin/RailsRunner.rb:24
76
+
77
+ [code]Rendering /applied/warehouse/public/500.html (500 Internal Server Error)
78
+
79
+ Any ideas?
@@ -0,0 +1,35 @@
1
+ Well, you asked for it... and it is long. :) (Short version... stick with Lighthouse...)
2
+
3
+ First, don't get me wrong, I love 37Signals' products. I have (had) a paid account for every one of their subscription apps. Currently, Backpack is my absolute favorite. Since they opened it up to be multi-user, it is the perfect Intranet for a company. However, I have always found Basecamp to be a little lacking for software projects. The ToDo list feature isn't great for tracking that kind of work. I am used to Issue Tracking systems like FogBugz, TestTrack Pro, JIRA, etc. I like to record everything I can regarding each ticket (bug, feature, whatever it is). Lighthouse has all the features you need for tracking a software development project, in a much more affordable package (compared to JIRA, Testrack Pro and FogBugz). I like FogBugz a lot, but it can get expensive if you are developing on a team. Lighthouse is just right... affordable, feature rich, nice to look at and easy to use.
4
+
5
+ Compared to Basecamp, they both have a Dashboard, Overview pages for each project, Messages, Attachments and Milestones. Obviously, the point at which they really diverge is task management.
6
+
7
+ Tickets vs. Todos
8
+ -----------------
9
+ Lighthouse is Ticket-centric as you know. You can track comments (history) with each ticket. Tickets also track any state changes (like adding new tags, changing the ticket status, etc). Basecamp's focus is equally distributed between all their objects. Team collaboration is the main (published) focus behind Basecamp. Basecamp's Todos are just 'one-liner' tasks that you can re-order and drag between lists. There are no unique IDs (ticket #18), comments, notes or history.
10
+
11
+ Pages vs. Writeboards
12
+ ---------------------
13
+ Basecamp has Writeboards, however, they aren't tightly integrated since it redirects you out of the application to use them (but having the links is better than nothing). Lighthouse has Pages, which are nice because they are right there in the project (no redirection). Both Writeboards and Pages are like the Wikis of other systems (FogBugz)... a great place to write documentation. I think Lighthouse does a little better job here, from the software development perspective. The thing that bothers me about the redirection of Basecamp's Writeboards is the loss of the navigation. You have to click 'Back to Project' then you can continue navigating. It just seems unnecessary to me (but I understand why). Both Pages and Writeboards are Textile-based but Writeboards do track your versions as you make edits to the documents. Lighthouse doesn't, but I know it could since Rick literally wrote the "plugin":http://github.com/technoweenie/acts_as_versioned/tree/master. ;) I wouldn't mind seeing Pages get their own sub-nav button beside Milestones (Overview >> Tickets >> Messages >> Milestones >> Pages).
14
+
15
+ File Management/Attachments
16
+ ---------------------------
17
+ I think Basecamp gets the file management part right. You can attach files to Messages or upload them directly to the Files page and you can search and browse them. They have a way to browse the image previews, etc. Lighthouse can attach to messages, tickets and comments, but the images aren't displayed inline which I think would be a nice feature. I sometimes don't realize the attachments are there because they get lost in the sidebar. In Lighthouse, when you do click an image, it links directly to it. I think it would be nice to have two links. One to view it within the context of the page (using something like FancyZoom) and the other could continue to take you to a direct link to the image. Or maybe you just hover over the link for a semi-large preview and clicking it remains the same. But, once you get used to the existing setup, it works fine.
18
+
19
+ RSS vs. Notifications
20
+ ---------------------
21
+ The thing I need to remember about Lighthouse is that it is more RSS-focused. Instead of notifications for things you create, they give you the RSS feeds. Since I jumped into RSS later than most, that doesn't always occur to me right away. But, now that I have subscribed to the feed, I can see what is going on just fine. With Apple Mail, you can subscribe to an RSS feed and have it show up in your Inbox with your email (and Outlook 2007 too, I think). So, it is essentially the same feature as direct notifications (just not targeted to specific users).
22
+
23
+ Chat
24
+ -----------
25
+ Basecamp has Chat integration, but it is really just a link to a particular Campfire room in the previously setup Campfire account. So, it isn't necessarily a 'feature'. See below under "Lighthouse Enhancements" for more on this.
26
+
27
+ Something cool I have setup is a 'webclip' of the Project list (from the Dashboard) and the History (also from the Dashboard). (I also did this for my GitHub repository list.) So, I can just press F12 on my Mac and see what is new on the site OR click a link right to a project or item. It works great. (But I got that idea from a blog post about doing the same thing with the Backpack Journal.) :)
28
+
29
+ Lastly, I have always been into UI. Justin has done a fantastic job with v2 of Lighthouse. I love the fonts, the colors, the arrangement of positive/negative space... I think it is absolutely fantastic on a Mac in Safari (or any combo, but that is my favorite). Plus, when you couple Engine Yard hosting with Safari rendering speed, font smoothing on a Mac, and Justin's artistic ability, it is just a great user experience. I find it to be an excellent, well-designed tool. (The design of Basecamp is very nice too, clean and easy to use, but I like Lighthouse v2 better.)
30
+
31
+ If I was you, I would stick with Lighthouse as your project management tool. Basecamp is great for project management, but it is better for generic projects.
32
+
33
+ Lighthouse Enhancements
34
+ -----------------------
35
+ Some feature requests for Lighthouse that would really tighten it up as a Software Development Project Management tool would be EITHER Message Notifications OR better explanation of the use of RSS to accomplish the same result. I don't think it is readily apparent. To most it would seem that Messages in Lighthouse just aren't as mature as Messages in Basecamp. Second, it would be nice to have customizable 'Quick Links' in the sidebar or somewhere. This would simply be a label field and a URL field (Target a new window, though). That way, you could add links to other commonly used tools like Github, Campfire, Backpack, etc. You could define them globally or on a per-project basis. They would all show up in the Project sidebar, but the global links would appear in every project. Finally, inline display of image attachments. Little previews right beside the comments would be very nice. I can recommend a great plugin called "attachment_fu":http://github.com/technoweenie/attachment_fu/tree/master for just such a job (ha!).
@@ -0,0 +1,92 @@
1
+ I know nothing. You can blame it all on Dreamhost: they offered a very easy interface to setup subversion without having to do much of anything. The good part is that I was very easily able to set up subversion and use it. I found it awesome for writing paper drafts and for the light programming I do. This subversion experience allowed me to see the value in Warehouse. The bad news is that this means somebody with virtually no terminal or Rails experience (me!) is trying install Warehouse, and the installation instructions are definitely NOT written in a way individuals like me can fully understand. Certain parts seem like complete gibberish.
2
+
3
+ So here's my attempt to document what a complete Terminal/Rails/Server novice needs to do to get Warehouse running on a Dreamhost server using OS X. I primarily need somebody to tell me if what I've outlined so far is correct, and to tell me specifically what to do for the parts where I'm lost. I'm hoping that with your help this thread can serve as a reference for any other novices like myself who would like to get this up and running.
4
+
5
+ PART 1: Installing Warehouse on Dreamhost
6
+
7
+ For this section, follow along with the page:
8
+ http://warehouseapp.com/installing/warehouse-on-dreamhost
9
+
10
+ 1) Follow the instructions to setup a fully hosted domain through Dreamhost. For most people this means setting up a new subdomain. This is easily done through dreamhost's control panel. The only tricky bit here is that you will need to fill out a support certificate and ask Dreamhost to allow wildcards on this specific domain you setup. Just fill out a support request through the dreamhost control panel. It's one of the drop down menus in their support. Literally just say "I need wildcards on "subdomain.domain.com" and they should be able to get it working pretty fast.
11
+
12
+ 2) Here is where the hard stuff starts.
13
+
14
+ a) You need to "unzip Warehouse in the appropriate directory". What is the appropriate directory? I don't know, but I assume it's the root directory of the subdomain just created (HELP!). Now, when they say unzip in the appropriate directory they mean they want you to use TERMINAL to connect to the dreamhost server and use UNIX commands. The use of the terminal is going to be unavoidable in this process, but you can avoid it at this step if you'd like. The easy way (for people not familiar with the UNIX) is to just unzip the file in OS X and just FTP the folder to your new subdomain using your favorite FTP client. Whether you should ftp the entire "warehouse" folder or just it's contents: I'm not sure. (I actually used ftp to upload the .gz file, which I then used the terminal to unzip, and then I had to unzip the .tar file (I'm trying to learn as I go). I ended up with the warehouse folder in the root directory of the subdomain).
15
+
16
+ b) Second, they want you to edit THREE files in this folder. The wording makes it seem like two, but it is really three. They are all located in "warehouse-1.0.4/public". Open them in some form of text editor and do the edits they specify (keeping with the FTP theme you can do this directly on the server with Transmit or Interarchy. Otherwise you are going to need to download the file, open with textedit, edit it, save it (make sure as plain text!), then re-upload the file). I have no clue how to do this stuff directly through the terminal, but I realize that's how the cool kids do it.
17
+
18
+ For both the "dispatch.rb" and "dispatch.fcgi" files, type in as a new line (make this the very first line on the file)
19
+
20
+ /usr/local/bin/ruby
21
+
22
+ Just type this in as a new line and don't replace/overwrite/delete anything. For the ".htaccess" file, follow the directions they outline. Not sure why the give specific directions for only one of the three files. I guess it's obvious if you aren't clueless like me.
23
+
24
+ 3) Now you are going to be forced to use TERMINAL to check if you did this right. There's no avoiding it now: fire up the TERMINAL program (it's found in "Applications/utilities" on your computer) and type
25
+
26
+ ssh username@domain.com
27
+
28
+ Username refers to your username to access the server (given to you by Dreamhost). Domain is your domain name with dreamhost. You'll then be asked for the password (also originally given to you by Dreamhost). If you get no error type:
29
+
30
+ irb
31
+
32
+ which starts some form program and then type
33
+
34
+ require 'svn/core'
35
+
36
+ if it says "true", you did it! Type
37
+
38
+ exit
39
+
40
+ to get out of irb (whatever that is)
41
+
42
+
43
+ PART 2: Connecting to the Database!
44
+ Okay, now you need to follow the standard installation instructions. Follow along with this page:
45
+ http://warehouseapp.com/installing/installing-and-registering-warehouse
46
+
47
+ 1) The first thing you'll need to do is to setup a database for Warehouse to use. Do this from the "goodies -> manageMySQL" menu on in the Dreamhost control panel.
48
+
49
+ a) Database Name: whatever
50
+
51
+ b) Hostname: you'll probably need to set-up a new hostname for the database. It's kind of confusing because it acts an awful lot like creating a subdomain, but it's not the same. AFAIK you can call the hostname whatever you want as it makes no difference to anything (other than your own organization). You'll end up with something like "database.domain.com".
52
+
53
+ c) User/Password info: whatever you want. Just keep note of them for future use.
54
+
55
+ 2) Okay, now you need to go back into TERMINAL and navigate to the root directory of Warehouse. This assumes you are still "connected" from that ssh business you just did. If not, just redo that part. Now, depending on how you unzipped, you might not need to do anything. If you dragged the warehouse folder CONTENTS to the server, don't do anything. If you dragged the folder (or the zip file and you unzipped on the server) type
56
+
57
+ ls
58
+
59
+ this will show you the name of any folder in the directory. Type
60
+
61
+ cd foldername
62
+
63
+ where "foldername" is whatever folder 'ls' told you (probably "warehouse-1.0.4")
64
+
65
+ now type
66
+
67
+ rake warehouse:bootstrap
68
+
69
+ Now it's going to ask you a bunch of questions:
70
+
71
+ a) For "Host Name" type the host name you gave to dreamhost for your database.
72
+ b) For "Database name" do the same (whatever you told dreamhost earlier)
73
+ c) For "username", do the same
74
+ d) For "password", do the same
75
+ e) For "socket path" do nothing (just hit enter). I have no idea what this is.
76
+ f) Answer "y" to the question and press enter
77
+
78
+ A bunch of stuff flies by and hopefully at the end it says "Warehouse is ready to roll
79
+
80
+ PART 3: FINALLY INSTALLING WAREHOUSE
81
+
82
+ Now it wants you to use the terminal (I think) to navigate to a webpage using RUBY (I think). Type:
83
+
84
+ script/server
85
+
86
+ to launch some program. Now... I don't know what to do here. There's some syntax to navigate to a page but typing my warehouse domain address does nothing. So close, so close....
87
+
88
+ Any help?
89
+
90
+ (Bonus question: does Warehouse play well with the simple subversion setup Dreamhost has?)
91
+
92
+ Thanks in advance!