Parse API and Show Output in Rails View - ruby-on-rails

So, I wrote a program that sends a get request to HappyFox (a support ticket web app) and I get a JSON file, Tickets.json.
I also wrote methods that parse the JSON and return a hash with information that I want, i.e tickets with and without a response.
How do I integrate this with my Rails app? I want my HappyFox View (in rails) to show the output of those methods, and give the user the ability to refresh the info whenever they want.
Ruby Code:
require 'httparty'
def happy_fox_call()
auth = { :username => 'REDACTED',
:password => 'REDACTED' }
#tickets = HTTParty.get("http://avatarfleet.happyfox.com/api/1.1/json/tickets/?size=50&page=1",
:basic_auth => auth)
tickets = File.new("Tickets.json", "w")
tickets.puts #tickets
tickets.close
end
puts "Calling API, please wait..."
happy_fox_call()
puts "Complete!"
require 'json'
$data = File.read('/home/joe/API/Tickets.json')
$tickets = JSON.parse($data)
$users = $tickets["data"][3]["name"]
Count each status in ONE method
def count_each_status(*statuses)
status_counters = Hash.new(0)
$tickets["data"].each do |tix|
if statuses.include?(tix["status"]["name"])
#puts status_counters # this is cool! Run this
status_counters[tix["status"]["name"]] += 1
end
end
return status_counters
end
Count tickets with and without a response
def count_unresponded(tickets)
true_counter = 0
false_counter = 0
$tickets["data"].each do |tix|
if tix["unresponded"] == false
false_counter += 1
else true_counter += 1
end
end
puts "There are #{true_counter} tickets without a response"
puts "There are #{false_counter} ticket with a response"
end
Make a function that creates a count of tickets by user
def user_count(users)
user_count = Hash.new(0)
$tickets["data"].each do |users|
user_count[users["user"]["name"]] += 1
end
return user_count
end
puts count_each_status("Closed", "On Hold", "Open", "Unanswered",
"New", "Customer Review")
puts count_unresponded($data)
puts user_count($tickets)
Thank you in advance!

You could create a new module in your lib directory that handles the API call/JSON parsing and include that file in whatever controller you want to interact with it. From there it should be pretty intuitive to assign variables and dynamically display them as you wish.
https://www.benfranklinlabs.com/where-to-put-rails-modules/

Related

Parse Open Graph Data in Rails using Metainspector

I am working on an app where I am required to fetch and save the open graph data of a website.
So far I have been able to grab properties such as title, description, url by using this code
before_save :get_meta_from_link
def check_link
begin
#page_link = MetaInspector.new(sanitized_url)
rescue Faraday::ConnectionFailed => e
errors.add(:link, "Oops, can't be processed ATM")
end
end
def get_meta_from_link
page = #page_link
return unless page.to_hash.present?
if page.title.present?
self.title = page.title
end
if page.description.present?
self.description = page.description
end
if page.url.present?
self.url = page.url
end
end
I am using the metainspector gem and trying to grab values such as og:locale, og:type. How can I fetch those values?
This is the link I am using to cross reference values: https://metainspectordemo.herokuapp.com
Ok, so I managed to solve it using
def check_link
begin
#page_link = MetaInspector.new(sanitized_url)
rescue MetaInspector::RequestError => e
errors.add(:link, "you provided is not being read by our system. Please check the link.")
end
end
in my link model
followed by
def get_meta_from_link
page = #page_link
paje = #page_link.meta_tags
return unless page.to_hash.present?
if page.title.present?
self.btitle = page.title
end
end

Send parameters from controller to model rails

I'm working on the Meetup Api.
I would like to save some conferences from the API into my database.
The saving conferences depend of the parameters passing into the view to the controller :
<%= link_to 'See conferences', conferences_path(:title => "ParisRb")%> |
Then I call the good method to look for the good conferences (comparing to the params) among all the one received from the api.
I would like the methods to be very generic and to be able to save any conferences not only 'ParisRb'.
So I modify all my methods in this goal but there is one I can not modify, I don't know how.
This is my whole code. The one I'd like to modify is self.conferences_filter(data) wich is supposed to receive the params from the controller instead of 'ParisRb'. But I know that passing parameters from the controller to the model is not a good practice. So any idea is welcome :)
lib/api_meetup.rb
class ApiMeetup
BASE_URI = "https://api.meetup.com"
def events(urlname)
HTTParty.get(BASE_URI + "/#{urlname}/events")
end
end
conferences_controller.rb
def index
#call to the API
response = ApiMeetup.new.events(params[:title])
api_data = JSON.parse(response.body)
filtered_conferences = Conference.conferences_filter(api_data)
conferences = Conference.save_conferences_from_api(filtered_conferences)
#conferences = conferences.current_conferences
end
conference.rb
#Keep only requested conferences
def self.conferences_filter(data)
requested_conferences = []
data.each do |event|
if event["name"].include?('ParisRb') #This should receive params[:title] instead of 'ParisRb'
requested_conferences << event
end
end
requested_conferences
end
#Save requested conferences from the Meetup API
def self.save_conferences_from_api(conferences)
# data = data_from_api
conferences.each do |line|
conference = self.new
conference.title = line['name']
conference.date = format_date(line['time'])
conference.url = line['link']
if conference.valid?
conference.save
end
end
self.all
end
That's was actually quite obvious.
I just needed to pass to argument to my method :
filtered_conferences = Conference.conferences_filter(api_data, params[:title])
#Keep only requested conferences
def self.conferences_filter(data, title)
requested_conferences = []
data.each do |event|
if event["name"].include?(title)
requested_conferences << event
end
end
requested_conferences
end

