New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Export user photos #5685
Export user photos #5685
Conversation
I fear there's a lot more to consider to this. Let's start with some assorted points that immediately pop into my mind.
|
You can have a look at how this is handled by #5499 |
#5499 at least backgrounds the work and sends a mail, it doesn't have an optimal UI flow either yet nor any cleanup. |
How about: an alert that the job may take some time, and then the user gets a notification in the usual way when the export is ready, with a download link. The export could be kept until downloaded (perhaps up to a maximum time). |
I'm gonna try to create a output stream. If can't, I'm gonna use #5499 method so user see same behavior for both exports. |
Best approach to stream a zip file is using https://github.com/fringd/zipline but it's not ported to rails 4 yet. :-( |
d251037
to
50dd131
Compare
Done: used #5499 way of export data. Comments are very welcome. |
|
||
Zip::ZipFile.open(export.path, Zip::File::CREATE) do |zipfile| | ||
photos.each do |photo| | ||
photo_path = "#{Rails.root}/public/uploads/images/#{photo.remote_photo_name}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't assume that, it might be hosted on S3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't then PR #5499 requires review as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! You're talking about line 331. I thought you were talking about line 317.
I assume that files are stored in same machine as web server. :-(
50dd131
to
281cafd
Compare
New try. In this opportunity I'm assuming files could not be in local file system. |
photos.each do |photo| | ||
temp_photo = Tempfile.new(photo.remote_photo_name, encoding: 'ascii-8bit') | ||
begin | ||
photo_path = "#{Rails.root}/public/uploads/images/#{photo.remote_photo_name}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but Rails.root
does not give you the upload location or even the sites domain or anything, it gives you the absolute path on the filesystem where the application is located, so this still doesn't work for stuff stored on S3.
I would give you more pointers, but I'm myself very unsure about what the best way to handle that case would be.
281cafd
to
e6ee9f8
Compare
New try. In this opportunity, photo file is gotten through unprocessed photo uploader. |
This PR is related to #5343 |
begin | ||
zos.put_next_entry(photo.remote_photo_name) | ||
zos.print(photo.unprocessed_image.file.read) | ||
rescue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a more specific exception that you expect? Or even a better, a way to guard the code raising to from running in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If file doesn't exists it returns Errno::ENOENT.
31712a2
to
5a36b0f
Compare
Done: redirecting when download_photos is called. In this case, filename should be unguessable. Then new request are stored with random filename. |
def secure_token(length=16) | ||
var = :"@#{mounted_as}_secure_token" | ||
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.hex(length/2)) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just 16**6
combinations, I see no reason to limit it that much.
5a36b0f
to
236103e
Compare
Filename token increased to 128bits. |
c3105b2
to
dda3d3b
Compare
7f63fd2
to
5141c0a
Compare
Re-based and code updated for new gems. Need review. Thanks! |
Zip::ZipOutputStream.open(temp_zip.path) do |zos| | ||
photos.each do |photo| | ||
begin | ||
photo_data = photo.unprocessed_image.file.read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good so far, I guess we just have to see how it behaves on S3 (+ Heroku) setup. I still don't understand how this call pulls the photo from S3 tbh. If you're able to clarify that... :)
Another last small remark I have is moving the temp_zip.close
below to an ensure
block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what a thought:
- If I delete a post with a photo in it, photo file is deleted from my disc.
- I don't found code that delete (unlink) the file. So there's an object that knows what to do.
- The uploader field may know where to upload and to delete it.
- If so, it may also know where to read it.
- I tried it and worked, at least in my local file system.
- I found that admin can choose where to store files by setting carrierwave config file. I didn't try over S3. Amazon wants my credit card number for a free account and... no, darling.
What I really want to know is how to create a test to simulate a S3 storage. Do you have a sample code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I don't have an example test for that, I'm actually not sure whether it's testable, I guess one could enable hosting on S3 in the test and then webmock should catch the network call.
Hit me up on IRC if you want credentials to a S3 bucket for your tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I fixed the S3 access ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you did. :)
Downloads work as expected, but having problem with upload. CarrierWave use same file name of downloaded image for the new uploaded zip. So upload fails saying "You can't upload a jpg. A zip expected" :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good. This capture confirms that one export file is maintained.
5141c0a
to
b154d87
Compare
New changes
These changed were successfully tested in AWS S3. |
Alright, thank you! |
Nice, thank you! |
UHU! Thank you too! |
Hey, thanks very much, @margori! |
My solution for bug #1802
Implemented "Export photos" button in user settings, currently disabled.
I'm using 'zip' files instead of 'tar', 'cause it's widely known and easily handled.