Get large images from Page Feed? using Koala Gem & Rails 3.2 - ruby-on-rails

Does anyone know how to pull different size images from the Page Feed?
I was trying to use the Type hash that works great for friends and profile pictures.
#page-feed = #graph.get_connections("somepage", "feed", {"type" => "large"})
but for some reason I'm always getting the same picture size for all posts.
Thanks !

Reading the code here: https://github.com/arsduo/koala/blob/81e66f459df840d9d5e122c0d498e2fb9d146655/lib/koala/api/graph_api.rb (line 178, def get_picture) you can see that the method accepts options hash:
Gem source:
# Fetches a photo.
# (Facebook returns the src of the photo as a response header; this method parses that properly,
# unlike using get_connections("photo").)
#
# #param options options for Facebook (see #get_object).
# To get a different size photo, pass :type => size (small, normal, large, square).
# #param block (see Koala::Facebook::API#api)
#
# #note to delete photos or videos, use delete_object(id)
#
# #return the URL to the image
def get_picture(object, args = {}, options = {}, &block)
# Gets a picture object, returning the URL (which Facebook sends as a header)
resolved_result = graph_call("#{object}/picture", args, "get", options.merge(:http_component => :headers)) do |result|
result ? result["Location"] : nil
end
block ? block.call(resolved_result) : resolved_result
end
So you can call it like .get_picture(id, type: :large). Like this:
graph = Koala::Facebook::API.new(token)
profile = graph.get_object('me')
graph.get_picture(profile['id'], type: :large)

Just in case anyone else comes across this, this is what I had to do in order to retrieve the large images. Note that I'm only grabbing the first post in the feed.
In my controller:
#fb_post = #facebook.get_connections(page_id, 'posts').first
#photo = #facebook.get_connections(#fb_post['id'], 'attachments').first
Then, to grab the proper link in the view inside of an img tag, I used:
#photo["media"]["image"]["src"]

For anyone still struggling with this, I was able to use the 'full_picture' field in my Koala object to retrieve a full-resolution URLs of the images:
fields = ['id','picture','full_picture']
graphObj = Koala::Facebook::API.new(accessToken)
hashes = graphObj.get_connection(groupId, 'feed', { limit: 10, fields: fields })
hashes.each do |hash|
mash = Hashie::Mash.new(hash)
fullPicture = mash.full_picture
end

Related

How to query for records where Active Storage attached and image is variable?

How can I query for all the users who have an image attached and where the image is .variable??
e.g
I can do this
# controller
#users = User.all
view:
<% if user.image.attached? && user.image.variable? %>
<!-- display image -->
<% end %>
Rather than having that logic in the view, I wonder if I can simply query for only those #users which meet the conditions of both user.image.attached? and user.image.variable?
Is this possible with some Active Record query?
Active Storage doesn't provide shortcut scopes for what you want, but you can come up with a custom solution.
For fetching only users with an attached image, join the corresponding attachments:
User.joins(:image_attachment)
An attachment (or rather: a blob) is variable, if its content_type is present in the ActiveStorage.variable_content_types array, see https://github.com/rails/rails/blob/v6.1.3.2/activestorage/app/models/active_storage/blob/representable.rb#L42-L44.
So we can further query for that content_type, but we need to join the blob (implicitly through the attachment) for that:
User.joins(:image_blob).where(active_storage_blobs: {content_type: ActiveStorage.variable_content_types})
And that should be the query for what you want. Additionally, you can have that as a scope so it's shorter when used:
# app/models/user.rb
scope :with_variable_image -> do
joins(:image_blob).where(active_storage_blobs: {content_type: ActiveStorage.variable_content_types})
end
# app/controllers/users_controller.rb or wherever
users = User.with_variable_image

How do I handle an external API callback with Ruby on Rails?

