I made this little program in Ruby, it permits to get all my liked videos. But since the maxResult is 50 and i have 1200 videos i need to use the nextPageToken.
But i don't inderstand how to use it in my program.
this is the code :
def playlist_items_list_by_playlist_id(service, part, **params)
params = params.delete_if { |p, v| v == ''}
response = service.list_playlist_items(part, params)
print_results(response)
end
playlist_items_list_by_playlist_id(service, 'snippet',
max_results: 50,
playlist_id: 'LLkyneo6XAv1no1jH33K2Bmg')
I tried to put :pageToken => next_page_tokenbeside the the playlist_id line but it is not working.
Can someone help me ?
Thank you
Related
I have a user, a micropost and a response model.
The user has many microposts and has many responses.
Microposts have tags using the acts as taggable gem.
I need to find the number of responses a user has, to microposts that are tagged with a specific tag. To be clear, for example, how many responses has user 1 given to microposts on "exercise"
There is some basic ruby syntax and relationship logic I am missing. This is what I haev in my user model.
def user_responses_on_topic tag
microposts = self.microposts.tagged_with(tag, :on => :tags)
responses_count = 0
microposts.each do |micropost|
count = micropost.responses.where("user_id = :user_id", user_id: self.id).size
responses_count = responses_count + count
end
end
Its giving me a value but I know its wrong because when I add responses on a particular topic the users value doesn't increase.
I am sure there is a simple "ruby" way to get at this using
responses = user.microposts.responses
But I need to know how to get the tagged logic on microposts into this code
I have tightened it up a bit but still not luck. The individual components of this code work but I can't get the whole thing to work together
def user_responses_on_topic(interest)
microposts = Micropost.tagged_with(interest, :on => :tags, :any => true)
responses ||= 0
microposts.each do |micropost|
responses += micropost.responses.where("user_id = :user_id", user_id: self.id).size
end
end
EDIT:
This works
def user_responses_on_topic(interest)
microposts = Micropost.tagged_with(interest, :on => :tags, :any => true)
count = 0
microposts.each do |micropost|
responses = micropost.responses.size
count = count + responses
end
count
end
But there's got to be a better Rails way (this smells of PHP)
Any ideas?
If all of the components are working independently, it might be as simple as adding a line to the end of your method: responses. After the .each loop executes, it returns the original array (not the value you modified within the loop). Since you want to return the number stored in responses, you want that variable to be the last line of your method.
You should be able to do the count in a single query like this:
microposts.tagged_with(tag, on: :tags).joins(:responses).where(responses: {user_id: id}).count
I'm banging my head trying to understand how the Twitter gem's pagination works.
I've tried max_id and cursor and they both strangely don't work.
Basically the maximum I can get out of search results is 100, and I would like to get 500.
Current code:
max_page = 5
max_id = -1
#data = []
for i in (1..max_page)
t = twt_client.search("hello world", :count => 100, :result_type => :recent, :max_id => max_id)
t.each do | tweet |
#data << tweet
end
max_id = t.next_results[:max_id]
end
This actually tells me that next_results is a private method, anyone has a working solution?
Without knowing which gem you're referencing (please specify a URL), I'd say intiuitively that cursor and max_id wouldn't get you what you want. However count would. Since you say you're only retrieving 100 results and count is set to 100, that would make sense to me.
t = twt_client.search("hello world", :count => 500, :result_type => :recent, :max_id => max_id)
I'm assuming you're talking about the Twitter client referenced here. My first question is: What's twt_client and for that matter, what does its search method return? It's also possible that you've unwittingly updated the gem and there's been a code base change that makes your current script out of date.
Take a look at your installed gem version and another look at the README here.
Twitter::SearchResults#next_results is private, because they try to provide uniform interface for enumeration.
Look, there's included Twitter::Enumerable in search_results.rb
module Twitter
class SearchResults
include Twitter::Enumerable
...
private
def last?
!next_page?
end
...
def fetch_next_page
response = #client.send(#request_method, #path, next_page).body
self.attrs = response
end
...
end
end
And if you look at enumerable.rb, you'll see that method's Twitter::SearchResults#last? and Twitter::SearchResults#fetch_next_page are used by Twitter::SearchResults#each method
module Twitter
module Enumerable
include ::Enumerable
# #return [Enumerator]
def each(start = 0)
return to_enum(:each, start) unless block_given?
Array(#collection[start..-1]).each do |element|
yield(element)
end
unless last?
start = [#collection.size, start].max
fetch_next_page
each(start, &Proc.new)
end
self
end
...
end
end
And Twitter::SearchResults#each will iterate over pages until there's #attrs[:search_metadata][:next_results] in Twitter's responses. So you need to break iteration after you'll reach 500th element.
I think you just need to use each
#data = []
tweet_number = 1
search_results = twt_client.search("hello world", count: 100, result_type: :recent)
search_results.each do |tweet|
#data << tweet
break if tweet_number == 500
end
This post is a result of looking into gem's sources and twitter's api. I could make a mistake somewhere, since I haven't checked my thoughts in console.
Try this (I basically only updated the calculation of the max_id in the loop):
max_page = 5
max_id = -1
#data = []
for i in (1..max_page)
t = twt_client.search("hello world", :count => 100, :result_type => :recent, :max_id => max_id)
t.each do | tweet |
#data << tweet
end
max_id = t.to_a.map(&:id).max + 1 # or may be max_id = t.map(&:id).max + 1
end
I am wondering if there's a more elegant way to say this in Ruby:
FREE_PLAN_MAXIMUM = 1
BASIC_PLAN_MAXIMUM = 10
PREMIUM_PLAN_MAXIMUM = 100
def maximum_entries_per_month
case plan
when "premium"
PREMIUM_PLAN_MAXIMUM
when "basic"
BASIC_PLAN_MAXIMUM
else
FREE_PLAN_MAXIMUM
end
end
I don't like the repetition of premium and basic inside the function. What might be an alternative?
It depends on the rest of your code, especially whether you're using those constants in other places. One pattern I've found nice for this kind of thing is a hash, though.
PLAN_MAXIMUMS = { free: 1, basic: 10, premium: 100 }
def maximum_entries_per_month
PLAN_MAXIMUMS[plan.to_sym] || PLAN_MAXIMUMS[:free]
end
Use Hash#fetch, which allows for a default value, instead of a case statement.
PLAN_MAXIMUMS = { free: 1, basic: 10, premium: 100 }
def maximum_entries_per_month
PLAN_MAXIMUMS.fetch(plan.to_sym, PLAN_MAXIMUMS[:free])
end
You don't need a method. Just have a hash:
maximum_entries_per_month = Hash.new(1).merge{"premium" => 100, "basic" => 10}
and call:
maximum_entries_per_month[plan]
what about:
FREE_PLAN_MAXIMUM = 1
BASIC_PLAN_MAXIMUM = 10
PREMIUM_PLAN_MAXIMUM = 100
PLANS = {'premium' => PREMIUM_PLAN_MAXIMUM, 'basic' => BASIC_PLAN_MAXIMUM, 'free' => FREE_PLAN_MAXIMUM}
def maximum_entries_per_month
PLANS[plan] or FREE_PLAN_MAXIMUM
end
that "or FREE_PLAN_MAXIMUM" will catch any plan that's not "premium", "basic" or "free", if you are sure you only have those three plans just remove that part
EDIT: this way you keep your other constants working
EDIT2: if you don't want to add more constants and you are sure plan is one of those, you can do:
def maximum_entries_per_month
self.class.const_get("#{plan.upcase}_PLAN_MAXIMUM")
end
I'm using the Ruby REST API for Redmine (here: http://www.redmine.org/projects/redmine/wiki/Rest_api_with_ruby). I need to be able to get all issues in a chunk of 100 at a time.
I know there is an options[:offset] and an options[:limit] that the method "api_offset_and_limit" is looking for.
How do I pass those options when I'm doing this? I tried putting them in the URL as GET options, but they didn't come through on the other end. The following gives me the first 25 issues, as I expect it to.
class Issue < ActiveResource::Base
self.site = 'http://redmine.server/'
self.user = 'foo'
self.password = 'bar'
end
# Retrieving issues
issues = Issue.find(:all)
I'm not familiar with the API, but the way you describe it, the following should work:
issues = Issue.find(:all, :params => {:offset => 0, :limit => 100})
In my apps/controllers/model_controller.rb I have (names of models/methods changed to protect the innocent):
def background_sync
#background_task_uid = Model.async_process_model_cache({:name => 'name'})
#model_sync = ModelSync.new # Adds a new record in the queue of pending jobs
#model_sync.process_id = #background_task_uid # Puts the background process id into the new ModelSync record
#model_sync.save
end
In app/workers/model_worker.rb:
def process_model_cache(options={})
[long background task]
result = Workling::Return::Store.set(options[:uid], 'done')
result = Workling::Return::Store.get(options[:uid]) #=> 'done'
end
Notice that the set and get are functioning properly here within this worker. The problem is later on...
Back in app/views/model/index.html.rb, I have a prototype helper polling a request to the same controller to determine whether the background job is complete:
<%= periodically_call_remote( :url => { :action => :background_complete }, :frequency => 5, :update => 'status_div') %>
And in apps/controllers/model_controller.rb, the function for checking the status of the background job:
def background_complete
#background_task_uid = ModelSync.find(:last)
if #background_task_uid
#background_task_uid.each do |task|
unless task.process_id == "" || task.process_id.nil?
#result = Workling::Return::Store.get(task.process_id) #=> nil
if #result.nil?
task.destroy
end
else
task.destroy
end
unless #result.nil?
render :text => "<span style='font-size:12px;margin-left:20px;'>"+#result+"</span>"
else
#result = "none" if #result.nil?
render :text => "<span style='font-size:12px;margin-left:20px;'>"+#result+"</span>"
end
end
end
end
And finally, in config/environments/development.rb:
Workling::Return::Store.instance = Workling::Return::Store::MemoryReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
(Note that I've tried running this with and without the last line commented. If commented out, Workling reverts to Spawn rather than Starling.)
So the problem is that I get nil from this line in background_complete:
#result = Workling::Return::Store.get(task.process_id) #=> nil
I know it is a year since you asked this question, but just getting into Starling now, myself, so didn't see this till now.
But it looks like your problem was (from development.rb):
Workling::Return::Store.instance = Workling::Return::Store::MemoryReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
It needed to be:
Workling::Return::Store.instance = Workling::Return::Store::StarlingReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
At least for the benefit of those google searchers out there... :)
Found the answer to this question. The fix is to remove the Workling::Return::Store.instance line from config/environments/development.rb
Then replace the get AND set calls as follows:
In app/workers/model_worker.rb:
store = Workling::Return::Store::StarlingReturnStore.new
key, value = #uid, #progress
store.set(key, value)
In app/controllers/models_controller.rb:
store = Workling::Return::Store::StarlingReturnStore.new
#result = store.get(task.process_id)
Obviously, there is a way to declare a shortcut in environments.rb to avoid calling a new StarlingReturnStore each time, but I'm out of my depth because I can't make that work.
Anyway, this fix works for me. I'm getting the output from each background job to report via set to the get in the controller, which then gets captured by the AJAX call and reported to the page via RJS.
Nice!