plagiarism 0.0.0 → 0.1.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.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/LICENSE.txt +20 -0
- data/README.md +78 -0
- data/lib/plagiarism.rb +72 -0
- data/lib/plagiarism/balance.rb +35 -0
- data/lib/plagiarism/request.rb +38 -0
- data/lib/plagiarism/response.rb +25 -0
- data/lib/plagiarism/search.rb +76 -0
- data/lib/plagiarism/text_search.rb +20 -0
- data/lib/plagiarism/url_search.rb +21 -0
- data/plagiarism.gemspec +23 -11
- data/spec/plagiarism/balance_spec.rb +39 -0
- data/spec/plagiarism/plagiarism_spec.rb +7 -0
- data/spec/plagiarism/text_search_spec.rb +52 -0
- data/spec/plagiarism/url_search_spec.rb +54 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/vcr_cassettes/successful_balance_request.yml +37 -0
- data/spec/vcr_cassettes/valid_text_search_with_results.yml +7948 -0
- data/spec/vcr_cassettes/valid_url_search_with_results.yml +7950 -0
- metadata +131 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ade6a7ba134174de6ea534c5af530e9c217fe64
|
4
|
+
data.tar.gz: 76be3b73bd7c18fb59faafa37165e9a123150f61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e69458e5af8d77b6b6d06b7098c587f8941655c59d6eb568ada3919b7bd6e8e0960db6cafcedf45fdad3dea71191a8f0031e85eed072f1a22d1a4329bac4c819
|
7
|
+
data.tar.gz: d65947e99d90ac5fcc892eca6b622603404c64d9edd41a255254c3ae98c7ef2006fe33ee2804952f8e43a7427eee33b218453a1c77285065bdec02f9d9972482
|
data/.rspec
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Zach Ohlgren
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
## Plagiarism
|
2
|
+
|
3
|
+
Search for plagiarism and check the originality of your content with Copyscape.
|
4
|
+
|
5
|
+
Plagiarism is a Ruby wrapper for the Copyscape (http://copyscape.com) Premium API.
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
### Getting Started
|
10
|
+
|
11
|
+
|
12
|
+
gem install plagiarism
|
13
|
+
|
14
|
+
require 'plagiarism'
|
15
|
+
|
16
|
+
|
17
|
+
Once you have your Copyscape username and API key you'll need to configure them.
|
18
|
+
|
19
|
+
Plagiarism.username = "username"
|
20
|
+
Plagiarism.api_key = "123456"
|
21
|
+
|
22
|
+
|
23
|
+
You can enable test mode to have Copyscape search against their example page,
|
24
|
+
http://www.copyscape.com/example.html.
|
25
|
+
|
26
|
+
Plagiarism.test_mode = true
|
27
|
+
|
28
|
+
|
29
|
+
### Usage
|
30
|
+
|
31
|
+
|
32
|
+
##### Check a URL for plagiarism
|
33
|
+
|
34
|
+
search = Plagiarism.url_seach("http://example.com")
|
35
|
+
|
36
|
+
if search.results? # => true
|
37
|
+
|
38
|
+
# How many results were found?
|
39
|
+
search.count # => 324
|
40
|
+
|
41
|
+
# Wow! That's a lot of results. Let's take a look...
|
42
|
+
search.results_url # => "http://view.copyscape.com/search/hm2yx3g9kg"
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
##### Check some text for plagiarism
|
49
|
+
|
50
|
+
# Some text to search against (15 words minimum)
|
51
|
+
excerpt = "When in the course of human events, it becomes necessary
|
52
|
+
for one people to dissolve the political bands"
|
53
|
+
|
54
|
+
search = Plagiarism.text_seach(excerpt)
|
55
|
+
|
56
|
+
if search.results? # => true
|
57
|
+
|
58
|
+
# How many results were found?
|
59
|
+
search.count # => 324
|
60
|
+
|
61
|
+
# Wow! That's a lot of results. Let's take a look...
|
62
|
+
search.results_url # => "http://view.copyscape.com/search/hm2yx3g9kg"
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
##### Check your account balance (in cents)
|
69
|
+
|
70
|
+
Plagiarism.balance # => 9900
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
##### Check your remaining search credits
|
75
|
+
|
76
|
+
Plagiarism.credits # => 1980
|
77
|
+
|
78
|
+
|
data/lib/plagiarism.rb
CHANGED
@@ -1,3 +1,75 @@
|
|
1
|
+
require 'plagiarism/request'
|
2
|
+
require 'plagiarism/response'
|
3
|
+
require 'plagiarism/balance'
|
4
|
+
require 'plagiarism/search'
|
5
|
+
require 'plagiarism/url_search'
|
6
|
+
require 'plagiarism/text_search'
|
7
|
+
|
1
8
|
module Plagiarism
|
2
9
|
|
10
|
+
@test_mode = false
|
11
|
+
@response_format = :xml
|
12
|
+
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
attr_reader :response_format
|
17
|
+
attr_accessor :username, :api_key, :test_mode
|
18
|
+
|
19
|
+
def configure
|
20
|
+
yield self
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# Return the current balance (in cents) in your Copyscape account
|
26
|
+
#
|
27
|
+
def balance
|
28
|
+
Balance.amount
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# Return the number remaining credits in your Copyscape account
|
33
|
+
#
|
34
|
+
def credits
|
35
|
+
Balance.credits
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Search for copies of some text
|
40
|
+
#
|
41
|
+
# Options:
|
42
|
+
#
|
43
|
+
# encoding:
|
44
|
+
# UTF-8, ISO-8859-1, etc. (default is UTF-8)
|
45
|
+
#
|
46
|
+
# scope:
|
47
|
+
# public, private, full (default is public)
|
48
|
+
#
|
49
|
+
# full_comparisons:
|
50
|
+
# number of full-text comparisons to request on matching
|
51
|
+
# results (default is 0, maximum is 10).
|
52
|
+
#
|
53
|
+
def text_search(text, options = {})
|
54
|
+
TextSearch.new(text, options)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Search for copies of a web page
|
59
|
+
#
|
60
|
+
# Options:
|
61
|
+
#
|
62
|
+
# scope:
|
63
|
+
# public, private, full (default is public)
|
64
|
+
#
|
65
|
+
# full_comparisons:
|
66
|
+
# number of full-text comparisons to request on matching
|
67
|
+
# results (default is 0, maximum is 10).
|
68
|
+
#
|
69
|
+
def url_search(url, options = {})
|
70
|
+
URLSearch.new(url, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
3
75
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'money'
|
2
|
+
|
3
|
+
module Plagiarism
|
4
|
+
class Balance < Request
|
5
|
+
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Return the amount (in cents) of your remaining Copyscape account balance
|
10
|
+
#
|
11
|
+
def amount
|
12
|
+
response = Request.new(:get, o: 'balance').response
|
13
|
+
if response.success?
|
14
|
+
Money.parse(response.doc.css('value').text).cents
|
15
|
+
else
|
16
|
+
raise "An error occurred while attempting to retrieve your account balance"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Return search credits remaining for your Copyscape account
|
22
|
+
#
|
23
|
+
def credits
|
24
|
+
response = Request.new(:get, o: 'balance').response
|
25
|
+
if response.success?
|
26
|
+
response.doc.css('total').text.to_i
|
27
|
+
else
|
28
|
+
raise "An error occurred while attempting to retrieve your account balance"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
module Plagiarism
|
4
|
+
class Request
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
base_uri "http://www.copyscape.com/api"
|
8
|
+
|
9
|
+
attr_accessor :response, :params
|
10
|
+
|
11
|
+
def initialize(method, options = {})
|
12
|
+
@params = build_params(options)
|
13
|
+
if method.eql? :get
|
14
|
+
@response = Response.new self.class.get('/', query: @params)
|
15
|
+
elsif method.eql? :post
|
16
|
+
@response = Response.new self.class.post('/', body: @params)
|
17
|
+
else
|
18
|
+
raise "Invalid HTTP request method"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
# Build the request parameters
|
25
|
+
def build_params(options = {})
|
26
|
+
raise "You must provide your Copyscape username" unless Plagiarism.username
|
27
|
+
raise "You must provide your Copyscape API key" unless Plagiarism.api_key
|
28
|
+
params = {
|
29
|
+
u: Plagiarism.username, # Copyscape username
|
30
|
+
k: Plagiarism.api_key, # Copyscape API key
|
31
|
+
f: Plagiarism.response_format, # Response format
|
32
|
+
}.merge(options)
|
33
|
+
params.merge!(x: 1) if Plagiarism.test_mode
|
34
|
+
params
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Plagiarism
|
4
|
+
class Response
|
5
|
+
|
6
|
+
attr_accessor :response, :doc
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(response)
|
10
|
+
@response = response
|
11
|
+
@doc = Nokogiri::XML(response.body) if @response.ok?
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def success?
|
16
|
+
@response.ok? && @doc.css("error").text == ""
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def error?
|
21
|
+
not success?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Plagiarism
|
2
|
+
class Search
|
3
|
+
|
4
|
+
attr_accessor :request, :response
|
5
|
+
|
6
|
+
|
7
|
+
# Return the number of results found
|
8
|
+
#
|
9
|
+
def count
|
10
|
+
@response.success? ? @response.doc.css("count").text.to_i : nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return true if any results were found
|
14
|
+
#
|
15
|
+
def results?
|
16
|
+
count && count > 0 ? true : false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return true if an error occurred
|
20
|
+
#
|
21
|
+
def error?
|
22
|
+
@response && @response.error? ? true : false
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Return true if the search request was successful
|
27
|
+
def success?
|
28
|
+
@response && @response.success? ? true : false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# Return the number of words checked
|
33
|
+
#
|
34
|
+
def words
|
35
|
+
@response.success? ? @response.doc.css("querywords").text.to_i : nil
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# Return the URL for viewing results
|
40
|
+
#
|
41
|
+
def results_url
|
42
|
+
if @response.success? && viewing_url = @response.doc.css("allviewurl").text
|
43
|
+
viewing_url != "" ? viewing_url : nil
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
|
53
|
+
def search_params(options)
|
54
|
+
params = {
|
55
|
+
o: operation_for_scope(options[:scope]),
|
56
|
+
c: options[:full_comparisons] || 0
|
57
|
+
}
|
58
|
+
params.merge(e: options[:encoding]) if self.class == TextSearch
|
59
|
+
params
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Map search scope to an api operation
|
64
|
+
#
|
65
|
+
def operation_for_scope(scope)
|
66
|
+
if scope == "full"
|
67
|
+
"cpsearch"
|
68
|
+
elsif scope == "private"
|
69
|
+
"psearch"
|
70
|
+
else
|
71
|
+
"csearch"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Plagiarism
|
2
|
+
class TextSearch < Search
|
3
|
+
|
4
|
+
def initialize(search_text, options = {})
|
5
|
+
validate_text(search_text)
|
6
|
+
params = {e: "UTF-8", t: search_text}.merge(search_params(options))
|
7
|
+
@request = Request.new(:post, params)
|
8
|
+
@response = @request.response
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
|
15
|
+
def validate_text(text)
|
16
|
+
raise "Invalid search text" if text.class != String || text.nil? || text == ""
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Plagiarism
|
2
|
+
class URLSearch < Search
|
3
|
+
|
4
|
+
def initialize(search_url, options = {})
|
5
|
+
validate_url(search_url)
|
6
|
+
params = search_params(options).merge(q: search_url)
|
7
|
+
@request = Request.new(:get, params)
|
8
|
+
@response = @request.response
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
|
15
|
+
def validate_url(url)
|
16
|
+
uri = URI.parse URI.encode(url)
|
17
|
+
raise "Please provide a valid search URL" unless uri.scheme && uri.host && uri.path
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/plagiarism.gemspec
CHANGED
@@ -1,12 +1,24 @@
|
|
1
|
-
Gem::Specification.new do |
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = 'plagiarism'
|
3
|
+
gem.version = '0.1.0'
|
4
|
+
gem.summary = "A Ruby wrapper for the Copyscape Premium API"
|
5
|
+
gem.description = "Search for plagiarism and check your content for originality with Copyscape"
|
6
|
+
gem.homepage = "https://github.com/zohlgren/plagiarism"
|
7
|
+
gem.authors = ["Zach Ohlgren"]
|
8
|
+
gem.email = "zach@ohlgren.me"
|
9
|
+
gem.license = 'MIT'
|
10
|
+
|
11
|
+
gem.add_dependency 'httparty'
|
12
|
+
gem.add_dependency 'nokogiri'
|
13
|
+
gem.add_dependency 'money'
|
14
|
+
gem.add_development_dependency 'rspec-core'
|
15
|
+
gem.add_development_dependency 'vcr'
|
16
|
+
gem.add_development_dependency 'excon', '>= 0.22.0'
|
17
|
+
gem.add_development_dependency 'webmock', '< 1.12.0'
|
18
|
+
|
19
|
+
|
20
|
+
gem.files = `git ls-files`.split("\n")
|
21
|
+
gem.test_files = gem.files.grep(/^spec/)
|
22
|
+
gem.require_path = "lib"
|
23
|
+
|
12
24
|
end
|