Write adapter for microsoft azure in sitemap_generator - ruby-on-rails

I am using sitemap_generator for generating sitemaps in my RoR project.Everything is working fine till now.I am hosting my project on Heroku, which doesn't allow writing to the local filesystem.I still require some write access, because the sitemap files need to be written out before uploading. But I have to use microsoft azure to store my sitemap.The adapters listed in sitemap_generator does not include azure.Could someone point me in the right direction for writing an adapter for azure.
Refering to "Configure carrierwave" in this article I have made a few changes in my code.
But I am not sure only editing the initialiazer file is going to help.In the above article Carrierwave points to the WaveAdapter here which uses CarrierWave::Uploader::Base to upload to any service supported by CarrierWave
config/initializers/azure.rb
Azure.configure do |config|
config.cache_dir = "#{Rails.root}/tmp/"
config.storage = :microsoft_azure
config.permissions = 0666
config.microsoft_azure_credentials = {
:provider => 'azure',
:storage_account_name => 'your account name',
:storage_access_key => 'your key',
}
config.azure_directory = 'container name'
end
Please help!

I copied my setup from the S3 adapter and from Azure's ruby example
Add the azure blob gem to your Gemfile:
gem 'azure-storage-blob'
create config/initializers/sitemap_generator/azure_adapter.rb:
require 'azure/storage/blob'
module SitemapGenerator
# Class for uploading sitemaps to Azure blobs using azure-storage-blob gem.
class AzureAdapter
#
# #option :storage_account_name [String] Your Azure access key id
# #option :storage_access_key [String] Your Azure secret access key
# #option :container [String]
def initialize
#storage_account_name = 'your account name'
#storage_access_key = 'your key'
#container = 'your container name (created already in Azure)'
end
# Call with a SitemapLocation and string data
def write(location, raw_data)
SitemapGenerator::FileAdapter.new.write(location, raw_data)
credentials = {
storage_account_name: #storage_account_name,
storage_access_key: #storage_access_key
}
client = Azure::Storage::Blob::BlobService.create(credentials)
container = #container
content = ::File.open(location.path, 'rb') { |file| file.read }
client.create_block_blob(container, location.filename, content)
end
end
end
Make sure the container you create in Azure is a 'blob' container so the container is not public but the blobs within are.
and then in config/sitemaps.rb:
SitemapGenerator::Sitemap.sitemaps_host = 'https://[your-azure-address].blob.core.windows.net/'
SitemapGenerator::Sitemap.sitemaps_path = '[your-container-name]/'
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AzureAdapter.new
That should do it!

Related

Rails image upload API without save data in database and return name

I want to create one API for image upload using CarrierWave with S3. Normal file upload is working but I want to create one API for upload image and return image URL, not need to the same name in the database table.
How can I do this?
You need to include the following gem in your gemfile,
gem 'aws-sdk', '~> 3'
And use below code in the controller (Using APIS)
require 'aws-sdk-s3'
class Api::V1::UploaderController < ApplicationController
def create
file = uploader_params[:image_url]
file_name = "#{file.original_filename}"
upload_file = file.tempfile
s3 = Aws::S3::Resource.new(region: ENV['AWS_REGION'],access_key_id: ENV['AWS_ACCESS_KEY'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] )
obj = s3.bucket(ENV['AWS_BUCKET_NAME']).object(file_name)
obj.upload_file(upload_file, { acl: 'public-read' })
success(data: obj.public_url, status: 200)
end
end

Rails carrierwave link generated different from s3 storage link

I created a rails api but I have a problem with image upload.
I'm using carrierwave , the upload of picture is working but I get a wrong link.
Example :
This is the link I find in the RESTful api :
https://s3.eu-west-2.amazonaws.com/gpsql/uploads/driver/picture/35/imagename.png
But when I check S3 storage I find a different link :
https://s3.eu-west-2.amazonaws.com/gpsql/gpsql/gpsql/uploads/driver/picture/35/imagename.png
This is initializer for s3 carrierwave :
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: '...', # required
aws_secret_access_key: '...', # required
region: 'us-west-2',
path_style: true,
}
config.fog_directory = 'gpsql' # required
config.asset_host = 'https://s3.eu-west-2.amazonaws.com/gpsql'
config.fog_attributes = {'Cache-Control' => "max-age=#{365.day.to_i}"} # optional, defaults to {}
end
In picture uploader :
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
How can I fix the link that is shown in the RESTful api also why there is so much "bucket name" in amazon link why not something straightforward link/bucketname/image.png
For the first link I find in restful api it doesn't work at all I get access denied or key not found for the second one in amazon s3 it works without any problem.
One of the problem is this
config.asset_host = 'https://s3.eu-west-2.amazonaws.com/gpsql'
it should be
config.asset_host = 'https://s3.eu-west-2.amazonaws.com'
Anyway I don't know why it's repeating twice...
So, if you can you should fix it in the configuration and move the folder in S3 to the proper place
If you can't move it I would try to change the store dir to "gpsql/gpsql/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
I'm not sure if that works but that would be my first step

How to integrate SoundCloud in Ruby on Rails?

