rea 0.0.1

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.
Files changed (48) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +48 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +7 -0
  7. data/Rakefile +23 -0
  8. data/bin/rea +8 -0
  9. data/lib/rea-dblp/rea/dblp.rb +59 -0
  10. data/lib/rea-dblp/rea/dblp/entry_parser.rb +48 -0
  11. data/lib/rea-dblp/rea/dblp/grab.rb +14 -0
  12. data/lib/rea-dblp/rea/dblp/parser.rb +36 -0
  13. data/lib/rea-dblp/rea/dblp/query_result_parser.rb +38 -0
  14. data/lib/rea-dblp/rea/dblp/search.rb +18 -0
  15. data/lib/rea.rb +28 -0
  16. data/lib/rea/command.rb +62 -0
  17. data/lib/rea/command/search.rb +52 -0
  18. data/lib/rea/command/utils.rb +31 -0
  19. data/lib/rea/errors.rb +62 -0
  20. data/lib/rea/loader.rb +8 -0
  21. data/lib/rea/version.rb +14 -0
  22. data/lib/rea/work_key.rb +33 -0
  23. data/rea.gemspec +192 -0
  24. data/rea.noespec +33 -0
  25. data/spec/rea-dblp/fixtures/entries/Damas2005.xml +17 -0
  26. data/spec/rea-dblp/fixtures/entries/Damas2009.xml +16 -0
  27. data/spec/rea-dblp/fixtures/entries/Erroneous.xml +1 -0
  28. data/spec/rea-dblp/fixtures/entries/QueryEntry.xml +15 -0
  29. data/spec/rea-dblp/fixtures/entries/Unrecognized.xml +3 -0
  30. data/spec/rea-dblp/fixtures/query_results/Erroneous.xml +1 -0
  31. data/spec/rea-dblp/fixtures/query_results/QueryResult.xml +25 -0
  32. data/spec/rea-dblp/fixtures/query_results/Unrecognized.xml +3 -0
  33. data/spec/rea-dblp/test_entry_parser.rb +72 -0
  34. data/spec/rea-dblp/test_grab.rb +18 -0
  35. data/spec/rea-dblp/test_query_result_parser.rb +38 -0
  36. data/spec/rea-dblp/test_search.rb +18 -0
  37. data/spec/spec_helper.rb +12 -0
  38. data/spec/test_rea.rb +12 -0
  39. data/spec/work_key/test_parse.rb +28 -0
  40. data/spec/work_key/test_to_ruby_literal.rb +20 -0
  41. data/spec/work_key/test_to_s.rb +12 -0
  42. data/tasks/debug_mail.rake +75 -0
  43. data/tasks/debug_mail.txt +13 -0
  44. data/tasks/gem.rake +68 -0
  45. data/tasks/spec_test.rake +71 -0
  46. data/tasks/unit_test.rake +76 -0
  47. data/tasks/yard.rake +51 -0
  48. metadata +215 -0
