Last active
October 25, 2016 16:24
-
-
Save RobertKim/5fb95d9bddc3d3e63214247d468ff286 to your computer and use it in GitHub Desktop.
Module used to consume AWR Cloud API (for processing domain name rankings on various search engines)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module RankingsAPI | |
NoDateError = Class.new(StandardError) | |
NoRankingError = Class.new(StandardError) | |
ProjectExistsError = Class.new(StandardError) | |
def self.get_latest_rankings(project, api=nil) | |
api = api || AWRCloud::API.new(project.awr_account.token) | |
project.update got_rankings_at: Time.now | |
date = get_latest_ranking_report_date project, api | |
ranking_data = get_ranking project, date, api | |
simplified_ranking_data = simplify_ranking_data project.domain, project.domain, date, ranking_data | |
end | |
def self.create_project user | |
begin | |
retries ||= 1 | |
project_name = user.domain.sub(/^https?\:\/\//, '').sub(/^www./,'') | |
puts "TRY ##{ retries } OF 5 FOR \'RankingsAPI.create_project\' | '#{project_name}'" | |
website = user.domain.sub(/^https?\:\/\//, '').sub(/^www./,'') | |
keywords = [] | |
10.times do |i| | |
kw = user.send("keyword_#{i+1}") | |
kw.if true: ->{ keywords << kw } | |
end | |
awr_account = AwrAccount.find(5) | |
api = AWRCloud::API.new awr_account.token | |
project = AWRCloud::Project.new project_name.sub(/^https?\:\/\//, '').sub(/^www./,'') | |
project.frequency = "monthly" | |
project.websites.add name: website, aliases: create_website_alias(website) | |
project.search_engines.add awr_id: "1481189791" #bing | |
project.search_engines.add awr_id: "2138589785" #google | |
project.search_engines.add awr_id: "85186592" #yahoo | |
keywords.each{|keyword| project.keywords.add(name: keyword)} | |
api.create_project project | |
p = Project.where(domain: website.sub(/^https?\:\/\//, '').sub(/^www./,'')).first_or_create | |
p.update(awr_account_id: awr_account.id) | |
rescue => e | |
puts "Exception => #{e} ... retrying '#{project_name}'" | |
puts "#{Time.now} | First attempt creating project for #{project_name} unsuccessful for #{project_name}." | |
sleep 45 | |
retry if (retries +=1) < 3 | |
ensure | |
log_api_call "create_project" | |
end | |
}, ->{ | |
exit | |
end | |
def self.get_latest_ranking_report_date project, api | |
log_api_call "get_dates" | |
project.update got_dates_at: Time.now | |
date = api.get_dates(project.domain)["dates"][-1]["date"] | |
date | |
rescue NoMethodError, JSON::ParserError | |
raise NoDateError.new "Could not get a ranking report date from response." | |
end | |
def self.get_ranking project, date, api | |
log_api_call "get_ranking" | |
project.update got_rankings_at: Time.now | |
api.get_ranking(project.domain, date) | |
rescue | |
raise NoRankingError.new "Ranking could not be retrieved from AWRCloud with the given project name and date." | |
end | |
private | |
def self.simplify_ranking_data project_name, domain, date, response | |
response.map{|segment| extract_valuable_ranking_data(project_name, domain, date, segment)}.reject{|segment| segment.nil?} | |
end | |
def self.extract_valuable_ranking_data project_name, domain, date, segment | |
output = {"date" => nil, "search_engine" => nil, "keyword" => nil, "keyword_group" => nil, "website" => nil, "url" => nil, "position" => nil, "best" => nil, "competition" => nil, "average" => nil, "cpc" => nil, "page" => nil, "ranking_type" => nil} | |
rank = segment["rankdata"].select{|rank| rank["url"].include?(domain)}.first | |
output["date"] = date | |
output["search_engine"] = segment["searchengine"].try{|y|y.ascii_only!} | |
output["keyword"] = segment["keyword"].try{|y|y.ascii_only!} | |
output["website"] = domain.try{|y|y.ascii_only!} | |
output["url"] = rank.try{|x|x["url"]}.try{|y|y.ascii_only!} | |
output["position"] = rank.try{|y|y["position"]} | |
output["page"] = rank.try{|z|z["page"]} | |
output["ranking_type"] = rank.try{|w|w["type"]} | |
output | |
end | |
def self.create_website_alias domain | |
"*.#{domain}" | |
end | |
def self.log_api_call name | |
AwrcloudApiCall.create method: name | |
end | |
def self.make_call_when_ready &block | |
sleep 1.minute until AwrcloudApiCall.free_api_calls? | |
yield | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment