Accessing Word documents in a Rails app - ruby-on-rails

I have a number of documents (mainly Word and Excel) that I'd like to make available to users of my Rails app. However, I've never tried something like this before and was wondering what the best way to do this was? Seeing as there will only be a small number of Word documents, and all will be uploaded by me, do I just store them somewhere in my Rails app (i.e. public/docs or similar) or should I set up a separate FTP and link to that? Perhaps there's an even better way of doing this?

If they're to be publically accessable, you definitely just want to stick them in public somewhere. Write a little helper to generate the URL for you based on however you want to refer to them in your app, for cleanliness (and so if you do change the URL later, for example to bucket your files to keep your directory sizes under control, you don't have to change links all over your app, just in one place.
If, on the other hand, your files are only for logged-in users, you'll need to use something like send_file to do the job, or one of the webserver-specific methods like the X-Sendfile header to check the user is authorised to view the file before sending it back to them.

I would do as you suggested and put them in public/docs. If you are planning on making an overview/index page for the files and link directly to them it would be easier if they were stored locally instead of a remote FTP server. However, since you are the one who will be uploading and maintaining these files, I think you should go with the option that's easiest for you.

Related

iOS - save data so that it is easily accessible outside of the app

Is there any way to save a file (to be exact, a .csv) somewhere outside the application sandbox? From what I've read it seems like it is only possible to save files inside the sandbox.
Maybe I'm thinking about it the wrong way, maybe I don't really need to save it outside the sandbox. What I actually need to do is:
Allow the user to save the file, so that he can use it in other applications (for example email client), and it would be best if the file would stay on his device after he deleted the app. The location of the saved file doesn't really matter, it could be chosen by user with some file picker or hard-coded. Is there any way to achieve this?
I'm using xamarin.forms so solution easy to implement in xamarin.forms would be much appreciated.
From what I've read it seems like it is only possible to save files inside the sandbox.
That is the general idea. You don't just have access to the filesystem on iOS. You could work around this by maybe saving it to iCloud or Dropbox, etc. depending on your use-case but basically you can't just save it somewhere common. Normally, you would then implement the 'share' functionality. What happens then is that iOS copies the file into the other apps' sandbox so it can work with it.

How to manage files uploaded by users?

