bwkfanboy 1.2.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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