Trying to get list of friends from twitter using httparty(ruby) - ruby

I am trying to get the list of specific user`s friends from twitter.
This is my code -
require 'rubygems'
require 'httparty'
class TwitterData
include HTTParty
base_uri 'http://api.twitter.com/1/'
default_params :output => 'json'
format :json
def self.get_username_data(username)
get('statuses/friends.json' , :query => { :screen_name => username })
end
end
puts "Please your twitter username - "
twitter_username = gets
puts TwitterData.get_username_data(twitter_username).inspect
This is the error I am getting -
Please your twitter username -
twitter
C:/Ruby192/lib/ruby/gems/1.9.1/gems/crack-0.1.8/lib/crack/json.rb:14:in `rescue in parse': Invalid JSON string (Crack::ParseError)
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/crack-0.1.8/lib/crack/json.rb:12:in `parse'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/parser.rb:116:in `json'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/parser.rb:136:in `parse_supported_format'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/parser.rb:103:in `parse'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/parser.rb:66:in `call'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/request.rb:180:in `parse_response'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/request.rb:164:in `handle_response'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty/request.rb:57:in `perform'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty.rb:280:in `perform_request'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/httparty-0.6.1/lib/httparty.rb:232:in `get'
from twitter_friends_2.rb:11:in `get_username_data'
from twitter_friends_2.rb:17:in `<main>'

Replace your method with this
def self.get_username_data(username)
get("/statuses/friends.json?screen_name=#{username}")
end
OR
def self.get_username_data(username)
get('/statuses/friends.json' , :query => { :screen_name => username.strip })
end
You need to strip the username because from command line when user enters the twitter username and hits enter key a "\n" gets appended to the username and the same username is sent as a parameter which causes the problem. Any of the above given code snippets should work.

Related

Strange behavior in rspec when raising exception

I am trying to figure out why the following spec won't pass when the expect and actual results look the same
1) Moodle::Client raises moodle error if token is invalid
Failure/Error: expect {
expected Moodle::MoodleError with {"exception"=>"moodle_exception", "errorcode"=>"invalidtoken", "message"=>"Invalid token - token not found"}, got #<Moodle::MoodleError: {"exception"=>"moodle_exception", "errorcode"=>"invalidtoken", "message"=>"Invalid token - token not found"}> with backtrace:
# ./lib/moodle/client.rb:27:in `resolve_request'
# ./lib/moodle/client.rb:11:in `method_missing'
# ./spec/moodle/client_spec.rb:48:in `block (4 levels) in <module:Moodle>'
# ./spec/moodle/client_spec.rb:47:in `block (3 levels) in <module:Moodle>'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr.rb:182:in `use_cassette'
# ./spec/moodle/client_spec.rb:46:in `block (2 levels) in <module:Moodle>'
# ./spec/moodle/client_spec.rb:47:in `block (3 levels) in <module:Moodle>'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/ryanme/.rvm/gems/ruby-2.2.2#phoenix/gems/vcr-2.9.3/lib/vcr.rb:182:in `use_cassette'
# ./spec/moodle/client_spec.rb:46:in `block (2 levels) in <module:Moodle>'
The code is still work in progress:
require 'typhoeus'
module Moodle
class Client
attr_reader :web_service_name, :filter_params
def method_missing message, *args, &block
if supports_web_service? message
#web_service_name = message
#filter_params = args.first
resolve_request
else
super
end
end
def supports_web_service? name
true # change to look at configuration for web services
end
def resolve_request
response = request.run
json_body = JSON.parse(response.body)
if json_body['exception']
raise MoodleError, json_body
else
json_body
end
end
def request
Typhoeus::Request.new(Moodle.configuration.api_url,
method: :post,
params: request_params,
headers: { 'Accept' => "json" })
end
def request_params
filter_params.merge!({ moodlewsrestformat: Moodle.configuration.format,
wsfunction: web_service_name,
wstoken: Moodle.configuration.token })
end
end
end
The spec spec is below:
it 'raises moodle error if token is invalid' do
Moodle.configure do|c|
c.host = 'http://dev.vle.getsmarter.co.za'
c.token = 'invalidtoken'
end
expected_response = {"exception"=>"moodle_exception","errorcode"=>"invalidtoken","message"=>"Invalid token - token not found"}
VCR.use_cassette("valid_service_with_invalid_token") do
expect {
Moodle::Client.new.core_user_get_users(params)
}.to raise_error(Moodle::MoodleError, expected_response)
end
end
My question is why is it breaking? Does it have something to do with the backtrace? Also any ideas on how to fix it would be great.
raise_error doesn't take a hash but an error message (either string or regexp).
This would work:
expect {
Moodle::Client.new.core_user_get_users(params)
}.to raise_error(Moodle::MoodleError, 'Invalid token - token not found')
You can set additional expectations by passing a block, e.g.:
expect {
Moodle::Client.new.core_user_get_users(params)
}.to raise_error(Moodle::MoodleError, 'Invalid token - token not found') { |error|
expect(error.errorcode).to eq('invalidtoken')
}

