Ruby Tweetstream MongoDB Error - ruby

I keep getting the following error when running the following ruby script. If anyone can help me fix this it would be greatly appreciated. I've removed any sensitive data such as API keys.
Code:
#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"
TweetStream.configure do |config|
config.consumer_key = 'KEY'
config.consumer_secret = 'SECRET'
config.oauth_token = 'TOKEN'
config.oauth_token_secret = 'TOKEN_SECRET'
config.auth_method = :oauth
end
db = Mongo::Connection.new("ds045037.mongolab.com", 45037).db("tweets")
auth = db.authenticate("DB_USERNAME", "DB_PASSWORD")
tweets = db.collection("tweetdata")
TweetStream::Daemon.new("TWITTER_USERNAME", "TWITTER_PASSWORD").track("TERM") do |status|
# Do things when nothing's wrong
data = {"created_at" => Time.parse(status.created_at), "text" => status.text, "geo" => status.geo, "coordinates" => status.coordinates, "id" => status.id, "id_str" => status.id_str}
tweets.insert({"data" => data});
end
Command to start the script:
ruby tweetscrape.rb
Ruby version:
ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-linux]
ruby -c tweetscrape.rb produces:
Syntax OK
Error Message:
/usr/local/rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:184:in `[]=': can't convert Symbol into Integer (TypeError)
from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/daemons-1.1.9/lib/daemons.rb:184:in `run_proc'
from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/daemon.rb:48:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/client.rb:131:in `filter'
from /usr/local/rvm/gems/ruby-1.9.3-p429/gems/tweetstream-2.5.0/lib/tweetstream/client.rb:98:in `track'
from tweetscrape.rb:19:in `<main>'
EDIT: I now have no errors using the below but nothing is entered in to the mongodb:
#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"
TweetStream.configure do |config|
config.consumer_key = 'gfdsgfdsgfdsgfdsgfdsgfds'
config.consumer_secret = 'gfsdgfdsgfdsgfdsgfsdgfd'
config.oauth_token = 'gfdgfdsgfsdgfdsgfsdgf'
config.oauth_token_secret = 'hsgfsdgfsdgfsdgfds'
config.auth_method = :oauth
end
db = Mongo::Connection.new("ds045037.mongolab.com", 45037).db("tweets")
auth = db.authenticate("gfsdgfdsgfsd", "gfdsgfdsgfdsgfsd")
tweets = db.collection("tweetdata")
TweetStream::Client.new.track('TERM') do |status|
puts status.text
data = {"created_at" => Time.parse(status.created_at), "text" => status.text, "geo" => status.geo, "coordinates" => status.coordinates, "id" => status.id, "id_str" => status.id_str}
tweets.insert({"data" => data})
end
Tweets show on screen through puts though...

The initial error you were getting with the Daemon class is because you're not passing the correct parameters to the constructor. The contructor takes a string and a hash.
Moving on from that , the insert failed because:
parsing status.datetime throws an exception (its already a Time object).
status.coordinate throws an exception if there's no coordinate.
The following code works for me (note : I added growl so you can see the tweets):
#!/usr/bin/env ruby
require "tweetstream"
require "mongo"
require "time"
require 'growl'
DESIRED = %w{created_at text geo coordinates id id_str}
host= ENV["MONGO_HOST"] || 'localhost'
port = ENV["MONGO_PORT"] || 27017
username = ENV["MONGO_USERNAME"]
password = ENV["MONGO_PASSWORD"]
term = ARGV[1] || 'TERM'
begin
TweetStream.configure do |config|
config.consumer_key = ENV["TWEET_CONSUMER_KEY"]
config.consumer_secret = ENV["TWEET_CONSUMER_SECRET"]
config.oauth_token = ENV["TWEET_OAUTH_TOKEN"]
config.oauth_token_secret = ENV["TWEET_OAUTH_TOKEN_SECRET"]
config.auth_method = :oauth
end
db = Mongo::Connection.new(host, port).db("tweets")
db.authenticate(username, password)
tweets = db.collection("tweetdata")
puts "about to start tracking term #{term}"
TweetStream::Daemon.new('tracker').track(term) do |status|
Growl.notify status.text, :title => status.user.screen_name
#
# filter out nil values
# filter out all keys not in the desired array
#
data = status.attrs.select{|k,v| !v.nil? && DESIRED.include?(k.to_s)}
tweets.insert({"data" => data});
end
rescue Mongo::ConnectionFailure
puts "Connection Error : #{$!}"
rescue Mongo::AuthenticationError
puts "Auth Error : #{$!}"
rescue Mongo::MongoDBError
puts "Unexpected Error : #{$!}"
end
You'll need to setup your environment with the following correct values :
export MONGO_USERNAME="..."
export MONGO_PASSWORD="..."
export TWEET_CONSUMER_KEY="..."
export TWEET_CONSUMER_SECRET="..."
export TWEET_OAUTH_TOKEN="..."
export TWEET_OAUTH_TOKEN_SECRET="..."
Then you can start the daemon with something like (in this case we'll search for yankees):
ruby tweetscrape.rb start yankees

Related

how to check mysql connexion

I would want to check if there is a connection with the database before execute the query .
But when I write if mysql_connection ... then it passes twice on mysql_connection:
def mysql_connection
puts "mysql_connection 1"
read_config_file
#connexion = Mysql2::Client.new(:host => #conf['host'], :username => #conf['user'], :password => #conf['password'], :database=> #conf['base'], :port => #conf['port'])
end
# USER QUERY MYSQL
def mysql_select_user(value)
puts "select"
# if mysql_connection then
p = mysql_connection.query("select #{value} from User")
p.each do |f|
puts "value : #{f}"
mysql_close
end
# else
# end
end
Use Mysql2::Client#ping method (from docs: http://www.rubydoc.info/gems/mysql2/0.3.13/Mysql2/Client#ping-instance_method)

Why do I have a worse performance of redis from ruby?

I've installed redis on a local virtual machine and run this code on my host. So I try to insert rows from a csv file to redis db. The CSV file includes 11000 rows and needs 20 seconds and I don't know why.
My code is:
require "redis"
require "csv"
CSV_FILE = "./data/SB_HI_OESL.CSV"
$redis = Redis.new(:host => "127.0.0.1", :port => 6379, :db => 0)
def insert_parent_child(parent, child)
start = Time.now
$redis.set("H:P:%s:%s" % [child[0], child[1]], "%s:%s" % [parent[4], parent[5]])
finish = Time.now
p (finish-start).inspect
end
CSV.foreach(CSV_FILE, { :col_sep => ';' }) do |row|
if $. != 1
insert_parent_child(row[-2..-1], row[0..1])
end
end
Output is:
"0.006501"
"0.003001"
"0.0005"
"0.011502"
"0.012002"
"0.004001"
"0.010502"
"0.011002"
I changed it to:
start = Time.now
$redis.pipelined {
CSV.foreach(CSV_FILE, { :col_sep => ';' }) do |row|
if $. != 1
insert_parent_child(row[-2..-1], row[0..1])
end
end
}
finish = Time.now
p (finish-start).inspect
Now output is "0.7315"

Execute the content of a second file in the first

I have a question, as I can edit this code to "twit" in a ruby file to send...
would be better that everything can be done from a file... but I can not do it :(
From already thank you very much! and this is my first post, if I mistake apology. I always read but now I can not find a twitter for ruby updated :(
require 'Twitter'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
client = Twitter::REST::Client.new do |config|
config.consumer_key = "xxxx"
config.consumer_secret = "xxxx"
config.access_token = "xxxx"
config.access_token_secret = "xxxx"
end
file = File.open("scrapy.rb")
ary = []
i = 0
file.each_line do |line|
ary[i] = line.chomp
i += 1
end
file.close
j = 0
i.times do
client.update("#{ary[j]}")
j += 1
sleep 10
end
My scrapy
require 'nokogiri'
require 'open-uri'
page = Nokogiri::XML(open('xxxxxxxxxxxx'))
eventos= page.xpath("//item")
eventos.each do |e|
ubicacion = e.xpath "title"
magnitud = e.xpath "emsc:magnitude"
horaUTC = e.xpath("emsc:time").text.split(" ",2).last
depth = e.xpath "emsc:depth"
link = e.xpath "guid"
puts [ubicacion, magnitud, horaUTC, depth, link].join "|"
end
Instead of
file = File.open("scrapy.rb")
simply require or load the other file
load 'scrapy'
Even better, you can convert the content of scrapy in a function, require the file once at the top of the first file, and call the function where you need it.
If you don't mind, I refactored the code a bit:
require 'Twitter'
require 'open3'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
client = Twitter::REST::Client.new do |config|
config.consumer_key = "xxxx"
config.consumer_secret = "xxxx"
config.access_token = "xxxx"
config.access_token_secret = "xxxx"
end
cmd = 'ruby scrapy.rb'
Open3.popen3(cmd) do |stdin, stdout|
file = stdout.read
ary = []
file.each_line do |line|
ary << line.chomp
end
ary.each do |line|
client.update(line)
sleep 10
end
end

Migrating Sinatra Webrick RACK:SSLEnforcer based HTTPS to Thin

I have been running Sinatra with Webrick and SSL using Rack::SSLenforcer in a development environment for a long while without any issues (based on https://github.com/tobmatth/rack-ssl-enforcer#readme ), i am trying to migrate to Thin in order to add websockets support but have issues getting my current app (without websockets) to run with Thin and SSL.
The basic code that i currently have on websockets is the following:
begin
pkey = OpenSSL::PKey::RSA.new(File.open("private_key.pem").read)
cert = OpenSSL::X509::Certificate.new(File.open("certificate.pem").read)
end
webrick_options = {
:Port => 8447,
:Logger => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
:DocumentRoot => "/ruby/htdocs",
:SSLEnable => true,
:SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
:SSLCertificate => cert,
:SSLPrivateKey => pkey,
:SSLCertName => [ [ "CN",WEBrick::Utils::getservername ] ],
:app => MyWebRTCServer
}
Rack::Server.start webrick_options
Then in my app i have the following:
configure do
# require SSL - https://github.com/tobmatth/rack-ssl-enforcer#readme
use Rack::SslEnforcer
set :session_secret, 'asdfa2342923422f1adc05c837fa234230e3594b93824b00e930ab0fb94b'
use Rack::Session::Cookie, :key => '_rack_session',
:path => '/',
:expire_after => 2592000, # In seconds
:secret => session_secret
# load password file -
begin
##config = YAML.load_file(File.join(Dir.pwd, 'config', 'users.yml'))
rescue ArgumentError => e
puts "Could not parse YAML: #{e.message}"
end
# puts "config: " + ##config.to_s
use Rack::Auth::Basic, "Restricted Area" do |u, p|
$LOG.info "Use Rack::Auth::Basic"
if (!##config[:users][u])
puts "Bad username"
false
else
# initialize the BCrypt with the password
tPassword = BCrypt::Password.new(##config[:users][u][:password].to_s)
# puts "From BCrypt: " + tPassword
if (tPassword == p)
# puts "Validated password"
# check whether the user is already logged in or not
if (!##user_table_cache[u.to_sym])
# puts "User already logged in or session has not expired"
userHash = Hash.new
userHash[:name] = u
userHash[:privilege] = ##config[:users][u][:privilege]
# add the user hash to the cache
##user_table_cache[u.to_sym] = userHash
end
end
true
end
end
end
All of this works on webrick with Sinatra. I have tried the following on Thin (based on Can I enable SSL in Sinatra with Thin?)
class MyApp < Sinatra::Base
# ...
get '/' do
puts "got request"
end
end
MyApp.run! do |server|
ssl_options = {
:cert_chain_file => './certificate.pem',
:private_key_file => './private_key.pem',
:verify_peer => false
}
server.ssl = true
server.ssl_options = ssl_options
end
However, I get the following error, when i try to access it from the browser.
C:\Software\Ruby Projects\Utils\sandbox\thintest>thistest
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Th
in
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop
terminate called after throwing an instance of 'std::runtime_error'
what(): Encryption not available on this event-machine
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
any thoughts would be greatly appreciated.

how to excute code on webrick server

I start a webrick server like this:
dell#dev:/var/www/ruby$ ruby -run -httpd. -p 5000
and have this code in abc.rb:
require 'webrick'
root = File.path '/tmp/public_html'
server = WEBrick::HTTPServer.new :Port => 5000, :DocumentRoot => root
trap 'INT' do server.shutdown end
server.start
ary = { "0"=>"fred", "1"=>10, "2"=>3.14, "3"=>"This is a string", "4"=>"last element", }
ary.each do |key, value|
puts "#{key} #{value}"
end
When I run this code it shows me the same code on browser
http://localhost:5000/abc.rb
How can I view the output this code, I have already asked this question and did not get any correct answer :(
Is it the right code? I want to know this, where this code place
require 'webrick'
root = File.path '/tmp/public_html'
server = WEBrick::HTTPServer.new :Port => 5000, :DocumentRoot => root
trap 'INT' do server.shutdown end
server.start
if any one give me step by step ans to run this code i am very thankful.. I don't understand the ans :( how to do this
From the documentation:
The easiest way to have a server perform custom operations is through
WEBrick::HTTPServer#mount_proc. The block given will be called with a
WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse
which must be filled in appropriately:
server.mount_proc '/' do |req, res|
res.body = 'Hello, world!'
end
Remember that server.mount_proc must server.start.
So:
require 'webrick'
root = File.path '/tmp/public_html'
server = WEBrick::HTTPServer.new :Port => 5000, :DocumentRoot => root
server.mount_proc '/abc.rb' do |req, res|
ary = { "0"=>"fred", "1"=>10, "2"=>3.14, "3"=>"This is a string", "4"=>"last element" }
res.body = ary.map do |key, value|
"#{key} #{value}"
end.join("\n")
end
trap 'INT' do server.shutdown end
server.start
Also, I believe the correct way to start your WebBrick is by running:
ruby abc.rb

Resources