I am new to RubyOnRails and SoundCloud.
I want to integrate SoundCloud API in my ruby on rails application.
For this I have registered on SoundCloud And I got the ClientID and ClientSecret. Also I have downloaded the SDK.
Now I have copied the files and folders from lib and spec directory to my applications lib and spec directory. Also I have added gem 'soundcloud' in the Gemfile.
After this I made simple code (copied from doc) in My Interactor:
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => YOUR_CLIENT_ID)
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
But here I'm getting the error -
uninitialized constant MyApp::Interactors::MyInteractor::MyAction::SoundCloud
I followed the steps from APIDoc. Is there any step by step example for integrating SoundCloud in Ruby on Rails so that I can follow?
How can I resolve this error?
MyInteracor.rb
module MyApp
module Interactors
module MyInteractor
class MyAction < Struct.new(:user, :params)
def run
# SoundCloud
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => 'my-client-id')
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
end
end
end
end
end
There's a typo in the soundcloud github page change the line:
client = SoundCloud.new(:client_id => 'my-client-id')
to
client = Soundcloud.new(:client_id => 'my-client-id')
[notice the lowercase c in Soundcloud]
Also you are going to need your client secret for SoundCloud's API to verify you.
Perhaps put client method and in it have client = SoundCloud.new(your-client-id,your-secret-key-your-redirect-uri) in a controller or helper with your client_id, client_secret, and redirect uri values protected in a .env file.
I think by leaving out your redirect_uri and client secret you might be getting this error in MyInteractor.rb
Hope this helps

How do you load credentials in a Ruby controller without storing them in the file?

I am working on a Twilio application using Sinatra. Since I dont have too much experience with Ruby (but am excitedly learning), I am having a problem with separating the credentials from my file. I would like to upload the files to a repository, but I want to keep the sensitive credentials in a separate file that would be imported.
The file is currently composed of:
require 'rubygems'
require 'twilio-ruby'
account_sid = "xxxxxx"
auth_token = "xxxxx"
client = Twilio::REST::Client.new account_sid, auth_token
from = "+12341231234"
friends = {
"+1231231234" => "Lenny"
}
friends.each do |key, value|
client.account.sms.messages.create(
:from => from,
:to => key,
:body => "Hey #{value}, Monkey party at 6PM. Bring Bananas!"
)
puts "Sent message to.#{value}"
end
How would I properly load the account_sid and auth_token lines to a separate file? What is the best practice for storing credentials like this?
Two common practices for this are:
1) Store the variables as environment variables on your system and access them with ENV
account_sid = ENV["TWILIO_ACCOUNT_SID"]
auth_token = ENV["TWILIO_AUTH_TOKEN"]
client = Twilio::REST::Client.new account_sid, auth_token
2) The other is to store them in a YAML file on your server and then when you deploy your application, symlink this file to where it should be in your repository. This file should be in your .gitgnore
#config.yml
twilio:
account_sid: "xxxxx"
auth_token: "xxxxx"
Then in your application
require 'yaml'
config = YAML.load_file("config.yml")
account_sid = config[:twilio][:account_sid]
auth_token = config[:twilio][:auth_token]
There are also several gems for configuration management, the only one I have used personally is figaro but it is rails specific.

Carrierwave & Amazon S3 file downloading/uploading

I have a rails 3 app with an UploadsUploader and a Resource model on which this is mounted. I recently switched to using s3 storage and this has broken my ability to download files using the send_to method. I can enable downloading using the redirect_to method which is just forwarding the user to an authenticated s3 url. I need to authenticate file downloads and I want the url to be http://mydomainname.com/the_file_path or http://mydomainname.com/controller_action_name/id_of_resource so I am assuming I need to use send_to, but is there a way of doing that using the redirect_to method? My current code follows. Resources_controller.rb
def download
resource = Resource.find(params[:id])
if resource.shared_items.find_by_shared_with_id(current_user) or resource.user_id == current_user.id
filename = resource.upload_identifier
send_file "#{Rails.root}/my_bucket_name_here/uploads/#{filename}"
else
flash[:notice] = "You don't have permission to access this file."
redirect_to resources_path
end
end
carrierwave.rb initializer:
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS', # required
:aws_access_key_id => 'xxxx', # copied off the aws site
:aws_secret_access_key => 'xxxx', #
}
config.fog_directory = 'my_bucket_name_here' # required
config.fog_host = 'https://localhost:3000' # optional, defaults to nil
config.fog_public = false # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
end
upload_uploader.rb
class UploadUploader < CarrierWave::Uploader::Base
storage :fog
def store_dir
"uploads"
end
end
All of this throws the error:
Cannot read file
/home/tom/Documents/ruby/rails/circlshare/My_bucket_name_here/uploads/Picture0024.jpg
I have tried reading up about carrierwave, fog, send_to and all of that but everything I have tried hasn't been fruitful as yet. Uploading is working fine and I can see the files in s3 bucket. Using re_direct would be great as the file wouldn't pass through my server. Any help appreciated. Thanks.
Looks like you want to upload to S3, but have not-public URLs. Instead of downloading the file from S3 and using send_file, you can redirect the user to the S3 authenticated URL. This URL will expire and only be valid for a little while (for the user to download).
Check out this thread: http://groups.google.com/group/carrierwave/browse_thread/thread/2f727c77864ac923
Since you're already setting fog_public to false, do you get an authenticated (i.e. signed) url when calling resource.upload_url

Resources