Create Tumblr Likes Agent (#1923)

* Create Tumblr Likes Agent

* Don't interpolate options

* Clear ID memory after 50 entries

In order to prevent the ID array from getting to large, keep only the
last 50 entries. 50 is currently the maximum the API will return at a
time, so we should never exceed that limit.

* Request likes after the last recorded like

Instead of just returning blog likes, request only likes after the
timestamp of the last liked item we’ve processed.
This commit is contained in:
Zack Fernandes 2017-04-07 16:27:24 -07:00 committed by Andrew Cantino
parent be0d0417bd
commit f21d6abaee
3 changed files with 111 additions and 0 deletions

View file

@ -0,0 +1,65 @@
module Agents
class TumblrLikesAgent < Agent
include TumblrConcern
gem_dependency_check { defined?(Tumblr::Client) }
description <<-MD
The Tumblr Likes Agent checks for liked Tumblr posts from a specific blog.
#{'## Include `tumblr_client` and `omniauth-tumblr` in your Gemfile to use this Agent!' if dependencies_missing?}
To be able to use this Agent you need to authenticate with Tumblr in the [Services](/services) section first.
**Required fields:**
`blog_name` The Tumblr URL you're querying (e.g. "staff.tumblr.com")
Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
MD
default_schedule 'every_1h'
def validate_options
errors.add(:base, 'blog_name is required') unless options['blog_name'].present?
errors.add(:base, 'expected_update_period_in_days is required') unless options['expected_update_period_in_days'].present?
end
def working?
event_created_within?(options['expected_update_period_in_days']) && !recent_error_logs?
end
def default_options
{
'expected_update_period_in_days' => '10',
'blog_name' => 'someblog',
}
end
def check
memory[:ids] ||= []
memory[:last_liked] ||= 0
# Request Likes of blog_name after the last stored timestamp (or default of 0)
liked = tumblr.blog_likes(options['blog_name'], after: memory[:last_liked])
if liked['liked_posts']
# Loop over all liked posts which came back from Tumblr, add to memory, and create events.
liked['liked_posts'].each do |post|
unless memory[:ids].include?(post['id'])
memory[:ids].push(post['id'])
memory[:last_liked] = post['liked_timestamp'] if post['liked_timestamp'] > memory[:last_liked]
create_event(payload: post)
end
end
elsif liked['status'] && liked['msg']
# If there was a problem fetching likes (like 403 Forbidden or 404 Not Found) create an error message.
error "Error finding liked posts for #{options['blog_name']}: #{liked['status']} #{liked['msg']}"
end
# Store only the last 50 (maximum the API will return) IDs in memory to prevent performance issues.
memory[:ids] = memory[:ids].last(50) if memory[:ids].length > 50
end
end
end

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,45 @@
require 'rails_helper'
describe Agents::TumblrLikesAgent do
before do
stub.any_instance_of(Agents::TumblrLikesAgent).tumblr {
obj = Object.new
stub(obj).blog_likes('wendys.tumblr.com', after: 0) {
JSON.parse File.read(Rails.root.join('spec/data_fixtures/tumblr_likes.json'))
}
stub(obj).blog_likes('notfound.tumblr.com', after: 0) { { 'status' => 404, 'msg' => 'Not Found' } }
}
end
describe 'a blog which returns likes' do
before do
@agent = Agents::TumblrLikesAgent.new(name: "Wendy's Tumblr Likes", options: {
blog_name: 'wendys.tumblr.com',
expected_update_period_in_days: 10
})
@agent.service = services(:generic)
@agent.user = users(:bob)
@agent.save!
end
it 'creates events based on likes' do
expect { @agent.check }.to change { Event.count }.by(20)
end
end
describe 'a blog which returns an error' do
before do
@broken_agent = Agents::TumblrLikesAgent.new(name: "Fake Blog Likes", options: {
blog_name: 'notfound.tumblr.com',
expected_update_period_in_days: 10
})
@broken_agent.user = users(:bob)
@broken_agent.service = services(:generic)
@broken_agent.save!
end
it 'creates an error message when status and msg are returned instead of liked_posts' do
expect { @broken_agent.check }.to change { @broken_agent.logs.count }.by(1)
end
end
end