@@ -0,0 +1,5 @@
1
+ # 0.0.1 / FIX ME
2
+
3
+ * Enhancements
4
+
5
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :runtime do
4
+ gem "http", "~> 0.1.0"
5
+ gem "nokogiri", "~> 1.5"
6
+ gem "quickl", "~> 0.4.2"
7
+ gem "pdf-toolkit", "= 1.0.0.rc1"
8
+ gem "epath", "~> 0.0.1"
9
+ gem "alf", "~> 0.12.0"
10
+ gem "bibtex-ruby", "~> 2.0"
11
+ end
12
+
13
+ group :development do
14
+ gem "rake", "~> 0.9.2"
15
+ gem "rspec", "~> 2.8.0"
16
+ end
@@ -0,0 +1,48 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ alf (0.12.0)
5
+ backports (~> 2.3.0)
6
+ myrrha (~> 1.2.1)
7
+ quickl (~> 0.4.2)
8
+ backports (2.3.0)
9
+ bibtex-ruby (2.0.4)
10
+ latex-decode (>= 0.0.6)
11
+ multi_json (~> 1.0)
12
+ diff-lcs (1.1.3)
13
+ epath (0.0.1)
14
+ http (0.1.0)
15
+ latex-decode (0.0.12)
16
+ unicode (~> 0.4)
17
+ latex-decode (0.0.12-java)
18
+ multi_json (1.0.4)
19
+ myrrha (1.2.2)
20
+ nokogiri (1.5.0)
21
+ nokogiri (1.5.0-java)
22
+ pdf-toolkit (1.0.0.rc1)
23
+ quickl (0.4.2)
24
+ rake (0.9.2.2)
25
+ rspec (2.8.0)
26
+ rspec-core (~> 2.8.0)
27
+ rspec-expectations (~> 2.8.0)
28
+ rspec-mocks (~> 2.8.0)
29
+ rspec-core (2.8.0)
30
+ rspec-expectations (2.8.0)
31
+ diff-lcs (~> 1.1.2)
32
+ rspec-mocks (2.8.0)
33
+ unicode (0.4.1)
34
+
35
+ PLATFORMS
36
+ java
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ alf (~> 0.12.0)
41
+ bibtex-ruby (~> 2.0)
42
+ epath (~> 0.0.1)
43
+ http (~> 0.1.0)
44
+ nokogiri (~> 1.5)
45
+ pdf-toolkit (= 1.0.0.rc1)
46
+ quickl (~> 0.4.2)
47
+ rake (~> 0.9.2)
48
+ rspec (~> 2.8.0)
@@ -0,0 +1,22 @@
1
+ # The MIT Licence
2
+
3
+ Copyright (c) 2012 - Bernard Lambeau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ rea.gemspec
2
+ rea.noespec
3
+ .gemtest
4
+ CHANGELOG.md
5
+ Gemfile
6
+ Gemfile.lock
7
+ bin/**/*
8
+ lib/**/*
9
+ LICENCE.md
10
+ Manifest.txt
11
+ Rakefile
12
+ README.md
13
+ spec/**/*
14
+ tasks/**/*
15
+ test/**/*
@@ -0,0 +1,7 @@
1
+ # Rea
2
+
3
+ Research Exploring Assistant
4
+
5
+ ## Links
6
+
7
+ https://github.com/blambeau/rea
@@ -0,0 +1,23 @@
1
+ begin
2
+ gem "bundler", "~> 1.0"
3
+ require "bundler/setup"
4
+ rescue LoadError => ex
5
+ puts ex.message
6
+ abort "Bundler failed to load, (did you run 'gem install bundler' ?)"
7
+ end
8
+
9
+ # Dynamically load the gem spec
10
+ $gemspec_file = File.expand_path('../rea.gemspec', __FILE__)
11
+ $gemspec = Kernel.eval(File.read($gemspec_file))
12
+
13
+ # We run tests by default
14
+ task :default => :test
15
+
16
+ #
17
+ # Install all tasks found in tasks folder
18
+ #
19
+ # See .rake files there for complete documentation.
20
+ #
21
+ Dir["tasks/*.rake"].each do |taskfile|
22
+ load taskfile
23
+ end
data/bin/rea ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ Dir.chdir File.dirname(__FILE__) do
3
+ require 'bundler/setup'
4
+ end
5
+ $:.unshift File.expand_path('../../lib', __FILE__)
6
+ require 'rea/command'
7
+ Rea::Command.run(ARGV)
8
+
@@ -0,0 +1,59 @@
1
+ module Rea
2
+ module DBLP
3
+
4
+ def grab(identifier)
5
+ Grab.new.call(identifier)
6
+ end
7
+ module_function :grab
8
+
9
+ def search(query)
10
+ Search.new.call(query)
11
+ end
12
+ module_function :search
13
+
14
+ def url
15
+ "http://www.dblp.org"
16
+ end
17
+ module_function :url
18
+
19
+ def shortcut
20
+ "dblp"
21
+ end
22
+ module_function :shortcut
23
+
24
+ private
25
+
26
+ include Rea::ErrorUtils
27
+
28
+ def entry_url(identifier)
29
+ "#{url}/rec/bibtex/#{identifier}.xml"
30
+ end
31
+
32
+ def search_url
33
+ "#{url}/search/api"
34
+ end
35
+
36
+ def get(url)
37
+ got = Http.get(url, :response => :object)
38
+ case got.status
39
+ when 200...300
40
+ not_found_error!(url) if got.body.empty?
41
+ got.body
42
+ when 400...500
43
+ not_found_error!(url)
44
+ when 500...600
45
+ third_party_error!(url)
46
+ else
47
+ unexpected_error!(url)
48
+ end
49
+ end
50
+
51
+ Rea::register_provider(self)
52
+ end # module DBLP
53
+ end # module Rea
54
+ require_relative 'dblp/parser'
55
+ require_relative 'dblp/entry_parser'
56
+ require_relative 'dblp/query_result_parser'
57
+ require_relative 'dblp/grab'
58
+ require_relative 'dblp/search'
59
+
@@ -0,0 +1,48 @@
1
+ module Rea
2
+ module DBLP
3
+ class EntryParser < Parser
4
+
5
+ def parse_text(entry, source = nil)
6
+ entries = []
7
+ parse_xml(entry, source) do |doc|
8
+ doc.xpath("/dblp/*").each do |entry|
9
+ entries << send(:"parse_#{entry.name}", entry)
10
+ end
11
+ end
12
+ entries
13
+ end
14
+
15
+ private
16
+
17
+ ###
18
+
19
+ def parse_inproceedings(entry)
20
+ { :kind => "inproceedings",
21
+ :key => work_key(entry.attribute("key").text),
22
+ :title => entry.xpath("title").text,
23
+ :source => entry.xpath("booktitle").text,
24
+ :year => entry.xpath("year").text,
25
+ :authors => entry.xpath("author").map(&:text) }
26
+ end
27
+
28
+ def parse_article(entry)
29
+ { :kind => "article",
30
+ :key => work_key(entry.attribute("key").text),
31
+ :title => entry.xpath("title").text,
32
+ :source => entry.xpath("journal").text,
33
+ :year => entry.xpath("year").text,
34
+ :authors => entry.xpath("author").map(&:text) }
35
+ end
36
+
37
+ def parse_queryentry(entry)
38
+ { :kind => entry.xpath('type').text,
39
+ :key => work_key(entry.attribute("key").text),
40
+ :title => entry.xpath("title").text,
41
+ :source => entry.xpath("venue").text,
42
+ :year => entry.xpath("year").text,
43
+ :authors => entry.xpath("authors/author").map(&:text) }
44
+ end
45
+
46
+ end # class EntryParser
47
+ end # module DBLP
48
+ end # module Rea
@@ -0,0 +1,14 @@
1
+ module Rea
2
+ module DBLP
3
+ class Grab
4
+ include DBLP
5
+
6
+ def call(identifier)
7
+ xml = get entry_url(identifier)
8
+ tuples = EntryParser.parse(xml)
9
+ tuples.first
10
+ end
11
+
12
+ end # class Grab
13
+ end # module DBLP
14
+ end # module Rea
@@ -0,0 +1,36 @@
1
+ module Rea
2
+ module DBLP
3
+ class Parser
4
+ include Rea::ErrorUtils
5
+
6
+ def self.parse(*args, &bl)
7
+ new.parse(*args, &bl)
8
+ end
9
+
10
+ def parse(path)
11
+ if path.respond_to?(:to_path)
12
+ parse_text(Path(path).read, path)
13
+ else
14
+ parse_text(path, nil)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def work_key(identifier)
21
+ WorkKey.new("dblp", identifier)
22
+ end
23
+
24
+ def parse_xml(xml, source)
25
+ options = Nokogiri::XML::ParseOptions::STRICT
26
+ parsed = Nokogiri::XML(xml.to_s, source.to_s, nil, options)
27
+ block_given? ? yield(parsed) : parsed
28
+ rescue NoMethodError
29
+ parse_format_error!(source)
30
+ rescue Nokogiri::XML::SyntaxError
31
+ parse_error!(source)
32
+ end
33
+
34
+ end # class Parser
35
+ end # module DBLP
36
+ end # module Rea
@@ -0,0 +1,38 @@
1
+ module Rea
2
+ module DBLP
3
+ class QueryResultParser < Parser
4
+
5
+ def parse_text(result, source = nil)
6
+ entries = []
7
+ parse_xml(result, source) do |doc|
8
+ unrecognized!(source) if doc.xpath('/result').empty?
9
+ doc.xpath("/result/hits/hit").each do |entry|
10
+ entries << send(:"xml_parse_hit", entry)
11
+ end
12
+ end
13
+ entries
14
+ end
15
+
16
+ private
17
+
18
+ def fix_xmlns(xml)
19
+ xml.gsub %r{<result>},
20
+ %q{<result xmlns:dblp="http://www.dblp.org/xmlns/dblp">}
21
+ end
22
+
23
+ def xml_parse_hit(hit)
24
+ key = hit.xpath('url').text[%r{http://www.dblp.org/rec/bibtex/(.*)}, 1]
25
+ content = <<-XML.gsub(/\n\s*/, "")
26
+ <dblp>
27
+ <queryentry key="#{key}">
28
+ #{hit.xpath('title').inner_text}
29
+ </queryentry>
30
+ </dblp>
31
+ XML
32
+ EntryParser.parse(content).first
33
+ end
34
+
35
+ end # class QueryResultParser
36
+ end # module DBLP
37
+ end # module Rea
38
+
@@ -0,0 +1,18 @@
1
+ module Rea
2
+ module DBLP
3
+ class Search
4
+ include DBLP
5
+
6
+ def call(query)
7
+ unless query.size == 1 and query[:title]
8
+ not_implemented_error!("Unable to search with #{query.inspect}")
9
+ end
10
+ title = query[:title].gsub(/\s+/, "%20")
11
+ xml = get("#{search_url}?q=#{title}")
12
+ tuples = QueryResultParser.parse(xml)
13
+ Relation(tuples)
14
+ end
15
+
16
+ end # class Search
17
+ end # module DBLP
18
+ end # module Rea
@@ -0,0 +1,28 @@
1
+ require_relative "rea/version"
2
+ require_relative "rea/loader"
3
+ require_relative "rea/errors"
4
+
5
+ #
6
+ # Research Exploring Assistant
7
+ #
8
+ module Rea
9
+
10
+ def WorkKey(str)
11
+ WorkKey.parse(str)
12
+ end
13
+ module_function :WorkKey
14
+
15
+ def register_provider(provider)
16
+ providers << provider
17
+ end
18
+ module_function :register_provider
19
+
20
+ def providers
21
+ @providers ||= []
22
+ end
23
+ module_function :providers
24
+
25
+ end # module Rea
26
+
27
+ require_relative 'rea/work_key'
28
+ require_relative 'rea-dblp/rea/dblp'
@@ -0,0 +1,62 @@
1
+ require 'rea'
2
+ module Rea
3
+ #
4
+ # rea - The Research Exploring Assistant
5
+ #
6
+ # SYNOPSIS
7
+ # #{program_name} [--version] [--help] COMMAND [cmd opts] ARGS...
8
+ #
9
+ # OPTIONS
10
+ # #{summarized_options}
11
+ #
12
+ # COMMANDS
13
+ # #{summarized_subcommands}
14
+ #
15
+ # See '#{program_name} help COMMAND' for more information on a specific command.
16
+ #
17
+ class Command < Quickl::Delegator(__FILE__, __LINE__)
18
+
19
+ # Install options
20
+ options do |opt|
21
+ @trace = false
22
+ opt.on('--trace') do
23
+ @trace = true
24
+ end
25
+ opt.on_tail("--help", "Show help") do
26
+ raise Quickl::Help
27
+ end
28
+ opt.on_tail("--version", "Show version") do
29
+ raise Quickl::Exit,
30
+ "rea #{Rea::VERSION} (c) 2012, Bernard Lambeau"
31
+ end
32
+ end
33
+
34
+ def execute(*args)
35
+ super
36
+ rescue Quickl::Error
37
+ raise
38
+ rescue Rea::Error => ex
39
+ if @trace
40
+ dump_exception(ex)
41
+ else
42
+ $stderr.puts ex.message
43
+ end
44
+ rescue Exception => ex
45
+ puts "Sorry, an internal error occured. Please report --trace to developers."
46
+ dump_exception(ex) if @trace
47
+ end
48
+
49
+ private
50
+
51
+ def dump_exception(ex, indent = 0)
52
+ $stderr.puts ex.message.gsub(/^/m," "*indent)
53
+ $stderr.puts ex.backtrace.map{|s|
54
+ s.gsub(/^/m," "*(indent+1))
55
+ }.join("\n")
56
+ dump_exception(ex.cause, indent + 1) if ex.respond_to?(:cause)
57
+ end
58
+
59
+ end # class Command
60
+ end # module Rea
61
+ require_relative "command/utils"
62
+ require_relative "command/search"