I'm in need of some guidance. I'm using the 6px.io API to resize images. The conversion can take a couple of seconds and 6px sends me a post callback when the image has been sent/stored in our S3 bucket. After the callback, when the image is resized and saved we'd like to download the file to the user's browser from our S3 bucket.
If the resized image is already in our S3 bucket and does not need to be processed by 6px we use send_data to download the file to the user. Unfortunately I can't use send_data on the callback controller action to initiate download of the file to the user. How is this done in Rails?
User story:
Click medium resize of image menu item of dropdown.
Rails controller action builds JSON with post callback url and sends to 6px.
6px returns JSON with input and output information plus the status (complete/fail).
File starts to download to user's computer/browser ***This is what I need help with.
Example code (this is for work, can't post the real code):
class FakeExampleController < ApplicationController
def convert_image
# code ommitted
#fake_example = FakeExample.find_by(:id)
image_conversion(params)
end
def callback
# width, height, type variable code ommitted
if params['status'] == 'complete'
converted_file = FakeConvertedImage.create!(filename: #new_file_name, attachment_id: #fake_example.id, format: type, width: width, height: height)
send_converted_file( :url => "OUR_S3_BUCKET", :filename => "#{converted_file.filename}", :type => "#{type}", :disposition => 'attachment' ) #This does not work to download file to user's browser.
else
raise
"Image Conversion Failed"
end
end
def image_conversion(params)
callback_url = fake_example_url.gsub(/localhost:3000/, '********.ngrok.com')
image_converter = ImageConverter.new(params) #This is a wrapper I made for the 6px-ruby gem
image_converter
.convert_type(#fakeexample.mime_type_for_6px(params[:mimetype])
.resize_images
.save("OUR_S3_BUCKET_URL", callback_url)
end
def send_converted_file(opts={})
other_opts = opts.select{ |opt,v| /(filename|type|disposition)/ === opt }
response = { url: opts.fetch(:url), :opts => other_opts }
send_data( open(URI.encode(response[:url].to_s)).read, response[:opts] )
end
end
I don't get/have any errors. I just need advice on how to download the file saved in our S3 to the user.

Rails - Upload picture to Facebook using URL

I'm using Koala for Facebook API and Paperclip for Amazon S3.
I already finished the code for S3 Upload, but having problem for Facebook's upload.
Here's my simplified code:
#user = User.find(params[:id])
#graph = Koala::Facebook::API.new(session[:access_token])
file = open(#user.photo.url(:origin)).read
# ALBUM_ID is constant, its value is the Facebook's album ID
#graph.put_picture(file, { }, ALBUM_ID)
I keep getting this error on last line:
ArgumentError
string contains null byte
I think the way I set file is wrong but I can't find other way to do it.
Thanks before.
While uploading picture on facebook using URL, you just need to send picture url directly (you don't need to send binary data).
# REMOVE THIS LINE
file = open(#user.photo.url(:origin)).read
Update API call as:
# ALBUM_ID is constant, its value is the Facebook's album ID
#graph.put_picture(#user.photo.url(:origin), {}, ALBUM_ID)
Some other ways to use put_picture method:
# put_picture(file, content_type, {:message => "Message"}, 01234560)
# put_picture(params[:file], {:message => "Message"})
# # with URLs, there's no optional content type field
# put_picture(picture_url, {:message => "Message"}, my_page_id)
Source: Koala gem.

Rails + CouchDb binary file upload to Database

Simple-Stored is based on top of CouchPotato for handling CouchDb in rails. While trying to upload files to the couchdb we have tryied using base64, json post and nothing seems to work quite right; we are trying to upload to the _attachments propertie of a document already stored.
Having the model like this :
class Patient
include SimplyStored::Couch
end
and in the controller while receiving the file trough the update action
def update
#patient = Patient.find(params[:id])
if params[:patient][:_attachments]
attachement = params[:patient][:_attachments]
filedata = attachement.tempfile.read
data = Base64.encode64(filedata).gsub(/\n/, '')
type = attachement.content_type
or_name = attachement.original_filename
#patient._attachments = {or_name => {'data' => data, 'content_type' => type}}
#patient.save
return render :json => #patient._attachments
end
end
Now the fun part is that I can see that #patient._acttachments has the file itself and that is what is returning in the render after the .save; but it is not actually saving it on the couchdb database.
Any ideas why is not doing the save or should I try to just push the _attachment to the couchdb database. ? (which by the way always returns a 500 error :( )
the solution it's very simple, based on the couchpotato website, you actually don't need to convert it to base64 here is the example of code working
if params[:patient][:_attachments]
attachement = params[:patient][:_attachments]
data = attachement.tempfile.read
type = attachement.content_type
or_name = attachement.original_filename
params[:patient][:_attachments] = {or_name => {'data' => data, 'content_type' => type}}
end
if #patient.update_attributes(params[:patient]) #blah blah blah
since the values are in the [:patient][:_attachments] params, you just need to pass it as another param tested and working.
Also you need to define your patients model as
property :_attachments
dunno if that is required but I did it.
I know I should not ask for money but since I WORK FOUR YOU its only 100 pesos/hour.. see you at the office
cheers
lols
I donno about the Ruby and couchpotato, but I don't think you need to Base64 your attachment. Just read the binary info and write it to request.
my 2cents. :)

Problems with MailChimp API in Ruby Error Code: -90

I am using the following code in my MailChimp Controller to submit simple newsletter data. When It is sent I receive the following error as a "Method is not exported by this server -90" I have attached my controller code below. I am using this controller for a simple newsletter signup form. (Name, Email)
class MailchimpController < ApplicationController
require "net/http"
require "uri"
def subscribe
if request.post?
mailchimp = {}
mailchimp['apikey'] = 'f72328d1de9cc76092casdfsd425e467b6641-us2'
mailchimp['id'] = '8037342dd1874'
mailchimp['email_address'] = "email#gmail.com"
mailchimp['merge_vars[FNAME]'] = "FirstName"
mailchimp['output'] = 'json'
uri = URI.parse("http://us2.api.mailchimp.com/1.3/?method=listSubscribe")
response = Net::HTTP.post_form(uri, mailchimp)
mailchimp = ActiveSupport::JSON.decode(response.body)
if mailchimp['error']
render :text => mailchimp['error'] + "code:" + mailchimp['code'].to_s
elsif mailchimp == 'true'
render :text => 'ok'
else
render :text => 'error'
end
end
end
end
I highly recommend the Hominid gem: https://github.com/tatemae-consultancy/hominid
The problem is that Net::HTTP.post_form is not passing the "method" GET parameter. Not being a big ruby user, I'm not certain what the actual proper way to do that with Net::HTTP is, but this works:
require "net/http"
data="apikey=blahblahblah"
response = nil
Net::HTTP.start('us2.api.mailchimp.com', 80) {|http|
response = http.post('/1.3/?method=lists', data)
}
p response.body
That's the lists() method (for simplicity) and you'd have to build up (and urlencode your values!) your the full POST params rather than simply providing the hash.
Did you take a look at the many gems already available for ruby?
http://apidocs.mailchimp.com/downloads/#ruby
The bigger problem, and main reason I'm replying to this, is that your API Key is not obfuscated nearly well enough. Granted I'm used to working with them, but I was able to guess it very quickly. I would suggest immediately going and disabling that key in your account and then editing the post to actually have completely bogus data rather than anything close to the correct key. The list id on the other hand, doesn't matter at all.
You'll be able to use your hash if you convert it to json before passing it to Net::HTTP. The combined code would look something like:
mailchimp = {}
mailchimp['apikey'] = 'APIKEYAPIKEYAPIKEYAPIKEY'
mailchimp['id'] = '8037342dd1874'
mailchimp['email_address'] = "email#gmail.com"
mailchimp['merge_vars[FNAME]'] = "FirstName"
mailchimp['output'] = 'json'
response = nil
Net::HTTP.start('us2.api.mailchimp.com', 80) {|http|
response = http.post('/1.3/?method=listSubscribe', mailchimp.to_json)
}

Resources