bwkfanboy 1.2.9 → 1.3.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/Rakefile CHANGED
@@ -6,7 +6,9 @@ require 'rake/clean'
6
6
  require 'rake/rdoctask'
7
7
  require 'rake/testtask'
8
8
 
9
- spec = Gem::Specification.new() {|i|
9
+ require_relative 'test/rake_git'
10
+
11
+ spec = Gem::Specification.new {|i|
10
12
  i.name = "bwkfanboy"
11
13
  i.summary = 'A converter from HTML to Atom feed that you can use to watch sites that do not provide its own feed.'
12
14
  i.description = i.summary
@@ -16,7 +18,7 @@ spec = Gem::Specification.new() {|i|
16
18
  i.homepage = "http://github.com/gromnitsky/#{i.name}"
17
19
  i.platform = Gem::Platform::RUBY
18
20
  i.required_ruby_version = '>= 1.9.2'
19
- i.files = FileList['lib/**/*', 'bin/*', 'doc/*', '[A-Z]*', 'test/**/*']
21
+ i.files = git_ls('.')
20
22
 
21
23
  i.executables = FileList['bin/*'].gsub(/^bin\//, '')
22
24
  i.default_executable = i.name
@@ -26,22 +28,25 @@ spec = Gem::Specification.new() {|i|
26
28
  i.rdoc_options << '-m' << 'doc/README.rdoc' << '-x' << 'plugins'
27
29
  i.extra_rdoc_files = FileList['doc/*']
28
30
 
31
+ i.add_dependency('open4', '>= 1.0.1')
29
32
  i.add_dependency('activesupport', '>= 3.0.3')
30
33
  i.add_dependency('nokogiri', '>= 1.4.4')
31
- i.add_dependency('open4', '>= 1.0.1')
32
34
  i.add_dependency('jsonschema', '>= 2.0.0')
35
+
36
+ i.add_development_dependency('git', '>= 1.2.5')
33
37
  }
34
38
 
35
- Rake::GemPackageTask.new(spec).define()
39
+ Rake::GemPackageTask.new(spec).define
36
40
 
37
- task(default: %(repackage))
41
+ task default: [:repackage]
38
42
 
39
- Rake::RDocTask.new('doc') {|i|
43
+ Rake::RDocTask.new('doc') do |i|
40
44
  i.main = 'doc/README.rdoc'
41
45
  i.rdoc_files = FileList['doc/*', 'lib/**/*.rb']
42
46
  i.rdoc_files.exclude("lib/**/plugins")
43
- }
47
+ end
44
48
 
45
- Rake::TestTask.new() {|i|
46
- i.test_files = FileList['test/test_*.rb']
47
- }
49
+ Rake::TestTask.new do |i|
50
+ i.test_files = FileList['test/test_*.rb']
51
+ i.libs << '.'
52
+ end
data/doc/NEWS.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ === 1.3.0
2
+
3
+ Thu Feb 10 11:17:57 EET 2011
4
+
5
+ - A new plugin: articles form econlib.org.
6
+
7
+ - (internal) Injected a small part of falsework's naive template.
8
+
1
9
  === 1.2.9
2
10
 
3
11
  - Reverted to rubygems 1.3.7 due to mysterious 1.5.0 behaviour.
data/doc/TODO ADDED
@@ -0,0 +1,7 @@
1
+ -*-org-*-
2
+
3
+ - Add plugin listing to _server.
4
+ - Several http requests to _fetch.
5
+ + Inject falsework template.
6
+ + econlib.org articles plugin.
7
+ - Rewrite Utils module to be more compatible with falsework.
@@ -0,0 +1,6 @@
1
+ module Bwkfanboy
2
+ module Meta
3
+ NAME = 'bwkfanboy'
4
+ VERSION = '1.3.0'
5
+ end
6
+ end
@@ -0,0 +1,34 @@
1
+ # This is a skeleton for a bwkfanboy 1.3.0 plugin. To understand how
2
+ # plugins work please read doc/plugins.rdoc file from bwkfanboy's
3
+ # distribution.
4
+
5
+ require 'nokogiri'
6
+
7
+ class Page < Bwkfanboy::Parse
8
+ module Meta
9
+ URI = 'http://www.econlib.org/cgi-bin/searcharticles.pl?sortby=DD&query=ha*'
10
+ URI_DEBUG = '/home/alex/lib/software/alex/bwkfanboy/test/semis/econlib.html'
11
+ ENC = 'UTF-8'
12
+ VERSION = 1
13
+ COPYRIGHT = "See bwkfanboy's LICENSE file"
14
+ TITLE = "Latest articles from econlib.org"
15
+ CONTENT_TYPE = 'html'
16
+ end
17
+
18
+ def myparse(stream)
19
+ baseurl = 'http://www.econlib.org'
20
+
21
+ # read 'stream' IO object and parse it
22
+ doc = Nokogiri::HTML(stream, nil, Meta::ENC)
23
+ doc.xpath("//*[@id='divResults']//tr").each {|i|
24
+ t = clean(i.xpath("td[3]//a").text)
25
+ next if t == ""
26
+ l = baseurl + clean(i.xpath("td[3]//a")[0].attributes['href'].value)
27
+ u = date(i.xpath("td[4]").children.text)
28
+ a = clean(i.xpath("td[3]/div").children[2].text)
29
+ c = clean(i.xpath("td[4]").children[2].text)
30
+
31
+ self << { title: t, link: l, updated: u, author: a, content: c }
32
+ }
33
+ end
34
+ end
@@ -4,10 +4,10 @@ require 'logger'
4
4
  require 'open4'
5
5
  require 'active_support/core_ext/module/attribute_accessors'
6
6
 
7
+ require_relative 'meta'
8
+
7
9
  module Bwkfanboy
8
10
  module Meta
9
- NAME = 'bwkfanboy'
10
- VERSION = '1.2.9'
11
11
  USER_AGENT = "#{NAME}/#{VERSION} (#{RUBY_PLATFORM}; N; #{Encoding.default_external.name}; #{RUBY_ENGINE}; rv:#{RUBY_VERSION}.#{RUBY_PATCHLEVEL})"
12
12
  PLUGIN_CLASS = 'Page'
13
13
  DIR_TMP = "/tmp/#{Meta::NAME}/#{ENV['USER']}"
data/test/helper.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'digest/md5'
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ require_relative '../lib/bwkfanboy/utils'
6
+ include Bwkfanboy
7
+
8
+ # don't run tests automatically if they were invoked as 'gem check -t ...'
9
+ if $0 =~ /gem/
10
+ require 'minitest/unit'
11
+ else
12
+ require 'minitest/autorun'
13
+ end
14
+
15
+ # Return the right directory for (probably executable) _c_.
16
+ def cmd(c)
17
+ case File.basename(Dir.pwd)
18
+ when Meta::NAME.downcase
19
+ # test probably is executed from the Rakefile
20
+ Dir.chdir('test')
21
+ when 'test'
22
+ # we are in the test directory, there is nothing special to do
23
+ else
24
+ # tests were invoked by 'gem check -t bwkfanboy'
25
+ begin
26
+ Dir.chdir(Utils.gem_dir_system + '/../../test')
27
+ rescue
28
+ raise "running tests from '#{Dir.pwd}' isn't supported: #{$!}"
29
+ end
30
+ end
31
+
32
+ '../bin/' + c
33
+ end
data/test/rake_git.rb ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # -*-ruby-*-
3
+ # :erb:
4
+
5
+ # This is a helper for your Rakefile. Read the comments for each
6
+ # function.
7
+
8
+ require 'git'
9
+ require 'pp'
10
+
11
+ # Return a list of files in a git repository _repdir_.
12
+ #
13
+ # Add this to your gem spec:
14
+ #
15
+ # spec = Gem::Specification.new {|i|
16
+ # i.files = git_ls('.')
17
+ # }
18
+ #
19
+ # What it does is just collecting the list of the files from the git
20
+ # repository. The idea is to use that list for the gem spec. No more
21
+ # missing or redundant files in gems!
22
+ def git_ls(repdir, ignore_some = true)
23
+ ignore = ['/?\.gitignore$']
24
+
25
+ r = []
26
+ g = Git.open repdir
27
+ g.ls_files.each {|i, v|
28
+ next if ignore_some && ignore.index {|ign| i.match(/#{ign}/) }
29
+ r << i
30
+ }
31
+ r
32
+ end
33
+
34
+ pp git_ls('.') if __FILE__ == $0
35
+
36
+ # Don't remove this: falsework/0.2.2/naive/2010-12-26T04:50:00+02:00
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <html xmlns:lf="urn:econlib"><head><title>Search Articles, Advanced Search | Library of Economics and Liberty</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta http-equiv="expires" content="0"/><meta http-equiv="Pragma" content="no-cache"/><link rel="shortcut icon" href="/res/img/favicon.ico" type="imag/x-icon"/><link rel="icon" href="/res/img/favicon.ico" type="imag/x-icon"/><link rel="stylesheet" type="text/css" href="/res/css/pagelayout.css"/><link rel="stylesheet" type="text/css" href="/res/css/html.css"/><link rel="stylesheet" type="text/css" href="/res/css/blog.css"/><link rel="stylesheet" type="text/css" href="/res/css/a.css"/><link rel="stylesheet" type="text/css" href="/res/css/masthead.css"/><link rel="stylesheet" type="text/css" href="/res/css/pagehead.css"/><link rel="stylesheet" type="text/css" href="/res/css/breadcrumbs.css"/><link rel="stylesheet" type="text/css" href="/res/css/sidebar.css"/><link rel="stylesheet" type="text/css" href="/res/css/page.css"/><link rel="stylesheet" type="text/css" href="/res/css/tables.css"/><link rel="stylesheet" type="text/css" href="/res/css/tabs.css"/><link rel="stylesheet" type="text/css" href="/res/css/footer.css"/><script type="text/javascript" src="/res/js/main.js"><!--//--></script><link rel="stylesheet" type="text/css" href="/res/css/article.css"/><script type="text/javascript"><!--
3
+ function check_query(x) { document.articlesearch.sortby.value = 'R'; return true; }
4
+ --></script><!--ha*:"ha*"--></head><body><table cellpadding="0" cellspacing="0" border="0" class="page_s1"><tr><td class="sidebar"><a href="/index.html"><img src="/res/img/masthead_econlib.jpg" class="block" title="Library of Economics and Liberty masthead logo" alt="Library of Economics and Liberty masthead logo"/></a><div class="breadcrumbs"> </div><div class="nav"><div class="selected"><div class="button">Search Articles</div></div><div class="group"><div class="head">Browse Article Archives</div><div class="button" onmouseover="overSideNav(this);" onmouseout="outSideNav(this);" onclick="document.location.href = '/library/archive.html';"><div class="label">by author</div></div><div class="button" onmouseover="overSideNav(this);" onmouseout="outSideNav(this);" onclick="document.location.href = '/library/articlearchivebydate.html';"><div class="label">by date</div></div></div><div class="button" onmouseover="overSideNav(this);" onmouseout="outSideNav(this);" onclick="document.location.href = '/library/About.html#articles';">
5
+ About the Articles and Columns
6
+ </div><div class="group"><div class="head">Frequently Asked Questions</div><div class="button" onmouseover="overSideNav(this);" onmouseout="outSideNav(this);" onclick="document.location.href = '/library/help.html#articles';"><div class="label">FAQs about Searching Articles</div></div></div></div><div class="p"><div class="bold-blue">Econlib Resources</div><div class="link"><a href="/library/About.html">About Econlib</a></div><div class="link"><a href="/library/contact.html">Contact Econlib</a></div><div class="link"><a href="javascript:openPopup('/library/quoteofthedaypopup.html');" title="Economics quote of the day by a famous economist">Quote of the Day</a></div><div class="link"><a href="/library/birthdays.html">Birthdays &amp; Commemorations</a></div><div class="link"><a href="/library/faq.html">Frequently Asked Questions</a></div><div class="link"><a href="/library/register.html">Get Econlib Newsletter</a></div></div></td><td class="page"><div class="masthead"><div class="search_zone"><div class="columns"><div class="s1c1"><form name="mainsearch" method="get" action="/cgi-bin/search.pl"><table class="controls" cellpadding="0" cellspacing="0" border="0"><tr><td><select name="list"><option selected="yes" value="fullsite">Full Site</option><option value="articles">Articles</option><option value="econlog">EconLog</option><option value="econtalk">EconTalk</option><option value="books">Books</option><option value="cee">Encyclopedia</option><option value="guides">Guides</option></select></td><td><input type="text" name="query"/></td><td><div class="button"><input type="image" src="/res/img/btn_search.jpg" class="block" onmouseover="swapImage(this,'/res/img/btn_search_over.jpg');" onmouseout="swapImage(this,'/res/img/btn_search.jpg');" alt="btn_search.jpg" title="Go"/></div></td></tr></table></form></div></div></div><div class="nav"><div class="buttons"><table cellpadding="0" cellspacing="0" border="0"><tr><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('/library/forum.html');">Articles</td><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('http://econlog.econlib.org');">EconLog</td><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('http://www.econtalk.org');">EconTalk</td><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('/library/classics.html');">Books</td><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('/library/CEE.html');">Encyclopedia</td><td class="button" onmouseover="overNav(this);" onmouseout="outNav(this);" onclick="pressNav('/library/topics.html');">Guides</td><td class="selected" onclick="pressNav('/library/searchpage.html');">Search</td></tr></table></div></div></div><div class="pagehead"><div class="content"><div class="padded"><div class="single"><h1 class="title">Search Articles</h1><div class="byline">Advanced Search</div></div></div></div></div><div class="breadcrumbs"><div class="links"><ul><li><a href="/index.html">Home</a></li><li>| <a href="/cgi-bin/fullsearch.pl">Search</a></li><li>| Search Articles</li></ul></div></div><div class="columns"><div class="s1c1"><div class="padding" style="padding-bottom:0px;"><div class="section"><div class="tabs"><ul><li><span class="tab" onmouseover="overTab(this);" onmouseout="offTab(this);" onclick="document.location.href='/cgi-bin/fullsearch.pl?query=' + document.articlesearch.query.value + ((document.articlesearch.andor[1].checked) ? '&amp;andor=or' : '');">Search Full Site</span></li><li class="selected"><span class="tab">Display Article Titles</span></li><li><span class="tab" onclick="javascript:article_para('314,315,313,312,310,311,308,309,306,307,304,305,302,303,300,301,298,299,296,297');" onmouseout="offTab(this);" onmouseover="overTab(this);">Display Article Paragraphs</span></li></ul></div><form name="articlesearch" method="get" action="/cgi-bin/searcharticles.pl" onSubmit="javascript: return check_query(this.query.value);"><input type="hidden" name="searchtype" value="ArticleSearch"/><input type="hidden" name="pgct" value="1"/><input type="hidden" name="sortby" value="DD"/><div class="advanced_search"><div class="tabs_title"><table class="centered" cellpadding="0" cellspacing="0"><tr><td><input type="radio" name="searchfield" value="F" checked="true"/></td><td><div style="padding-right:30px" class="label">Search full text</div></td></tr><tr><td><input type="radio" name="searchfield" value="T"/></td><td><div style="padding-right:30px" class="label">Search Titles</div></td></tr><tr><td><input type="radio" name="searchfield" value="A"/></td><td><div style="padding-right:30px" class="label">Search authors <input type="hidden" name="id" value=""/></div></td></tr></table></div><div class="section">
7
+ Search for:
8
+ <div class="search"><table class="controls" cellpadding="0" cellspacing="0" border="0"><tr><td><input type="text" name="query" size="30" value="ha*"/></td><td><div class="button"><input type="image" src="/res/img/btn_search.jpg" class="block" onmouseover="swapImage(this,'/res/img/btn_search_over.jpg');" onmouseout="swapImage(this,'/res/img/btn_search.jpg');" alt="btn_search.jpg" title="Go" onclick="javascript: document.articlesearch.searchtype.value = 'ArticleSearch'; document.articlesearch.pgct.value = '1';"/></div></td><td class="faq"><a href="/library/help.html#articles" class="more_txt" title="Use quotes for exact phrases. Click for more tips.">HELP WITH SEARCHING ARTICLES</a></td></tr></table></div><div class="floats" style="margin-top:4px;"><div class="left"><table class="centered" cellpadding="0" cellspacing="0"><tr><td><input type="radio" name="andor" value="and" checked="true"/></td><td><div class="label">Match all terms ("and")</div></td></tr><tr><td><input type="radio" name="andor" value="or"/></td><td><div class="label">Match any terms ("or") </div></td></tr></table></div></div></div></div></form></div></div></div></div><div class="section" style="width: 600px; padding-left: 20px; padding-right: 0px;"><div id="divResults"><div class="titlebar">314 Articles found for search term(s): ha*</div><div class="floats"><div class="right"><span class="italic"><a class="more_txt" href="#pagelisting">Displaying results</a>  1-20</span></div><div class="left"><p><div class="notes"><a title="Show matching paragraphs from these articles." class="show_para" href="javascript:article_para('314,315,313,312,310,311,308,309,306,307,304,305,302,303,300,301,298,299,296,297');">SHOW PARAGRAPHS that match your search terms<br/>from articles 1-20</a></div>Click on a column heading to sort by that item (<span class="arrow-rt">Indicates current sort</span>) </p></div></div><table cellspacing="0" cellpadding="0" border="0" class="ts1"><tbody><tr><th> </th><th><div class="left"><a title="Sort by Relevance" href="javascript:proc_sort('R');"> Rank</a></div></th><th><div class="left"><a title="Sort by Title" href="javascript:proc_sort('T');">Title</a> and <a title="Sort by Author" href="javascript:proc_sort('A');"> Author</a></div></th><th class="last" style="width:90px;"><div class="left"><a title="Sort by Descending/Ascending Publication Date" href="javascript:proc_sort('DA')" class="more_txt"> Pub. Date</a></div></th></tr><tr><td>1. </td><td>(14)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('314');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2011/Murphyairsecurity.html">Ensuring—and Insuring—Air Security</a><br/>Robert P. Murphy</div></td><td class="last">07 Feb 2011<br/><i>Featured Article</i></td></tr><tr class="even"><td>2. </td><td>(5)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('315');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2011/Jasayfoolish.html">The Foolish Quest for Stability</a><br/>Anthony de Jasay</div></td><td class="last">07 Feb 2011<br/><i>Reflections from Europe</i></td></tr><tr><td>3. </td><td>(2)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('313');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2011/Jasaynegative.html">Negative Productivity</a><br/>Anthony de Jasay</div></td><td class="last">13 Jan 2011<br/><i>Reflections from Europe</i></td></tr><tr class="even"><td>4. </td><td>(21)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('312');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2011/LuskNorwoodlocavore.html">The Locavore's Dilemma: Why Pineapples Shouldn't Be Grown in North Dakota
9
+ </a><br/>Jayson L. Lusk and F. Bailey Norwood</div></td><td class="last">03 Jan 2011<br/><i>Featured Article
10
+ </i></td></tr><tr><td>5. </td><td>(17)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('310');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Leemorality.html">The Political Economy of Morality: Political Pretense vs. Market Performance</a><br/>Dwight R. Lee</div></td><td class="last">06 Dec 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>6. </td><td>(4)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('311');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasayfantasy.html">Micro, Macro and Fantasy Economics</a><br/>Anthony de Jasay</div></td><td class="last">06 Dec 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>7. </td><td>(8)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('308');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Boudreauxglobalization.html">Free Trade and Globalization: More than "Just Stuff" </a><br/>Donald J. Boudreaux</div></td><td class="last">01 Nov 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>8. </td><td>(6)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('309');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasaydemocracy.html">The Best of the Worst: What Price Democracy </a><br/>Anthony de Jasay</div></td><td class="last">01 Nov 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>9. </td><td>(22)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('306');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Murphystockmarket.html">The Stock Market </a><br/>Robert P. Murphy</div></td><td class="last">04 Oct 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>10. </td><td>(15)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('307');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasaybankdebt.html">Bank Debt, Sovereign Debt and the Dogs That Did Not Bark </a><br/>Anthony de Jasay</div></td><td class="last">04 Oct 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>11. </td><td>(8)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('304');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Sobelgangs.html">More Gangs, Less Crime </a><br/>Russell S. Sobel</div></td><td class="last">06 Sep 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>12. </td><td>(9)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('305');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasaytwocheers.html">Two Cheers For Fiscal Austerity: Part II. </a><br/>Anthony de Jasay</div></td><td class="last">06 Sep 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>13. </td><td>(27)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('302');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Murphydiscrimination.html">The Economics of Discrimination </a><br/>Robert P. Murphy</div></td><td class="last">02 Aug 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>14. </td><td>(12)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('303');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasayausterity.html">Two Cheers For Fiscal Austerity: Part I. </a><br/>Anthony de Jasay</div></td><td class="last">02 Aug 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>15. </td><td>(16)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('300');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Sumnerneoliberalism.html">The Unacknowledged Success of Neoliberalism </a><br/>Scott Sumner</div></td><td class="last">05 Jul 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>16. </td><td>(20)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('301');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasayinsurance.html">Is Society a Great Big Insurance Company? </a><br/>Anthony de Jasay</div></td><td class="last">05 Jul 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>17. </td><td>(29)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('298');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Powellimmigration.html">An Economic Case for Immigration </a><br/>Benjamin Powell</div></td><td class="last">07 Jun 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>18. </td><td>(22)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('299');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasaydebtcard.html">Is Society a Great Big Credit Card? Part II. </a><br/>Anthony de Jasay</div></td><td class="last">07 Jun 2010<br/><i>Reflections from Europe</i></td></tr><tr><td>19. </td><td>(8)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('296');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Borderssubjectivity.html">The Relentless Subjectivity of Value </a><br/>Max Borders</div></td><td class="last">03 May 2010<br/><i>Featured Article</i></td></tr><tr class="even"><td>20. </td><td>(12)<br/><a class="show_para" title="Show matching paragraphs from this article." href="javascript:article_para('297');"> </a></td><td><div class="p"><a class="bold-blue" title="View Article with search terms highlighted" href="/library/Columns/y2010/Jasaycreditcard.html">Is Society a Great Big Credit Card? Part I.</a><br/>Anthony de Jasay</div></td><td class="last">03 May 2010<br/><i>Reflections from Europe</i></td></tr></tbody></table><br/><a class="more_txt" name="pagelisting">Displaying results</a> 1-20 on Page 1 of 16. Pages
11
+ <b>1</b> <a href="javascript: proc_page('2');" title="Page 2" class="links"><u>2</u></a> <a href="javascript: proc_page('3');" title="Page 3" class="links"><u>3</u></a> <a href="javascript: proc_page('4');" title="Page 4" class="links"><u>4</u></a> <a href="javascript: proc_page('5');" title="Page 5" class="links"><u>5</u></a> <a href="javascript: proc_page('6');" title="Page 6" class="links"><u>6</u></a> <a href="javascript: proc_page('7');" title="Page 7" class="links"><u>7</u></a> <a href="javascript: proc_page('8');" title="Page 8" class="links"><u>8</u></a> <a href="javascript: proc_page('9');" title="Page 9" class="links"><u>9</u></a> <a href="javascript: proc_page('10');" title="Page 10" class="links"><u>10</u></a> <a href="javascript: proc_page('11');" title="Page 11" class="links"><u>11</u></a> <a href="javascript: proc_page('12');" title="Page 12" class="links"><u>12</u></a> <a href="javascript: proc_page('13');" title="Page 13" class="links"><u>13</u></a> <a href="javascript: proc_page('14');" title="Page 14" class="links"><u>14</u></a> <a href="javascript: proc_page('15');" title="Page 15" class="links"><u>15</u></a> <a href="javascript: proc_page('16');" title="Page 16" class="links"><u>16</u></a> <script type="text/javascript"><!--
12
+ function proc_sort(sort_var) { document.articlesearch.sortby.value = sort_var; document.articlesearch.searchtype.value = 'Search'; document.articlesearch.submit(); }
13
+ function article_para(id) { document.articlesearch.reset(); document.articlesearch.searchtype.value = 'ArticleSearchPara'; document.articlesearch.id.value = id; document.articlesearch.submit();}
14
+ function proc_page(pgnum) { document.articlesearch.reset(); document.articlesearch.pgct.value = pgnum; document.articlesearch.searchtype.value = 'Search'; document.articlesearch.submit(); }
15
+
16
+ --></script></div></div><div class="p"><a class="top" href="#">Return to top</a></div></td></tr><tr><td class="footer_sidebar"><div class="sidebar"><div class="p">
17
+ Copyright © 1999-2008<br/><a href="http://www.libertyfund.org">Liberty Fund, Inc.</a><br/>
18
+ All Rights Reserved
19
+ </div></div><img src="/res/img/spacer.gif" width="180" height="1" class="block" alt="spacer gif"/></td><td class="footer_page"><div class="content"><div style="float:left;"><img src="/res/img/amagiLF.jpg" title="Liberty Fund logo, amagi symbol" alt="Liberty Fund logo, amagi symbol"/></div><div style="float:left;width:321px;padding-right:10px;">
20
+ The cuneiform inscription in the Liberty Fund logo is the earliest-known written appearance of the word "freedom" (amagi), or "liberty." It is taken from a clay document written about 2300 B.C. in the Sumerian city-state of Lagash.
21
+ </div><div style="float:left;width:50px;"><a href="/library/contact.html">Contact</a> <a href="/library/sitemap.html">Site Map</a> <a href="/library/privacy.html">Privacy and Legal</a> <a href="http://www.econlib.org">http://www.econlib.org</a></div></div><img src="/res/img/spacer.gif" width="560" height="1" class="block" alt="spacer gif"/></td></tr></table></body></html>
data/test/semis/links.txt CHANGED
@@ -1,3 +1,4 @@
1
1
  # output_file URL
2
2
  quora.html http://www.quora.com/Brandon-Smietana/answers
3
3
  bwk.html http://www.dailyprincetonian.com/advanced_search/?author=Brian+Kernighan
4
+ econlib.html http://www.econlib.org/cgi-bin/searcharticles.pl?sortby=DD&query=ha*
data/test/test_fetch.rb CHANGED
@@ -1,28 +1,25 @@
1
- require 'digest/md5'
2
-
3
- require_relative '../lib/bwkfanboy/utils'
4
- require_relative 'ts_utils'
1
+ require_relative 'helper'
5
2
 
6
3
  # TODO add HTTP 404 check; drop connection from server during HTTP 200
7
4
  # replay...
8
5
  class TestFetch < MiniTest::Unit::TestCase
9
- CMD = 'bwkfanboy_fetch'
6
+ CMD = cmd('bwkfanboy_fetch')
10
7
 
11
8
  def test_empty_url
12
- r = Bwkfanboy::Utils.cmd_run("echo '' | #{cmd CMD}")
9
+ r = Utils.cmd_run("echo '' | #{CMD}")
13
10
  assert_equal(1, r[0])
14
11
  assert_match(/No such file or directory/, r[1])
15
12
  end
16
13
 
17
14
  def test_invalid_url
18
- r = Bwkfanboy::Utils.cmd_run("echo 'http://invalid.hostname.qwerty' | #{cmd CMD}")
15
+ r = Utils.cmd_run("echo 'http://invalid.hostname.qwerty' | #{CMD}")
19
16
  assert_equal(1, r[0])
20
17
  assert_match(/504 Host .+ lookup failed: Host not found/, r[1])
21
18
  end
22
19
 
23
20
  def test_local_file
24
21
  cmd CMD
25
- r = Bwkfanboy::Utils.cmd_run("echo #{@tpath}semis/bwk.html | #{cmd CMD}")
22
+ r = Utils.cmd_run("echo semis/bwk.html | #{CMD}")
26
23
  assert_equal(0, r[0])
27
24
  # MD5 (html/bwk.html) = c8259a358dd7261a79b226985d3e8753
28
25
  assert_equal(Digest::MD5.hexdigest(r[2]), '00cc906c59c0eb11c3eaa8166dab729f')
@@ -1,25 +1,22 @@
1
- require 'digest/md5'
2
-
3
- require_relative '../lib/bwkfanboy/utils'
4
- require_relative 'ts_utils'
1
+ require_relative 'helper'
5
2
 
6
3
  class TestGenerate < MiniTest::Unit::TestCase
7
- CMD = 'bwkfanboy_generate'
4
+ CMD = cmd('bwkfanboy_generate')
8
5
 
9
6
  def test_empty_input
10
- r = Bwkfanboy::Utils.cmd_run("echo '' | #{cmd CMD}")
7
+ r = Utils.cmd_run("echo '' | #{CMD}")
11
8
  assert_equal(1, r[0])
12
9
  assert_match(/stdin had invalid JSON/, r[1])
13
10
  end
14
11
 
15
12
  def test_invalid_json
16
- r = Bwkfanboy::Utils.cmd_run("echo '{\"foo\" : \"bar\"}' | #{cmd CMD} --check")
13
+ r = Utils.cmd_run("echo '{\"foo\" : \"bar\"}' | #{CMD} --check")
17
14
  assert_equal(1, r[0])
18
15
  assert_match(/channel is missing and it is not optional/, r[1])
19
16
  end
20
17
 
21
18
  def test_right_json
22
- r = Bwkfanboy::Utils.cmd_run("#{cmd CMD} --check < #{@tpath}semis/bwk.json")
19
+ r = Utils.cmd_run("#{CMD} --check < semis/bwk.json")
23
20
  assert_equal(0, r[0])
24
21
  # bin/bwkfanboy_generate < test/semis/bwk.json|md5
25
22
  assert_equal('adc5a0d9487bdc11b6896fe29745ffa3', Digest::MD5.hexdigest(r[2]))
data/test/test_parse.rb CHANGED
@@ -1,27 +1,25 @@
1
- require 'digest/md5'
2
-
3
- require_relative '../lib/bwkfanboy/utils'
4
- require_relative 'ts_utils'
1
+ require_relative 'helper'
5
2
 
6
3
  class TestParse < MiniTest::Unit::TestCase
7
- CMD = 'bwkfanboy_parse'
4
+ CMD = cmd('bwkfanboy_parse')
5
+ LIBDIR = '../lib/bwkfanboy'
8
6
 
9
7
  def test_no_plugin
10
- r = Bwkfanboy::Utils.cmd_run("#{cmd CMD} ''")
8
+ r = Utils.cmd_run("#{CMD} ''")
11
9
  assert_equal(1, r[0])
12
10
  assert_match(/cannot load plugin/, r[1])
13
11
  end
14
12
 
15
13
  def test_empty_plugin
16
14
  cmd CMD
17
- r = Bwkfanboy::Utils.cmd_run("#{cmd CMD} #{Dir.pwd}/#{@tpath}plugins/empty.rb ")
15
+ r = Utils.cmd_run("#{CMD} #{Dir.pwd}/plugins/empty.rb")
18
16
  assert_equal(1, r[0])
19
17
  assert_match(/plugin .+ has errors: class Page isn't defined/, r[1])
20
18
  end
21
19
 
22
20
  def test_plugin_parse
23
21
  cmd CMD
24
- r = Bwkfanboy::Utils.cmd_run("#{cmd CMD} #{Dir.pwd}/#{@tpath}../lib/bwkfanboy/plugins/bwk.rb < #{@tpath}semis/bwk.html")
22
+ r = Utils.cmd_run("#{CMD} #{Dir.pwd}/#{LIBDIR}/plugins/bwk.rb < semis/bwk.html")
25
23
  assert_equal(0, r[0])
26
24
  # bin/bwkfanboy_parse `pwd`/lib/bwkfanboy/plugins/bwk.rb < test/semis/bwk.html | md5
27
25
  assert_equal('a433a4a27bafb060a41aa85a40808056', Digest::MD5.hexdigest(r[2]))
data/test/test_server.rb CHANGED
@@ -1,19 +1,18 @@
1
1
  require 'open-uri'
2
- require 'digest/md5'
3
2
 
4
- require_relative 'ts_utils'
3
+ require_relative 'helper'
5
4
 
6
5
  $count = 1
7
6
 
8
7
  # this tests will mess up logs and the pid file
9
8
  class TestServer < MiniTest::Unit::TestCase
10
- CMD = 'bwkfanboy_server'
9
+ CMD = cmd('bwkfanboy_server')
11
10
  PORT = 9042
12
11
  ADDR = '127.0.0.1'
13
12
 
14
13
  def setup
15
14
  @port = PORT + $count
16
- @pid = spawn("#{cmd CMD} -D -p #{@port}")
15
+ @pid = spawn("#{CMD} -D -p #{@port}")
17
16
  $count += 1
18
17
  sleep(2) # wait for the server's loading
19
18
  end
data/web/bwkfanboy.cgi ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # -*-ruby-*-
3
+
4
+ require 'cgi'
5
+ require_relative '../lib/bwkfanboy/parser'
6
+
7
+ # set this!
8
+ CONVERTER = '/home/alex/lib/software/alex/bwkfanboy/bin/bwkfanboy'
9
+
10
+ def errx(t)
11
+ print "Content-Type: text/plain\r\n\r\n"
12
+ print "#{Bwkfanboy::Meta::NAME}.cgi error: #{t}"
13
+ exit 0
14
+ end
15
+
16
+ cgi = CGI.new
17
+ if cgi.has_key?('p') then
18
+ errx("invalid plugin name: #{cgi['p']}") if cgi['p'] !~ Bwkfanboy::Meta::PLUGIN_NAME
19
+ else
20
+ errx("parametr 'p' required")
21
+ end
22
+
23
+ if cgi.has_key?('o')
24
+ errx("'o' is too harsh") if cgi['o'] !~ Bwkfanboy::Meta::PLUGIN_OPTS
25
+ end
26
+
27
+ cmd = "#{CONVERTER} '#{cgi['p']}' #{cgi['o']}"
28
+ r = Bwkfanboy::Utils.cmd_run(cmd)
29
+ errx("\n\n#{r[1]}") if r[0] != 0
30
+ xml = r[2]
31
+
32
+ print "Content-Type: application/atom+xml; charset=UTF-8\r\n"
33
+ print "Content-Length: #{xml.length}\r\n"
34
+ print "Content-Disposition: inline; filename=\"#{Bwkfanboy::Meta::NAME}-#{cgi['p']}.xml\"\r\n\r\n"
35
+
36
+ puts xml
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 2
8
- - 9
9
- version: 1.2.9
7
+ - 3
8
+ - 0
9
+ version: 1.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Alexander Gromnitsky
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-07 00:00:00 +02:00
17
+ date: 2011-02-10 00:00:00 +02:00
18
18
  default_executable: bwkfanboy
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: activesupport
21
+ name: open4
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
@@ -26,14 +26,14 @@ dependencies:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
- - 3
29
+ - 1
30
30
  - 0
31
- - 3
32
- version: 3.0.3
31
+ - 1
32
+ version: 1.0.1
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  - !ruby/object:Gem::Dependency
36
- name: nokogiri
36
+ name: activesupport
37
37
  prerelease: false
38
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
@@ -41,14 +41,14 @@ dependencies:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  segments:
44
- - 1
45
- - 4
46
- - 4
47
- version: 1.4.4
44
+ - 3
45
+ - 0
46
+ - 3
47
+ version: 3.0.3
48
48
  type: :runtime
49
49
  version_requirements: *id002
50
50
  - !ruby/object:Gem::Dependency
51
- name: open4
51
+ name: nokogiri
52
52
  prerelease: false
53
53
  requirement: &id003 !ruby/object:Gem::Requirement
54
54
  none: false
@@ -57,9 +57,9 @@ dependencies:
57
57
  - !ruby/object:Gem::Version
58
58
  segments:
59
59
  - 1
60
- - 0
61
- - 1
62
- version: 1.0.1
60
+ - 4
61
+ - 4
62
+ version: 1.4.4
63
63
  type: :runtime
64
64
  version_requirements: *id003
65
65
  - !ruby/object:Gem::Dependency
@@ -77,6 +77,21 @@ dependencies:
77
77
  version: 2.0.0
78
78
  type: :runtime
79
79
  version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: git
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 1
90
+ - 2
91
+ - 5
92
+ version: 1.2.5
93
+ type: :development
94
+ version_requirements: *id005
80
95
  description: A converter from HTML to Atom feed that you can use to watch sites that do not provide its own feed.
81
96
  email: alexander.gromnitsky@gmail.com
82
97
  executables:
@@ -96,46 +111,52 @@ extra_rdoc_files:
96
111
  - doc/bwkfanboy_generate.rdoc
97
112
  - doc/bwkfanboy_parse.rdoc
98
113
  - doc/bwkfanboy_server.rdoc
114
+ - doc/TODO
99
115
  files:
100
- - lib/bwkfanboy/plugins/bwk.rb
101
- - lib/bwkfanboy/plugins/freebsd-ports-update.rb
102
- - lib/bwkfanboy/plugins/quora.js
103
- - lib/bwkfanboy/plugins/quora.rb
104
- - lib/bwkfanboy/parser.rb
105
- - lib/bwkfanboy/utils.rb
106
- - lib/bwkfanboy/schema.js
107
- - lib/bwkfanboy/fetch.rb
108
- - lib/bwkfanboy/generate.rb
109
- - lib/bwkfanboy/plugin_skeleton.erb
116
+ - README.rdoc
117
+ - Rakefile
118
+ - bin/bwkfanboy
119
+ - bin/bwkfanboy_fetch
110
120
  - bin/bwkfanboy_generate
111
121
  - bin/bwkfanboy_parse
112
- - bin/bwkfanboy
113
122
  - bin/bwkfanboy_server
114
- - bin/bwkfanboy_fetch
115
123
  - doc/LICENSE
116
124
  - doc/NEWS.rdoc
117
125
  - doc/README.rdoc
118
- - doc/plugin.rdoc
126
+ - doc/TODO
119
127
  - doc/bwkfanboy_fetch.rdoc
120
128
  - doc/bwkfanboy_generate.rdoc
121
129
  - doc/bwkfanboy_parse.rdoc
122
130
  - doc/bwkfanboy_server.rdoc
123
- - README.rdoc
124
- - Rakefile
125
- - TODO
131
+ - doc/plugin.rdoc
132
+ - lib/bwkfanboy/fetch.rb
133
+ - lib/bwkfanboy/generate.rb
134
+ - lib/bwkfanboy/meta.rb
135
+ - lib/bwkfanboy/parser.rb
136
+ - lib/bwkfanboy/plugin_skeleton.erb
137
+ - lib/bwkfanboy/plugins/bwk.rb
138
+ - lib/bwkfanboy/plugins/econlib.rb
139
+ - lib/bwkfanboy/plugins/freebsd-ports-update.rb
140
+ - lib/bwkfanboy/plugins/quora.js
141
+ - lib/bwkfanboy/plugins/quora.rb
142
+ - lib/bwkfanboy/schema.js
143
+ - lib/bwkfanboy/utils.rb
144
+ - test/helper.rb
126
145
  - test/plugins/empty.rb
146
+ - test/popen4.sh
147
+ - test/rake_git.rb
148
+ - test/semis/Rakefile
127
149
  - test/semis/bwk.html
128
150
  - test/semis/bwk.json
129
- - test/semis/quora.html
151
+ - test/semis/econlib.html
130
152
  - test/semis/links.txt
131
- - test/semis/Rakefile
153
+ - test/semis/quora.html
132
154
  - test/test_fetch.rb
133
- - test/test_parse.rb
134
- - test/xml-clean.sh
135
- - test/popen4.sh
136
- - test/ts_utils.rb
137
155
  - test/test_generate.rb
156
+ - test/test_parse.rb
138
157
  - test/test_server.rb
158
+ - test/xml-clean.sh
159
+ - web/bwkfanboy.cgi
139
160
  has_rdoc: true
140
161
  homepage: http://github.com/gromnitsky/bwkfanboy
141
162
  licenses: []
data/TODO DELETED
@@ -1,4 +0,0 @@
1
- -*-text-*-
2
-
3
- - Add plugin listing to bwkfanboy_server.
4
- - More tests.
data/test/ts_utils.rb DELETED
@@ -1,29 +0,0 @@
1
- # don't run test automatically
2
- # if they were invoked as 'gem check -t ...'
3
- if $0 =~ /gem/
4
- require 'minitest/unit'
5
- else
6
- require 'minitest/autorun'
7
- end
8
-
9
- # return the right directory for _c_
10
- def cmd(c)
11
- @tpath = ''
12
- case File.basename(Dir.pwd)
13
- when 'bwkfanboy'
14
- # test probably is executed from the Rakefile
15
- @tpath = 'test/'
16
- 'bin/' + c
17
- when 'test'
18
- # we are probably in the test directory
19
- '../bin/' + c
20
- else
21
- # tests were invoked by 'gem check -t bwkfanboy'
22
- begin
23
- Dir.chdir(Bwkfanboy::Utils.gem_dir_system + '/../../test')
24
- '../bin/' + c
25
- rescue
26
- raise "running tests from '#{Dir.pwd}' isn't supported: #{$!}"
27
- end
28
- end
29
- end