Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Adler committed Aug 21, 2014
0 parents commit 56a5709
Show file tree
Hide file tree
Showing 17 changed files with 444 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--color
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source "https://rubygems.org"
gemspec
32 changes: 32 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
PATH
remote: .
specs:
filter8 (0.1)
faraday

GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.5)
faraday (0.9.0)
multipart-post (>= 1.2, < 3)
multipart-post (2.0.0)
rake (10.1.1)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.8)
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.6)
timecop (0.6.3)

PLATFORMS
ruby

DEPENDENCIES
filter8!
rake (~> 10.1.0)
rspec (~> 2.14.1)
timecop
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require "bundler"
require 'rspec/core/rake_task'

task :default => :spec

Bundler::GemHelper.install_tasks
RSpec::Core::RakeTask.new :spec
27 changes: 27 additions & 0 deletions filter8.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Gem::Specification.new do |s|
s.name = "filter8"
s.version = "0.1"
s.default_executable = "hola"

s.authors = ["Tim Adler"]
s.date = %q{2014-08-19}
s.description = %q{A ruby wrapper for Filter8 (http://filter8.com). An API to filter lots of stuff from texts, e.g. bad words.}
s.summary = %q{A ruby wrapper for Filter8 (http://filter8.com). An API to filter lots of stuff from texts, e.g. bad words.}
s.email = %q{[email protected]}
s.license = "MIT"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.homepage = %q{http://rubygems.org/gems/filter8}
s.require_paths = ["lib"]
s.rubygems_version = %q{1.6.2}
s.summary = %q{Filter8!}

s.add_dependency 'faraday'

s.add_development_dependency 'rake', '~> 10.1.0'
s.add_development_dependency 'rspec', '~> 2.14.1'
s.add_development_dependency 'timecop'

end

5 changes: 5 additions & 0 deletions lib/filter8.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require "filter8/filter8"
require "filter8/exception"
require "filter8/client"
require "filter8/response"
require "filter8/request"
44 changes: 44 additions & 0 deletions lib/filter8/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'digest'
require 'uri'
require 'faraday'
require 'json'

module Filter8
class Client
attr_accessor :api_key, :api_secret

API_URL = 'https://api.filter8.com'
API_ENDPOINT = '/content/item.js'

def initialize(api_key: nil, api_secret: nil, options: {})
@api_key = api_key
@api_secret = api_secret
@options = options
end

def send_request(filter8_request)
conn = Faraday.new(:url => API_URL) do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end

conn.basic_auth self.api_key, password

response = conn.post "#{API_ENDPOINT}?#{nonce_param}", filter8_request.request_params
JSON.parse response.body
end

def nonce_param
"nonce=#{timestamp}"
end

def password
Digest::MD5.hexdigest("#{timestamp}#{self.api_secret}")
end

def timestamp
@timestamp ||= Time.now.to_i.to_s
end
end
end
5 changes: 5 additions & 0 deletions lib/filter8/exception.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Filter8
class Exception < StandardError

end
end
12 changes: 12 additions & 0 deletions lib/filter8/filter8.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Filter8
class Filter8
BLACKLIST_FILTER = :blacklist

AVAILABLE_FILTERS = [BLACKLIST_FILTER]

FILTER_PARAMS = {
BLACKLIST_FILTER => [:locale, :tags, :severity]
}

end
end
67 changes: 67 additions & 0 deletions lib/filter8/request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module Filter8
class Request
attr_accessor :content
attr_accessor :blacklist

def initialize(content = nil, options = {})
@content = content
options.each do |filter_name, filter_options|
validate_filter_options(filter_name, filter_options)

instance_variable_value = nil
if filter_options.is_a? Hash
instance_variable_value = { enabled: true }
instance_variable_value = instance_variable_value.merge(filter_options)
else
instance_variable_value = filter_options
end
instance_variable_set("@#{filter_name}", instance_variable_value)
end
end

def request_params
request_params = "content=#{self.content}"

Filter8::AVAILABLE_FILTERS.each do |filter_name|
if self.respond_to?(filter_name) && !self.send(filter_name).nil?
request_params = request_params + "&" + filter_options_to_params(filter_name)
end
end

request_params
end

private

def filter_options_to_params(filter_name)
params = []

filter_options = self.send(filter_name)
if filter_options.is_a? Hash
filter_options.each do |filter_option, filter_option_value|
if filter_option_value.respond_to? :each
filter_option_value.each do |value|
params << "#{filter_name}.#{filter_option}=#{value}"
end
else
params << "#{filter_name}.#{filter_option}=#{filter_option_value}"
end
end
else
params << "#{filter_name}=#{filter_options}"
end

return params.join("&")
end

def validate_filter_options(filter_name, filter_options)
raise Exception.new("'#{filter_name}' is not a valid filter8-filter") unless Filter8::AVAILABLE_FILTERS.include?(filter_name)

if filter_options.respond_to? :each
filter_options.each do |filter_option, filter_option_value|
raise Exception.new("'#{filter_option}' is not a valid option for filter '#{filter_name}'") unless Filter8::FILTER_PARAMS[filter_name].include?(filter_option)
end
end
end
end
end
11 changes: 11 additions & 0 deletions lib/filter8/response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Filter8
class Response
def initialize(json)
@json = json
end

def replacement
@json["filter"]["replacement"]
end
end
end
75 changes: 75 additions & 0 deletions spec/lib/filter8/client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require 'spec_helper'

describe Filter8::Client do

before do
Timecop.freeze(Time.local(2014, 1, 1))
end

let(:client) {Filter8::Client.new(api_key: "12345", api_secret: "abcde")}

describe "#initialization" do
it "will configure a new client with the given parameters" do
expect(client.api_key).to eq "12345"
expect(client.api_secret).to eq "abcde"
end
end

describe "#send_request" do
let(:faraday_response) {double("Faraday::Response", body: { "test" => "response" }.to_json)}
let(:faraday_connection) {double("Faraday::Connection", basic_auth: nil, post: faraday_response)}
let(:filter8_request) {double("Filter8::Request", request_params: { "test" => "data" })}

before do
Faraday.stub(:new).and_return(faraday_connection)
end

it "will correctly configure a new farady-connection to the filter8-server" do
expect(Faraday).to receive(:new).with(:url => 'https://api.filter8.com').and_return(faraday_connection)
client.send_request(filter8_request)
end

it "will use basic-auth with the api_key and the calculated password" do
expect(faraday_connection).to receive(:basic_auth).with(client.api_key, client.password)
client.send_request(filter8_request)
end

it "will send the given filter8_requests form-data via post" do
expect(faraday_connection).to receive(:post).with("/content/item.js?#{client.nonce_param}", filter8_request.request_params)
client.send_request(filter8_request)
end

it "will parse the response as JSON and return the result" do
expect(client.send_request(filter8_request)).to eq({ "test" => "response" })
end

end

describe "#timestamp" do
it "will return the current Time as a unix-timestamp" do
expect(client.timestamp).to eq Time.local(2014, 1, 1).to_i.to_s
end

it "will return the same value every time it is asked" do
Timecop.return

timestamp = client.timestamp
sleep 1.0/4

expect(client.timestamp).to eq timestamp
end
end

describe "#password" do
it "will return a md5-digested combination of nonce and api_secret" do
expect(client.password).to eq Digest::MD5.hexdigest("#{client.timestamp}#{client.api_secret}")
end
end

describe "#nonce_param" do
it "will return the nonce-param with the clients timestamp" do
expect(client.nonce_param).to eq "nonce=#{client.timestamp}"
end
end

end
7 changes: 7 additions & 0 deletions spec/lib/filter8/filter8_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'spec_helper'

describe Filter8::Filter8 do

pending "write it"

end
48 changes: 48 additions & 0 deletions spec/lib/filter8/request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require 'spec_helper'

describe Filter8::Request do

describe "#initialization" do
it "will configure a new request with no options" do
expect(Filter8::Request.new("fuck")).to be_a Filter8::Request
end

it "will allow valid filters as options" do
request = Filter8::Request.new("fuck", blacklist: "test")
expect(request.blacklist).to eq "test"
end

it "will NOT allow invalid filters as options" do
expect{Filter8::Request.new("fuck", some_filter: "test")}.to raise_error(Filter8::Exception)
end

it "will allow valid filters with valid options" do
request = Filter8::Request.new("fuck", blacklist: {locale: [:en, :de]})

expect(request.blacklist).to eq({enabled: true, locale: [:en, :de]})
end

it "will NOT allow valid filters with invalid options" do
expect{Filter8::Request.new("fuck", blacklist: {myarg: "test"})}.to raise_error(Filter8::Exception)
end
end

describe "#request_params" do
it "will return the correct parameters, when no options are given" do
expect(Filter8::Request.new("fuck").request_params).to eq "content=fuck"
end

it "will return the correct parameters, when one option with a single value is given" do
expect(Filter8::Request.new("fuck", blacklist: "test").request_params).to eq "content=fuck&blacklist=test"
end

it "will return the correct parameters, when one option with a hash is given" do
expect(Filter8::Request.new("fuck", blacklist: {locale: :en}).request_params).to eq "content=fuck&blacklist.enabled=true&blacklist.locale=en"
end

it "will return the correct parameters, when one option with a multiple value is given" do
expect(Filter8::Request.new("fuck", blacklist: {locale: [:en, :de]}).request_params).to eq "content=fuck&blacklist.enabled=true&blacklist.locale=en&blacklist.locale=de"
end
end

end
Loading

0 comments on commit 56a5709

Please sign in to comment.