instapaper 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/{PostInstall.txt → .gemtest} +0 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.simplecov +1 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE.md +20 -0
  8. data/README.md +152 -0
  9. data/Rakefile +13 -4
  10. data/instapaper.gemspec +33 -0
  11. data/lib/faraday/response/raise_http_1xxx.rb +65 -0
  12. data/lib/instapaper.rb +26 -10
  13. data/lib/instapaper/authentication.rb +32 -0
  14. data/lib/instapaper/client.rb +43 -0
  15. data/lib/instapaper/client/account.rb +13 -0
  16. data/lib/instapaper/client/bookmark.rb +81 -0
  17. data/lib/instapaper/client/folder.rb +34 -0
  18. data/lib/instapaper/client/user.rb +14 -0
  19. data/lib/instapaper/configuration.rb +88 -0
  20. data/lib/instapaper/connection.rb +35 -0
  21. data/lib/instapaper/request.rb +22 -9
  22. data/lib/instapaper/version.rb +1 -31
  23. data/spec/faraday/response_spec.rb +22 -0
  24. data/spec/fixtures/access_token.qline +1 -0
  25. data/spec/fixtures/bookmarks_add.json +1 -0
  26. data/spec/fixtures/bookmarks_archive.json +1 -0
  27. data/spec/fixtures/bookmarks_get_text.txt +299 -0
  28. data/spec/fixtures/bookmarks_list.json +5 -0
  29. data/spec/fixtures/bookmarks_move.json +1 -0
  30. data/spec/fixtures/bookmarks_star.json +1 -0
  31. data/spec/fixtures/bookmarks_unarchive.json +1 -0
  32. data/spec/fixtures/bookmarks_unstar.json +1 -0
  33. data/spec/fixtures/bookmarks_update_read_progress.json +1 -0
  34. data/spec/fixtures/folders_add.json +1 -0
  35. data/spec/fixtures/folders_delete.json +1 -0
  36. data/spec/fixtures/folders_list.json +1 -0
  37. data/spec/fixtures/folders_set_order.json +1 -0
  38. data/spec/fixtures/verify_credentials.json +1 -0
  39. data/spec/instapaper/client/account_spec.rb +27 -0
  40. data/spec/instapaper/client/bookmark_spec.rb +234 -0
  41. data/spec/instapaper/client/folder_spec.rb +89 -0
  42. data/spec/instapaper/client/user_spec.rb +28 -0
  43. data/spec/instapaper/client_spec.rb +65 -0
  44. data/spec/instapaper_spec.rb +85 -0
  45. data/spec/spec_helper.rb +44 -0
  46. metadata +230 -99
  47. data/History.txt +0 -3
  48. data/Manifest.txt +0 -43
  49. data/README.rdoc +0 -73
  50. data/config/hoe.rb +0 -73
  51. data/config/requirements.rb +0 -15
  52. data/lib/instapaper/base.rb +0 -113
  53. data/lib/instapaper/constants.rb +0 -37
  54. data/lib/instapaper/exceptions.rb +0 -41
  55. data/lib/instapaper/protocol.rb +0 -47
  56. data/lib/instapaper/request/abstract_request.rb +0 -104
  57. data/lib/instapaper/request/add_url_request.rb +0 -68
  58. data/lib/instapaper/request/authentication_request.rb +0 -60
  59. data/lib/instapaper/request/request_error.rb +0 -34
  60. data/lib/instapaper/request/request_errors.rb +0 -41
  61. data/lib/instapaper/request/request_validation.rb +0 -34
  62. data/lib/instapaper/response.rb +0 -10
  63. data/lib/instapaper/response/abstract_response.rb +0 -38
  64. data/lib/instapaper/response/add_url_success_response.rb +0 -41
  65. data/lib/instapaper/response/authentication_invalid_response.rb +0 -40
  66. data/lib/instapaper/response/authentication_success_response.rb +0 -40
  67. data/lib/instapaper/response/bad_request_response.rb +0 -40
  68. data/lib/instapaper/response/response_builder.rb +0 -61
  69. data/lib/instapaper/response/service_error_response.rb +0 -40
  70. data/script/console +0 -10
  71. data/script/destroy +0 -14
  72. data/script/generate +0 -14
  73. data/script/txt2html +0 -82
  74. data/setup.rb +0 -1585
  75. data/tasks/deployment.rake +0 -34
  76. data/tasks/environment.rake +0 -7
  77. data/tasks/website.rake +0 -17
  78. data/test/test_auth.rb +0 -62
  79. data/test/test_error.rb +0 -81
  80. data/test/test_helper.rb +0 -2
  81. data/test/test_instapaper.rb +0 -9
  82. data/test/test_request.rb +0 -45
  83. data/website/index.html +0 -99
  84. data/website/index.txt +0 -69
  85. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  86. data/website/stylesheets/screen.css +0 -138
  87. data/website/template.html.erb +0 -48