I have a web app which uses nginx. Suppose it's in Rails, but it doesn't really matter.
I'm planning to have around a hundred of pictures/files uploaded every day by users. I don't want to use any custom solution for storying and uploading images and instead I want to manage that myself.
1) Is there an idiomatic place/path where I should store those images? Or will any path within the reach of nginx will work?
2) Should it be a separate folder from the one that I'm use for storying images for CSS?
3) How would I organize folders forest? That is, should it be something like /my_base_image_folder/{year}/{month}/{day}/{image_sequence_number}.jpg?
Or maybe /my_base_image_folder/{article_id}/{image_sequence_number}.jpg? Or should I put them in the same folder `/my_base_image_folder/{img_guid}.jpg?
And why?
4) What's a recommended solution for naming uploading files? GUID? Or a sequence number?
It all depends on your use case for consuming those images again. If you're planning to retrieve images uploaded by the users for those users on later sessions, ie., if your users have to browse through their images in your application, it's better to store it in a_public_folder/user_id_hashed/. If you're planning to retrieve images based on the uploaded time or date, it's better if you go with a_public_folder/year/month/day/... Make sure the public folder is accessible by your ngnix by using not-too-open permission, just to be safe. Also, naming the image files, a combination of timestamp and a small random hex should do I guess, no big deal.

Storage of user data

When looking at how websites such as Facebook stores profile images, the URLs seem to use randomly generated value. For example, Google's Facebook page's profile picture page has the following URL:
https://scontent-lhr3-1.xx.fbcdn.net/hprofile-xft1/v/t1.0-1/p160x160/11990418_442606765926870_215300303224956260_n.png?oh=28cb5dd4717b7174eed44ca5279a2e37&oe=579938A8
However why not just organise it like so:
https://scontent-lhr3-1.xx.fbcdn.net/{{ profile_id }}/50x50.png
Clearly this would be much easier in terms of storage and simplicity. Am I missing something? Thanks.
Companies like Facebook have fairly intense CDNs. They may look like randomly generated urls but they aren't, each individual route is on purpose and programed to be handled in that manner.
They aren't after simplicity of storage like you would be if you were just using a FTP to connect to a basic marketing website server. While you may put all your images in a /images folder, Facebook is much too complex for this. Dozens of different types of applications accessing hundreds if not thousands of CDNs and servers world wide.
If you ever build a web app, such as a Ruby on Rails app, and you work with a services such as AWS (Amazon Web Services) you'll also encounter what seems like nonsensical urls. But it's all part of the fast delivery network provided within the architecture. Every time you "push" your app up to the server new urls are generated for each unique resource automatically, css files, JavaScript files, image files, etc all dynamically created. You don't have to type in each of these unique urls individually each time you publish the app, the code simply knows where to look for those as a part of the publishing process.
Example: you tell the web app to look for
//= require jquery
and it returns you http://example.com/assets/jquery-eb3e278249152b5b5d5170b73d9dbf52.js?body=1 in your header.
It doesn't matter that the url is more complex than it should be, the application recognizes it, and that's all that matters.
Simply put, I think it can boil down to two main reasons: Security and Cache:
Security - Adding these long unpredictable hashes prevent others from guessing photo URLs and makes it pretty hard to download photos you aren't supposed to.
Consider what would happen if I could easily guess your profile photo URL and download it, even when you explicitly chose to share it only with friends.
Cache - by adding "random" query params to each photo, you make sure each photo instance gets its own URL. Thus you can store the photo in browser's cache for a long time, knowing that whenever you replace it with a new one, the new photo will have a fresh URL and the browser won't keep showing you the old photo.
If you were to keep the same URL for each user's profile photo (e.g. https://scontent-lhr3-1.xx.fbcdn.net/{{ profile_id }}/50x50.png), and then upload a new photo, either one of these can happen:
If you stored the photo in browser's cache for a long time, the browser will keep showing you the cached version (as long as URL is the same, and cache hasn't expired, there's no need to re-download the image).
If, instead, you only keep the image in cache for short period of time, you end up hitting your server much more then actually needed, increasing the load and hurting performance.
I hope this clarifies it.
With your route scheme, how would you avoid strangers to access the pictures of a private account? The hash also prevent bots to downloads all the pictures.
I get your pain :-) I might not stay with describing how this problem could appear more, but rather let me speak of a solution. Well it is normal that in general code while dealing with hashed value or even base64ed value it seems likes mess to deal with, but with an identifier to explain along, it does not remain much!
I use to work in a company where we use to collate Facebook post, using Graph API get its Insights Object and extract information from it for easy passing around within UI and sending back to our Redis cache store; and once we defined a data-structure in TaffyDB how an object organization is going to look like, everything just made sense with its ability to query the useful finite from long junk looking stream of minified Javascript stream
Refer: http://www.taffydb.com/
The extra values in the URL are useful to:
Track access. This is like when a newspaper appends "&homepage" vs. "&email" to an article URL, so their system knows how a reader found the page.
Avoid abuse and control access. Imagine that a user loaded a small, popular pornographic image into a profile image. They could then hijack the CDN to be a free web host for their porn site. But that code is used internally by the CDN to limit the number of views.

iOS app that creates HTML5 content

I'm trying to do something a bit complicated and I'm not entirely sure how to go about it. Could you please give me some pointers on the tech I should use and how I should go about implementing this. Here's what I need to do:
Create an iOS app that allows the user to upload pictures from his camera roll and modify variables with sliders. (so far so good)
These variables and graphics are used to modify some htlm5 code (i.e. the graphics the user supplies are called by the hmtl code and the variables modify some set variables in the script) (Do I just edit the code as a string?)
The code is put together and uploaded to a server where it is accessible at a unique URL. The user can save multiple times and each time it creates a new URL. (Do I need an FTP here?)
Your question is too general, but as far as I can help, Yes you have to create and edit some html source texts, and append every object that user is adding to the page as some html codes, files, css, etc.
and for uploading, if you want the user to upload the site to his/her own ftp server or web hosting service, yes you need FTP connection to create with the server.
But if you want your user to upload the website to a space you're providing for the user, then you need some server part and maybe some APIs. then you may use FTP or even some APIs to create and update files on your server. It highly depends on the service you want to provide.

Keeping users uploaded documents private

I believe this question is platform/technology independent, however I am using Ruby on Rails with the carrierwave gem.
Users upload documents to my site, and I need to keep them private. I am exploring the different options available to me, along with their advantages and disadvantages.
Option 1
Obfuscate urls to images to make them impossible to guess.
This would be relatively simple to implement and fast to serve up. However, if a url was made public by whatever means, security is lost.
Option 2
Have documents accessed through some sort of intermediate step that requires authentication. This would have improved security over option 1, but would place additional load on the server. A page containing previews of a number of uploaded documents would hammer the server.
Are there any other options available to me? Have I made any mistakes with my claims, or missed any important points?
I think the best option you have is to have a "key" for your documents. You can generate a key, with a certain lifetime, and when you go on /document/name/access_key, you find the record matching and return the file associated with the record. Never exposing the real URL.

Resources