Why is Mechanize returning "undefined method 'value=' for nil:NilClass" when trying to set a password?

I wrote a script with Mechanize to scrape some links, which later I will write code to put into an Excel file.
For now I can't authenticate past the first page. I keep getting an undefined method value= for nil:NilClass when attempting to set the password in the form and haven't been able to find any information on it.
I don't even have the method value= in my code so I don't understand what is going on. The code runs fine for the username, but once I enter the password and hit enter I get the error:
users.rb:11:in `block (2 levels) in <main>': undefined method `value=' for nil:NilClass (NoMethodError)
from (eval):23:in `form_with'
from formity_users.rb:7:in `block in <main>'
from /home/codelitt/.rvm/gems/ruby-2.0.0-p247/gems/mechanize-2.7.1/lib/mechanize.rb:433:in `get'
from formity_users.rb:5:in `<main>'
This is my users.rb script:
require 'rubygems'
require 'mechanize'
a = Mechanize.new
a.get('https://www.example.com') do |page|
#Enter information into forms
logged_in = page.form_with(:id => 'frmLogin') do |f|
puts "Username?"
f.field_with(:name => "LoginCommand.EmailAddress").value = gets.chomp
puts "Password?"
f.field_with(:name => "Login.Password").value = gets.chomp
end.click_button
#Click drop down
admin_page = logged_in.click.link_with(:text => /Admin/)
#Click Users and enter user admin section
user_admin = admin_page.click.link_with(:text => /Users/)
#Scrape and print links for now
user_admin.links.each do |link|
text = link.text.strip
next unless text.length > 0
puts text
end
end
I think your error is coming from
f.field_with(:name => "Login.Password")
which seems to be nil. For username, I see that you have specified input name LoginCommand.EmailAddress and for password input name is Login.Password.
I'd expect anybody who has written this markup to use consistent names. Maybe you should look that the underlying html to see you're using correct field names in your code.

Where to put auth information

So I'm making a small program in VisualRuby that can tweet. So here's what my main.rb looks like:
#!/usr/bin/ruby
require 'vrlib'
require 'twitter_oauth'
#make program output in real time so errors visible in VR.
STDOUT.sync = true
STDERR.sync = true
#everything in these directories will be included
my_path = File.expand_path(File.dirname(__FILE__))
require_all Dir.glob(my_path + "/bin/**/*.rb")
LoginWindow.new.show
and my LoginWindow.rb looks like this
require 'twitter_oauth'
class LoginWindow #(change name)
include GladeGUI
client = TwitterOAuth::Client.new(
:consumer_key => '****',
:consumer_secret => '****',
:token => '****-****',
:secret => '****'
)
def show()
load_glade(__FILE__) #loads file, glade/MyClass.glade into #builder
set_glade_all() #populates glade controls with insance variables (i.e. Myclass.label1)
show_window()
end
def button1__clicked(*argv)
if client.authorized?
puts "true"
end
end
end
And finally my window looks like this:
Now when I run this and click the login button, VR spits this out
C:/Users/*/visualruby/Test/bin/LoginWindow.rb:22:in `button1__clicked': undefined local variable or method `client' for #<LoginWindow:0x3f56aa8>
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/vrlib-0.0.33/lib/GladeGUI.rb:146:in `call'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/vrlib-0.0.33/lib/GladeGUI.rb:146:in `block (3 levels) in parse_signals'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/vrlib-0.0.33/lib/GladeGUI.rb:331:in `call'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/vrlib-0.0.33/lib/GladeGUI.rb:331:in `main'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/vrlib-0.0.33/lib/GladeGUI.rb:331:in `show_window'
from C:/Users/*/visualruby/Test/bin/LoginWindow.rb:17:in `show'
from main.rb:14:in `<main>'
I don't think I'm supposed to put the client = Twitter.... stuff inside the LoginWindow class but I can't think of anywhere else to put it. Any ideas on how to fix this issue?
This is a quick solution for what you need.
in your LoginWindow.rb
def initialize
#client = TwitterOAuth::Client.new(
:consumer_key => '****',
:consumer_secret => '****',
:token => '****-****',
:secret => '****'
)
end
def button1__clicked(*argv)
if #client.authorized?
puts "true"
end
end
The problem with this solution is now you can't call button1_clicked without initializing LogginWindow before, so be careful.