@@ -1,3 +0,0 @@
1
- == 0.1.0 2009-02-17
2
-
3
- Initial Release
@@ -1,43 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- PostInstall.txt
4
- README.rdoc
5
- Rakefile
6
- config/hoe.rb
7
- config/requirements.rb
8
- lib/instapaper.rb
9
- lib/instapaper/base.rb
10
- lib/instapaper/constants.rb
11
- lib/instapaper/exceptions.rb
12
- lib/instapaper/protocol.rb
13
- lib/instapaper/request.rb
14
- lib/instapaper/request/abstract_request.rb
15
- lib/instapaper/request/add_url_request.rb
16
- lib/instapaper/request/authentication_request.rb
17
- lib/instapaper/request/request_error.rb
18
- lib/instapaper/request/request_errors.rb
19
- lib/instapaper/request/request_validation.rb
20
- lib/instapaper/response.rb
21
- lib/instapaper/response/abstract_response.rb
22
- lib/instapaper/response/add_url_success_response.rb
23
- lib/instapaper/response/authentication_invalid_response.rb
24
- lib/instapaper/response/authentication_success_response.rb
25
- lib/instapaper/response/bad_request_response.rb
26
- lib/instapaper/response/response_builder.rb
27
- lib/instapaper/response/service_error_response.rb
28
- lib/instapaper/version.rb
29
- script/console
30
- script/destroy
31
- script/generate
32
- script/txt2html
33
- setup.rb
34
- tasks/deployment.rake
35
- tasks/environment.rake
36
- tasks/website.rake
37
- test/test_helper.rb
38
- test/test_instapaper.rb
39
- website/index.html
40
- website/index.txt
41
- website/javascripts/rounded_corners_lite.inc.js
42
- website/stylesheets/screen.css
43
- website/template.html.erb
@@ -1,73 +0,0 @@
1
- = instapaper
2
-
3
- * http://instapaper.rubyforge.org
4
-
5
- == DESCRIPTION:
6
-
7
- The instapaper gem provides a neat interface to the Instapaper API.
8
-
9
- == SYNOPSIS:
10
-
11
- # "password" is optional
12
- base = Instapaper::Base.new("username","password")
13
-
14
- # Test authentication (not required to add url)
15
- result = base.authenticate
16
- # => Instapaper::Response::AuthenticationSuccessResponse
17
-
18
- result.code # => 200
19
-
20
- # Add URL
21
- result = base.add("http://example.org/some-article.html")
22
- # => Instapaper::Response::AddURLSuccess
23
-
24
- result.code # => 200
25
-
26
- # Bad Auth
27
- base = Instapaper::Base.new("baduser","badpass")
28
- result = base.authenticate
29
- # => Instapaper::Response::AuthenticationInvalidResponse
30
-
31
- result.code # => 403
32
-
33
- # Advanced usage
34
- base = Instapaper::Base.new("username","password")
35
- options = {:url => "http://example.org/some-article.html", :title => "MyArticle"}
36
- request = AddURLRequest.new(options,"username","password")
37
-
38
- base.secure? # => true (as default)
39
-
40
- base.use_clear_protocol!
41
- # => connection will now use HTTP instead of HTTPS
42
-
43
- response = base.send_request(request)
44
-
45
-
46
- == INSTALL:
47
-
48
- * sudo gem install instapaper
49
-
50
- == LICENSE:
51
-
52
- (The MIT License)
53
-
54
- Copyright (c) 2009 FIXME full name
55
-
56
- Permission is hereby granted, free of charge, to any person obtaining
57
- a copy of this software and associated documentation files (the
58
- 'Software'), to deal in the Software without restriction, including
59
- without limitation the rights to use, copy, modify, merge, publish,
60
- distribute, sublicense, and/or sell copies of the Software, and to
61
- permit persons to whom the Software is furnished to do so, subject to
62
- the following conditions:
63
-
64
- The above copyright notice and this permission notice shall be
65
- included in all copies or substantial portions of the Software.
66
-
67
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
68
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
69
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
70
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
71
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
72
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
73
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,73 +0,0 @@
1
- require 'instapaper/version'
2
-
3
- AUTHOR = 'Douglas Willcocks' # can also be an array of Authors
4
- EMAIL = "douglas.willcocks@gmail.com"
5
- DESCRIPTION = "A simple wrapper for the Instapaper API"
6
- GEM_NAME = 'instapaper' # what ppl will type to install your gem
7
- RUBYFORGE_PROJECT = 'instapaper' # The unix name for your project
8
- HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
- DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
- EXTRA_DEPENDENCIES = [
11
- # ['activesupport', '>= 1.3.1']
12
- ] # An array of rubygem dependencies [name, version]
13
-
14
- @config_file = "~/.rubyforge/user-config.yml"
15
- @config = nil
16
- RUBYFORGE_USERNAME = "unknown"
17
- def rubyforge_username
18
- unless @config
19
- begin
20
- @config = YAML.load(File.read(File.expand_path(@config_file)))
21
- rescue
22
- puts <<-EOS
23
- ERROR: No rubyforge config file found: #{@config_file}
24
- Run 'rubyforge setup' to prepare your env for access to Rubyforge
25
- - See http://newgem.rubyforge.org/rubyforge.html for more details
26
- EOS
27
- exit
28
- end
29
- end
30
- RUBYFORGE_USERNAME.replace @config["username"]
31
- end
32
-
33
-
34
- REV = nil
35
- # UNCOMMENT IF REQUIRED:
36
- # REV = YAML.load(`svn info`)['Revision']
37
- VERS = Instapaper::VERSION::STRING + (REV ? ".#{REV}" : "")
38
- RDOC_OPTS = ['--quiet', '--title', 'instapaper documentation',
39
- "--opname", "index.html",
40
- "--line-numbers",
41
- "--main", "README",
42
- "--inline-source"]
43
-
44
- class Hoe
45
- def extra_deps
46
- @extra_deps.reject! { |x| Array(x).first == 'hoe' }
47
- @extra_deps
48
- end
49
- end
50
-
51
- # Generate all the Rake tasks
52
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
53
- $hoe = Hoe.new(GEM_NAME, VERS) do |p|
54
- p.developer(AUTHOR, EMAIL)
55
- p.description = DESCRIPTION
56
- p.summary = DESCRIPTION
57
- p.url = HOMEPATH
58
- p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
59
- p.test_globs = ["test/**/test_*.rb"]
60
- p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
61
-
62
- # == Optional
63
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
64
- #p.extra_deps = EXTRA_DEPENDENCIES
65
-
66
- #p.spec_extras = {} # A hash of extra values to set in the gemspec.
67
- end
68
-
69
- CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
- PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
- $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
- $hoe.rsync_args = '-av --delete --ignore-errors'
73
- $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -1,15 +0,0 @@
1
- require 'fileutils'
2
- include FileUtils
3
-
4
- require 'rubygems'
5
- %w[rake hoe newgem rubigen].each do |req_gem|
6
- begin
7
- require req_gem
8
- rescue LoadError
9
- puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
- puts "Installation: gem install #{req_gem} -y"
11
- exit
12
- end
13
- end
14
-
15
- $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
@@ -1,113 +0,0 @@
1
- # Copyright (c) 2009 Douglas Willcocks
2
- #
3
- # Permission is hereby granted, free of charge, to any person
4
- # obtaining a copy of this software and associated documentation
5
- # files (the "Software"), to deal in the Software without
6
- # restriction, including without limitation the rights to use,
7
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the
9
- # Software is furnished to do so, subject to the following
10
- # conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- # OTHER DEALINGS IN THE SOFTWARE.
23
-
24
-
25
- # Provide a simple wrapper interface to Instapaper
26
-
27
- require 'net/http'
28
- require 'net/https'
29
- require 'uri'
30
-
31
- module Instapaper
32
- class Base
33
-
34
- include Protocol
35
- include Constants
36
- include Request
37
- include Response
38
- include Exceptions
39
-
40
- # Instatiate a new Instapaper object that will act as the adaptor the Instapaper
41
- # API.
42
- #
43
- # Usernames are mandatory, but passwords are optional as on Instapaper
44
- def initialize(username, password = nil)
45
- @username = username
46
- @password = password
47
- @protocol = PROTOCOLS[:secure]
48
- end
49
-
50
- # Add a URL to Instapaper
51
- #
52
- # See Base#get_add_request
53
- def add(url_data, options = {})
54
- req = get_add_request(url_data,options)
55
-
56
- return send_request(req)
57
- end
58
-
59
- # Create a request to add a URL to instapaper
60
- #
61
- # Takes a hash of options:
62
- #
63
- # :title
64
- # plain text, no HTML, UTF-8
65
- # :selection
66
- # plain text, no HTML, UTF-8
67
- # :auto_title
68
- # Replaces title. Instapaper will crawl the URL to detect a title.
69
- # Use this if you do not know a title for the URL, such as when it’s an
70
- # inline link somewhere that hasn’t been opened.
71
- # Defaults to 1
72
- #
73
- def get_add_request(url_data, options = {})
74
-
75
- raise InvalidRequestDetailsException unless options.is_a?(Hash)
76
-
77
- options[:url] = url_data
78
- AddURLRequest.new(options,@username,@password)
79
- end
80
-
81
- # Test the authentication credentials
82
- def authenticate
83
- req = AuthenticationRequest.new(@username,@password)
84
-
85
- return send_request(req)
86
- end
87
-
88
- # Do the actual communication with the server
89
- def send_request(request)
90
-
91
- request.use_clear_protocol! unless secure?
92
- request.prepare
93
-
94
- url = URI.parse(request.url)
95
- req = Net::HTTP::Post.new(url.path)
96
-
97
- req.set_form_data(request.post_data)
98
-
99
- http = Net::HTTP.new(url.host,url.port)
100
-
101
- http.use_ssl = secure?
102
-
103
- # Instapaper triggers an invalid SSL, so there's no way of telling
104
- # if it's being spoofed. May as well just turn off warnings.
105
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
106
-
107
- res = http.request(req)
108
-
109
- return ResponseBuilder.build(res,request)
110
- end
111
-
112
- end
113
- end
@@ -1,37 +0,0 @@
1
- # Copyright (c) 2009 Douglas Willcocks
2
- #
3
- # Permission is hereby granted, free of charge, to any person
4
- # obtaining a copy of this software and associated documentation
5
- # files (the "Software"), to deal in the Software without
6
- # restriction, including without limitation the rights to use,
7
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the
9
- # Software is furnished to do so, subject to the following
10
- # conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- # OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- # Various constants
25
-
26
- module Instapaper
27
- module Constants #:nodoc: all
28
-
29
- PROTOCOLS = {:clear => "http", :secure => "https"}.freeze
30
- HOST = "instapaper.com"
31
- API_BASE = "api"
32
-
33
- API_AUTH = "authenticate"
34
- API_ADD = "add"
35
-
36
- end
37
- end
@@ -1,41 +0,0 @@
1
- # Copyright (c) 2009 Douglas Willcocks
2
- #
3
- # Permission is hereby granted, free of charge, to any person
4
- # obtaining a copy of this software and associated documentation
5
- # files (the "Software"), to deal in the Software without
6
- # restriction, including without limitation the rights to use,
7
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the
9
- # Software is furnished to do so, subject to the following
10
- # conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- # OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- # Errors thrown
25
-
26
- module Instapaper
27
- module Exceptions
28
-
29
- class InstapaperException < Exception; end #:nodoc:
30
-
31
- # Thrown when the request object was built with incomplete data
32
- class InvalidRequestDetailsException < InstapaperException; end
33
-
34
- # Thrown when trying to use an abstract request as an actual request
35
- class AbstractRequestException < InstapaperException; end
36
-
37
- # Thrown when the server returns a response code we don't know how to handle
38
- class UnrecognisedResponseCodeException < InstapaperException; end
39
-
40
- end
41
- end
@@ -1,47 +0,0 @@
1
- # Copyright (c) 2009 Douglas Willcocks
2
- #
3
- # Permission is hereby granted, free of charge, to any person
4
- # obtaining a copy of this software and associated documentation
5
- # files (the "Software"), to deal in the Software without
6
- # restriction, including without limitation the rights to use,
7
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the
9
- # Software is furnished to do so, subject to the following
10
- # conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- # OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- module Instapaper
25
-
26
- module Protocol
27
-
28
- include Constants
29
-
30
- # Make the request using HTTPS (default)
31
- def use_secure_protocol!
32
- @protocol = PROTOCOLS[:secure]
33
- end
34
-
35
- # Make the request using HTTP (username/password passed in clear)
36
- def use_clear_protocol!
37
- @protocol = PROTOCOLS[:clear]
38
- end
39
-
40
- # Are we using HTTPS?
41
- def secure?
42
- @protocol == PROTOCOLS[:secure]
43
- end
44
-
45
- end
46
-
47
- end