Infinitely listen to jabber events?

I am writing a chat application, using Jabber, on Ruby on Rails. Sending messages was quite easy to implement, but receiving messages in a loop is quite a challenge.
I want to get callbacks from the server without browser refreshes. I tried to use ActionController::Live for this.
In my client side, my code is:
var source = new EventSource('/chat/events');
source.addEventListener('refresh', function(event)
{
AddMessage(event.data);
});
My controller code is:
def chat_events
# SSE expects the `text/event-stream` content type
response.headers['Content-Type'] = 'text/event-stream'
sse = Reloader::SSE.new(response.stream)
puts "Starting XMMP call"
begin
#xmmpClient = XmppClient.new
#xmmpClient.loginUsingNameAndPassword(****, ***)
#xmmpClient.listen_connections sse
rescue IOError
puts "Error"
# When the client disconnects, we'll get an IOError on write
ensure
puts "closing stream"
sse.close
end
end
And, my XMMP client is:
def listen_connections(writer = nil)
if not #logged_in
puts "Not logged"
raise "Not logged"
end
#robot.send(Jabber::Presence.new.set_show(nil))
loop do
puts "Listening callback"
#robot.add_message_callback do |message|
puts "Got message " + message.inspect
if not writer.nil?
writer.write({ :message => message.body }, :event => 'refresh')
end
end
sleep 2
end
end
What I got:
The chat_events method of the controller is called every second or so.
Because of this, several callbacks are executed at once.
When I got a message, I got it four or five times.
{"message":"fffdsfd"}
{"message":"fffdsfd"}
{"message":"fffdsfd"}
{"message":"fffdsfd"}
And the worst stuff - my server is not responding to other responses, although I use the Puma multi-threaded server.
What is the correct way to implement functionality like this?
I get the solution
puts "."
client.add_message_callback do |message|
if message.type != :error
arr = message.from.to_s.split('#')
puts arr[0]
puts message.body
end
end
while 1
end

Rake task - undefined method

I tinkering my way into creating a rake task that grabs the amount of checkins for a given page throw facebook-graph. I usign the koala gem and rails.
I do this by creating a rake task:
task :get_likes => :environment do
require 'koala'
# Grab the first user in the database
user = User.first
# Loop throw every school & and call count_checkins
School.columns.each do |column|
user.facebook.count_checkins(column.name, user)
end
end
# Count like for every school else return 0
def count_checkins(name, u)
a = u.facebook.fql_query('SELECT checkins FROM page WHERE name = "' + name + '"')
if a[0].nil?
return 0
else
return b = a[0]["checkins"]
end
end
# Initialize an connection to the facebook graph
def facebook
#facebook ||= Koala::Facebook::API.new(oauth_token)
end
But I get a error:
private method `count_checkins' called for #<Koala::Facebook::API:0x007fae5bd348f0>
Any ideas or better way to code a rake task would be awesome!
Check the full error here: https://gist.github.com/shuma/4949213
Can't really format this properly in a comment, so I'll put it in an answer. I would put the following into the User model:
# Count like for every school else return 0
def count_checkins(name)
a = self.facebook.fql_query('SELECT checkins FROM page WHERE name = "' + name + '"')
if a[0].nil?
return 0
else
return b = a[0]["checkins"]
end
end
# Initialize an connection to the facebook graph
def facebook
#facebook ||= Koala::Facebook::API.new(oauth_token)
end
Then change the rake task to:
task :get_likes => :environment do
require 'koala'
# Grab the first user in the database
user = User.first
# Loop throw every school & and call count_checkins
School.columns.each do |column|
user.count_checkins(column.name)
end
end
That way count_checkins is defined on the user model, rather than trying to modify a class within Koala -- and you aren't duplicating work by having to pass around more User and Facebook parameters than are necessary.

em-mongo examples?

Looking to use em-mongo for a text analyzer script which loads text from db, analyzes it, flags keywords and updates the db.
Would love to see some examples of em-mongo in action. Only one I could find was on github em-mongo repo.
require 'em-mongo'
EM.run do
db = EM::Mongo::Connection.new.db('db')
collection = db.collection('test')
EM.next_tick do
doc = {"hello" => "world"}
id = collection.insert(doc)
collection.find('_id' => id]) do |res|
puts res.inspect
EM.stop
end
collection.remove(doc)
end
end
You don't need the next_tick method, that is em-mongo doing for you. Define callbacks, that are executed if the db actions are done. Here is a skeleton:
class NonBlockingFetcher
include MongoConfig
def initialize
configure
#connection = EM::Mongo::Connection.new(#server, #port)
#collection = init_collection(#connection)
end
def fetch(value)
mongo_cursor = #collection.find({KEY => value.to_s})
response = mongo_cursor.defer_as_a
response.callback do |documents|
# foo
# get one document
doc = documents.first
end
response.errback do |err|
# foo
end
end
end

Resources