TypeError (can't cast File): Rails Carrierwave File upload - ruby-on-rails-5

I am using Carrierwave and Rails getting the following error while uploading a file.
Started POST "/upload_client_input_file?project_id=7" for 192.168.1.101 at 2018-08-06 10:46:43 +0530
Processing by InputFilesController#upload_client_input_file as /
Parameters: {"file"=>#, #original_filename="input.csv.part_1.1", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"file\"; filename=\"input.csv.part_1.1\"\r\nContent-Type: application/octet-stream\r\n">, "project_id"=>"7"}
Completed 500 Internal Server Error in 27ms (ActiveRecord: 7.9ms)
TypeError (can't cast File):
app/controllers/input_files_controller.rb:61:in `upload_client_input_file'
My model code:
class InputFile < ApplicationRecord
belongs_to :project
mount_uploader :file, AvatarUploader
end
My uploader code:
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_whitelist
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
My Controller code:
def upload_client_input_file
params.permit!
project_id = params["project_id"]
tempfile = params["file"].tempfile
file = CSV.read(tempfile)
input_file_id = InputFile.find_or_create_by(batch_name: "Test", flag: true, project_id: project_id, file: File.open(tempfile,"r")).id
end

Related

Update ListView dynamically when Log file updated

I have a log file in .txt format, that is being updated continuously. Then I want to show the file content in ListView (PyQt5) dynamically
Use a QFileSystemWatcher to detect when you file has been modified.
A quick example:
class LogWatcher(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.watcher = QFileSystemWatcher()
self.watcher.addPath("./foobar.txt") # The file you want to check
self.watcher.fileChanged.connect(self.displayLine)
def displayLine(self, path): # Will be called when the file has changed
print(path, "has changed")
if __name__ == '__main__':
app = QtWidgets.QApplication([])
logger = LogWatcher()
sys.exit(app.exec_())
Each time the file foobar.txt changes, the method displayLine is called

Converting request form data ( images) to bytes

I'm getting formdata from my client side, this is a image data. On the backend I have a flask server running in which I have to convert this data to numpy array so that I can pass this value to my process function(basically a model that takes blur images and converts into better quality)
I have tried whole lot different options, such as tried to convert the data into bytes, cv2 file read etc. I have been stuck on this for a while. Any direction is appreciated
const fd = new FormData();
fd.append("project", this.imgUrl);
const options = {
method: "POST",
body: fd,
};
// delete options.headers["Content-Type"];
fetch("http://172.16.1.34:1234/api/test", options)
.then(res => res)
.then(res => {
console.log(res);
})
.catch(err => console.log(err));
}
def test():
# if request.method == 'POST':
# print('Here')
# print(request.files)
# something = request.form['project']
# print(something)
#
# print(type(something))
# print(len(something))
# img = cv2.imread(something)
# image = process_image(img)
# print("im here")
if request.method == 'POST':
print("inside")
photo = request.form['project']
print(photo)
# try:
# delete_files("./temp_results")
# except:
# pass
# filename = secure_filename(image.filename)
# image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
#
# img_name = os.listdir("./temp_results")[0]
#
# image = cv2.imread('./temp_results/' + img_name)
# print(image.shape)
# # processed_image = process_image(image)
# scipy.misc.imsave("./temp_results/temp.png", processed_image)
return jsonify({'Hello': True})
# scipy.misc.imsave(image,'./temp_results/temp.png')
# return send_file("./temp_results/temp.png", attachment_filename='temp.png')
I want to convert this form data into numpy array

Disable or Bypass login of odoo when trying to hit from external application

I am trying to open odoo url from my hosted application but its redirecting to login screen. As user is already logged in to my application logically user should not be redirected to login screen again...How can I bypass this security check of odoo???
Thanks In advance
From your question, I think what you are trying to achieve is to authenticate your user's odoo session automatically if that user is already authenticated in your non-odoo application. To achieve that, you can implement your application such that, on authentication of a user, your backend will authenticate a session in odoo with corresponding user, and set session_id cookie of user's browser to that authenticated session_id. I guess that may be achievable if both application are served under same domain with reverse proxying using nginx or apache, as other's already commented, there is no way you can totally disable or bypass authentication of odoo itself, as this is a well developed business related software, and that will just defeat it's purpose.
It is possible to bypass the security of odoo. These changes are required in these two files
`
**server/odoo/http.py**
line number 406 in odoo 12
def validate_csrf(self, csrf):
# if not csrf:
# return False
#
# try:
# hm, _, max_ts = str(csrf).rpartition('o')
# except UnicodeEncodeError:
# return False
#
# if max_ts:
# try:
# if int(max_ts) < int(time.time()):
# return False
# except ValueError:
# return False
#
# token = self.session.sid
#
# msg = '%s%s' % (token, max_ts)
# secret = self.env['ir.config_parameter'].sudo().get_param('database.secret')
# assert secret, "CSRF protection requires a configured database secret"
# hm_expected = hmac.new(secret.encode('ascii'), msg.encode('utf-8'), hashlib.sha1).hexdigest()
# return consteq(hm, hm_expected)
return True
def setup_session(self, httprequest):
explicit_session = True
# recover or create session
# session_gc(self.session_store)
#
# sid = httprequest.args.get('session_id')
# explicit_session = True
# if not sid:
# sid = httprequest.headers.get("X-Openerp-Session-Id")
# if not sid:
# sid = httprequest.cookies.get('session_id')
# explicit_session = False
# if sid is None:
# httprequest.session = self.session_store.new()
# else:
# httprequest.session = self.session_store.get(sid)
httprequest.session = self.session_store.new()
httprequest.session.uid =2
httprequest.session.login = 'root'
httprequest.session.db = 'odoo'
httprequest.session.sid = '7aa5500f30365aead781465ec08bbb03c3a5024b'
return explicit_session
line number 1348
def setup_session(self, httprequest):
explicit_session = True
# recover or create session
# session_gc(self.session_store)
#
# sid = httprequest.args.get('session_id')
# explicit_session = True
# if not sid:
# sid = httprequest.headers.get("X-Openerp-Session-Id")
# if not sid:
# sid = httprequest.cookies.get('session_id')
# explicit_session = False
# if sid is None:
# httprequest.session = self.session_store.new()
# else:
# httprequest.session = self.session_store.get(sid)
httprequest.session = self.session_store.new()
httprequest.session.uid =2
httprequest.session.login = 'root'
httprequest.session.db = 'odoo'
httprequest.session.sid = '7aa5500f30365aead781465ec08bbb03c3a5024b'
return explicit_session
**server/odoo/service/security.py**
line number 18
def check_session(session, env):
# self = env['res.users'].browse(session.uid)
# expected = self._compute_session_token(session.sid)
# if expected and odoo.tools.misc.consteq(expected, session.session_token):
# return True
# self._invalidate_session_cache()
return True

CarrierWave isn't uploading image

I am trying to upload user profile picture from my application to a centralized application using carrierwave gem. In params avatar is getting passed but not getting updated.
Here my applicaton log:
Started PATCH "/api/v1/users/47" for ::1 at 2018-07-01 13:45:14 +0530
Processing by Api::V1::UsersController#update as JSON
Parameters: {"user"=>{"avatar"=>#<ActionDispatch::Http::UploadedFile:0x00007f7c7cda6e20 #tempfile=#<Tempfile:/tmp/RackMultipart20180701-10347-otl55f.jpg>, #original_filename="leotolstoy1.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"leotolstoy1.jpg\"\r\nContent-Type: image/jpeg\r\n">, "first_name"=>"Mayuresh"}, "id"=>"47"}
And centralized application log:
Started POST "/api/v1/users/update" for 127.0.0.1 at 2018-07-01 13:45:15 +0530
Processing by Api::V1::UsersController#update as */*
Parameters: {"first_name"=>"Mayuresh", "last_name"=>nil, "avatar"=>{"tempfile"=>"#<File:0x00007f7c7c6ba468>", "original_filename"=>"leotolstoy1.jpg", "content_type"=>"image/jpeg", "headers"=>"Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"leotolstoy1.jpg\"\r\nContent-Type: image/jpeg\r\n"}, "user"=>{"first_name"=>"Mayuresh", "last_name"=>nil, "avatar"=>{"tempfile"=>"#<File:0x00007f7c7c6ba468>", "original_filename"=>"leotolstoy1.jpg", "content_type"=>"image/jpeg", "headers"=>"Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"leotolstoy1.jpg\"\r\nContent-Type: image/jpeg\r\n"}}}
Application Load (0.4ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."secret" = $1 ORDER BY "oauth_applications"."id" ASC LIMIT $2 [["secret", "<secret_token>"], ["LIMIT", 1]]
AccessToken Load (0.4ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."active" = $1 AND "oauth_access_tokens"."token" = $2 ORDER BY "oauth_access_tokens"."id" ASC LIMIT $3 [["active", true], ["token", "<access_token>"], ["LIMIT", 1]]
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(1.8ms) BEGIN
User Exists (1.5ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND ("users"."id" != $2) AND "users"."type" = $3 LIMIT $4 [["email", "<email>"], ["id", 1], ["type", "User"], ["LIMIT", 1]]
SQL (0.4ms) UPDATE "users" SET "first_name" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["first_name", "Mayuresh"], ["updated_at", 2018-07-01 08:15:15 UTC], ["id", 1]]
(12.7ms) COMMIT
As you can see only first name is getting updated not avatar.
Avatar uploader in centralized application:
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
# "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
'tmp/upload/'
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w(jpg jpeg png)
end
def content_type_whitelist
/image\//
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
Even if I am trying to update from rails console at centralized application, it is not getting updated.
2.3.4 :049 > user.update avatar: 'https://static1.squarespace.com/static/586af0132994caa37cca0067/5876e27f9f74561d8c5ce4df/5876e296c534a514869fe56e/1484187414154/Tree+On+The+Bank.jpg'
(0.7ms) BEGIN
User Exists (0.8ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 AND ("users"."id" != $2) AND "users"."type" = $3 LIMIT $4 [["email", "<email>"], ["id", 1], ["type", "User"], ["LIMIT", 1]]
SQL (0.4ms) UPDATE "users" SET "updated_at" = $1, "avatar" = $2 WHERE "users"."id" = $3 [["updated_at", 2018-07-01 07:39:16 UTC], ["avatar", "abc.jpg"], ["id", 1]]
(13.4ms) COMMIT
=> true
Not able in figuring out what is wrong here.
The problem was that file object which was getting passed to centralized application was not the original file object because as per code I was converting parameters to json and then was making connection through faraday to connect to centralized application.
What I did is made a separate faraday connection for uploading files and passed parameters as it is in payload as below:
conn = Faraday.new url: url do |f|
f.request :multipart
f.request :url_encoded
f.adapter Faraday.default_adapter
end
payload = { avatar: Faraday::UploadIO.new(update_params[:avatar], update_params[:avatar].content_type, update_params[:avatar].original_filename) }
conn.put '/api/v1/users/update', payload
Now my application parameters:
Started PATCH "/api/v1/users/47" for ::1 at 2018-07-01 13:45:14 +0530
Processing by Api::V1::UsersController#update as JSON
Parameters: {"user"=>{"avatar"=>#<ActionDispatch::Http::UploadedFile:0x00007f7c7cda6e20 #tempfile=#<Tempfile:/tmp/RackMultipart20180701-10347-otl55f.jpg>, #original_filename="leotolstoy1.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"leotolstoy1.jpg\"\r\nContent-Type: image/jpeg\r\n">, "first_name"=>"Mayuresh"}, "id"=>"47"}
And centralized application parameters:
Started PUT "/api/v1/users/update" for 127.0.0.1 at 2018-07-05 02:12:04 +0530
Processing by Api::V1::UsersController#update as */*
Parameters: {"avatar"=>#<ActionDispatch::Http::UploadedFile:0x0000000775e1d8 #tempfile=#<Tempfile:/tmp/RackMultipart20180705-23054-1cbcry3.png>, #original_filename="nio.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"avatar\"; filename=\"leotolstoy1.jpg\"\r\nContent-Length: 272286\r\nContent-Type: image/png\r\nContent-Transfer-Encoding: binary\r\n">}
As you can see avatar parameter is actual ActionDispatch object and that's why images are getting uploaded properly.
And for remote url's I got solution here. It will be done as below:
2.3.4 :049 > user.update remote_avatar_url: 'https://static1.squarespace.com/static/586af0132994caa37cca0067/5876e27f9f74561d8c5ce4df/5876e296c534a514869fe56e/1484187414154/Tree+On+The+Bank.jpg'

Carrierwave: how to crop and resize so that the final picture has exactly the same width and height?

I'm using Rails 3 with carrierwave and Rmagick.
I want the picture to be resized exactly to 192 x 135
This seamed simple at first but nothing I tried worked until now.
Anyone found a solution for this? Here is my code for the uploader.
class AvatarUploader < CarrierWave::Uploader::Base
#Include RMagick or MiniMagick support:
include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
def default_url
# # For Rails 3.1+ asset pipeline compatibility:
ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
end
process :resize_to_fit => [250, 250]
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fit => [200, 200]
end
version :medium do
process :resize_to_fit => [250, 250]
end
version :mini do
process :resize_to_fit => [100, nil]
process crop: '100x100+0+0'
end
version :grid do
process :resize_to_fit => [192, 135]
process crop: '192x135+0+0'
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
private
# Simplest way
def crop(geometry)
manipulate! do |img|
img.crop(geometry)
img
end
end
# Resize and crop square from Center
def resize_and_crop(size)
manipulate! do |image|
if image[:width] < image[:height]
remove = ((image[:height] - image[:width])/2).round
image.shave("0x#{remove}")
elsif image[:width] > image[:height]
remove = ((image[:width] - image[:height])/2).round
image.shave("#{remove}x0")
end
image.resize("#{size}x#{size}")
image
end
end
end
Change your line
process :resize_to_fit => [250, 250]
To
process :resize_to_fill => [192, 135]
I asked a similar question about a month ago. Hope this helps! :)