Ruby NoMethodError (undefined method `map') in Post Request

I'm trying to do a POST request from a ruby app and I'm getting the following error.
Here is the code:
def action_reply(token,action_id,reply_text)
require 'uri'
require 'net/http'
require 'net/https'
#reply = { 'ACTION_ID' => action_id, 'text' => reply_text }.to_json
#A token is required to do this post
#token_url = 'https://example.com/reply?oauth_token=' + token
uri = URI.parse(#token_url)
response = Net::HTTP.post_form(uri,#reply)
end
I'm getting an error in the last step that says:
NoMethodError (undefined method `map' for #<String:0x000000063798e8>)
Any idea why this is?
Thanks!
Because you're passing a string to a method expecting a hash: remove the to_json call.
Unrelated, but is it necessary to have those instance variables be instance variables?

rails rspec mock_model Object expected, got String

I have a Directory controller and a Files controller. I'm testing the Files controller. I've created valid attributes for the File and I'm trying to mock_model the Directory to get the test to pass. The GET tests all work, but none of the POST tests work. The POST tests all give the error: "Directory expected, got String."
describe FilesController do
def valid_attributes {
:name => "test",
:reference_id => 1,
:location => "/path/to/directory",
:software => "excel",
:software_version => "2010",
:directory => mock_model(Directory)
}
end
describe "POST create" do
describe "with valid params" do
it "creates a new AssemblyFile" do
expect {
post :create, :assembly_file => valid_attributes
}.to change(AssemblyFile, :count).by(1)
end
it "assigns a newly created assembly_file as #assembly_file" do
post :create, :assembly_file => valid_attributes
assigns(:assembly_file).should be_a(AssemblyFile)
assigns(:assembly_file).should be_persisted
end
it "redirects to the created assembly_file" do
post :create, :assembly_file => valid_attributes
response.should redirect_to(AssemblyFile.last)
end
end
end
1) FilesController POST create with valid params creates a new File
Failure/Error: post :create, :file => valid_attributes
ActiveRecord::AssociationTypeMismatch:
Directory(#87017560) expected, got String(#49965220)
# ./app/controllers/files_controller.rb:60:in `new'
# ./app/controllers/files_controller.rb:60:in `create'
# ./spec/controllers/files_controller_spec.rb:79:in `block (5 levels) in <top (required)>'
# ./spec/controllers/files_controller_spec.rb:78:in `block (4 levels) in <top (required)>'
If I look at the test.log file, it shows that assembly is a string ("assembly" => "1011"). So I'm not sure why the mock_model isn't creating an object?
I've tried using stub! instead of mock_model, but that gets complicated because the create! used for stub! needs a lot of its own valid variables set and I don't really want to have to set a whole bunch of other valid attributes for that when I'm not trying to even test the Directory controller at all.
What am I doing wrong in my approach here?
Pass the id of the mock in the params hash instead of the mock itself. You'll also need to stub the find method so the mock is available in the controller action:
#directory = mock_model(Directory)
Directory.stub(:find).with(#directory.id).and_return(#directory)
post :create, :assembly_file => valid_attributes.merge(:directory_id => #directory.id)
# in controller
#directory = Directory.find(params[:assembly_file][:directory_id]) # => returns the mock

Resources