Realtime shared folder on RoR - ruby-on-rails

I'm working on an intranet for a school, I would like to set up online folders for students, some kind of Google Drive-ish folder, one for each class.
So far, I managed to create it, but I would like to add some improvements.
Basically, each Class has many Resources, and each Resource has an attached file (with Paperclip). So, for now, I'm using Dropzone, and each time a student uplaods a file, it works just fine, but other student have to refresh to see the file.
I was wondering if there was a way to upload resources in real-time, so that everytime a student uploads a file, all other students can see it appear as soon as it is uploaded.
I searched for a bit, on one hand, I have the Publish/Subscribe which appears to bring some kind of realtime, but only for messengers-like applications, and on the other hand, I got some gems, like Remotipart, which allow to upload files asynchronously.
Is there a way to combine both ?
I'm using RoR 4

By using Remotipart, only the student who uploads the document can see the uploaded data & no other students can see it. You can do a patch by polling.Hit a Ajax request after few seconds which will fetch the data from the server & append it on the HTML

Related

RAILS -how to allow user to add music/spotify playlists to their personal page?

For a ruby on rails school project(no intention to use publicly), I want to allow users to upload music playlist to their page, using something like spotify/soundcloud, Any ideas on how to implement this?
Mainly how to give the user the ability to choose what to add on their page, (eg. how instagram user upload an image, here user can upload their own songs/external playlists)
(user history is not important)
If you want to give the user the ability to upload an actual mp3 file (or similar), you should look into ActiveStorage/Paperclip/Carrierwave/Shrine. ActiveStorage is closely coupled with Rails so it might be the easiest to get started with.
If you use ActiveStorage you won't have to write the associations or the file fields; it'll do that for you. You'll simply have to drop in has_many_attached, and given your file field is called Song, it'll look something like:
class User < ApplicationRecord
has_many_attached :songs
end
To start locally, you can configure your Rails app to just use your local storage; you don't need to get messy with any remote storage until you need to (e.g. production).
On the user's profile (given they have one), you can simply reference the songs, such as:
#user.songs.each do ... end
Rails is really scary at first. It's opinionated and overwhelming. If you need more direction my email's in my profile :) I'm n00b friendly.
two different things here:
so for Spotify, you'd need to go through a system like TuneCore or another means to get source files in there. I think Soundcloud would probably get you there, but you could just have people upload to your site with Carrierwave. For audio processing, you will need to do some server work to make sure you have the packages (LAME is required for MP3 encoding. I know, silly name).
https://github.com/carrierwaveuploader/carrierwave
https://github.com/TrevorHinesley/carrierwave-audio
This would also allow you to have people upload their own profile picture or other images, etc.
From there, you can have any fields you like on a profile. If you want to embed an instagram feed, etc. you'll need to tackle each one of those as you go. I'd start with the core piece, get that right, and then enhance.

ASP.NET MVC upload file containing objects

I have a directory that contains a csv file and avatar images.
The contents of csv file are as
Id Name Avatar Dept School
1 Mark 01019.jpg Market None
2 John 21122.jpg Business None
3 Sam 33311.jpg IT None
....
....
50 James 9823.jpg IT USA
The avatar images are placed in the same folder of csv file.
What I want is that when a user uploads csv file, then the info in file is converted into business objects, say Person. I can upload and parse the csv to get Id, Name, Dept, School, but ofcourse cant make it upload avatar images (in the csv file) to server, in same web request.
What are the possible ways to achieve this? Assume that I want to avoid zipping all images+csv in a single .zip file and then upload it on server.
Thanks.
I just love when people end their question by excluding the only possible solution.
The server (where your web application is running) has no direct access to the client (where the files are). The only thing the server can work with is what the client chooses to give it. So, your option is to have the user upload each image file invidually, along with the CSV, or to zip it all up, so they can send everything in a single upload. That's it. Period. At least with a standard web page.
You can of course create a Java applet or a Flash application that the user would authorize to access their filesystem to retrieve the necessary files. Essentially, the process is still the same, it's just the Java/Flash app would automatically do the file uploads instead of requiring the user to manually do them. However, both Java (on the web) and Flash are all but dead technologies at this point, so by using either of those, you're creating a dependency on something that is constantly exploited and not guaranteed to continue to receive security patches for the life of your application. Flash, in particular, has already been end-of-lifed, so Adobe will abandon support entirely within the next few years, max.
Long and short, tell your user to zip it up and upload a zip file.

Rails newbie - how to structure a calendar generating app

I'm working on a service to provide our students and faculty with one single calendar (ICS subscription) of their academic dates (start and end of term & exam periods, class dates and times, exam dates and times, etc). I'm a Ruby and Rails newbie; we're starting to work more with it here so I figured this would be a good learning opportunity. I'm having trouble figuring out how to structure and model (if at all) certain parts of the app.
The app is conceptually pretty basic:
User logs in and a user record is created for them. A UUID is generated and stored on the user's record; it's used to generate their ICS URL (http://myservice.foo/feeds/johndoe_ce4970706f320130588b109add5c7cb0.ics).
When the user requests their ICS file (through the above URL), I need to query a bunch of different systems in order to get information in order to build a calendar:
The Student Information System (SIS) contains the user's schedule (e.g. johndoe is taking ENGL 100 on MWF from 10:30 - 11:20). I need to parse this data and create events.
Our online learning management system, Canvas, provides a calendar of assignments for courses contained inside it. It's accessible as an ICS file, so I need to pull down that file, parse it and include it in the "master" calendar that my app will generate.
Instructors can specify an additional ICS URL for their course so that they can include arbitrary events not provided by either of the two above sources. Like the Canvas calendar, I need to download and parse that ICS.
I have the first part working; I can log in through our single sign-on system (CAS) and a user record is created with a generated UUID. I'm not sure how to handle the second part, though. I don't need to store much permanent data; basically, I only need to keep around the user record (which contains their username, the generated UUID, and some access tokens for the Canvas LMS). The feed will be generated the first time it's requested, cached for some period (and regenerated on-demand when needed).
Where should I be putting the parsing and generating code? I'd like it to be somewhat modular as I expect that we'd be adding other data sources as they crop up. Should I be creating calendar and event models if I'm not actually persisting that data?
No, there is no need to create an empty model for interaction with 3rd party services. I had a similar problem, where I needed to receive data from an external service and wanted it to be modular. One of recommended solutions I found was to create a class (that handles business logic of the interaction with the external service) in the "lib" folder under the root directory of your rails project.
It later can be required in your controller and used to receive date from the third party service. Or if you want it autoloaded, then you can add path to lib directory in your application.rb file under config.autoload_paths setting.

Nested forms, inline uploads, and progress bars with Carrierwave in Rails

I have rather esoteric usecase for nested forms, multi-file uploads, and progress bars in Rails. I haven't found any online discussions about precisely about this so far. If I have overlooked something, I am sorry. Please correct me.
Here is what I want:
A given form has multiple dynamic fields. One of which is 'attach a file'.
For this 'Attach a file', I would like an interface which is essentially similar to gmail.
That interface enables you to :
click 'attach file'.
select a local file, which starts uploading immediately in the background, giving you a progress bar in the mean time.
this allows you to write your message, or add more files.
You can cancel a live upload and even delete attachments after the fact by un-checking a box.
Here are the models and associations I am working with.
I have a model Recording which has many AudioFiles.
Each AudioFile contains audio data, as well as metadata like size, type, date created etc.
A Recording has several other child collections as well.
Here is how the 'Create Recording' form should behave:
It should enable the user to add multiple number of child fields, including multiple audio files..
So far, I am using the excellent Nested Form (https://github.com/ryanb/nested_form) gem to create the non-AudioFile children of a Recording. IT works brilliantly.
What I want is to be able to have similar nested fields to upload multiple audio files, asynchronously, with progress indicators, and with an ability to cancel or delete uploaded files.
There are many resources which demonstrate how to use uploaders in conjunction with carrierwave to store files with progress information. For instance, https://github.com/yortz/carrierwave_jquery_file_upload, and https://github.com/blueimp/jQuery-File-Upload/wiki/Rails-setup-for-V5 .
Essentially, what these examples do is to generate a request from one of these uploaders which is directed to a controller create action for a model which has a carrierwave uploader attached to it. I have got this much to work OK.
What I can't figure out is how to do this in a nested form context. The tricky bits are:
Suppose I write up the AJAX to do a post from a 'Create Recording' form, and have that post create a new AudioFile record. How do I associate that audio file with the as-yet-un-created recording?
If the user aborts the transaction, how will the AudioFile record thus created be cleaned up?
I can think of hacky-ways to do both of the above, but I am wondering if there are more elegant approaches. I am rather new to rails so I am guessing that I am not using it to the fullest.
Thanks,
Apurva
I thought I would contribute back to the community by sharing how I solved this problem.
To summarize, the major problem was to reconcile the behavior of CarrierWave, nested forms, and fine grained control of file uploads.
The crux of the issue was that Nested Forms create the root record and all its associations in a single POST operation to the #create action of the root Controller.
In the example above, the Recording model was the root, while AudioFile, Note, and Categorization were the associations to be created along with a Recording.
So with Nested Forms, I would have to create all these records in a single POST, which would preclude the possibility of canceling uploads in isolation, or uploading in parallel with adding other fields (like Notes).
That would not make for a good user experience. My solution was really simple:
I chose not to use nested forms.
Recording#create would always be called with empty parameters. The Recording attributes would get sensible default values in the create operation.
The user would only see the Recording#edit page.
On the Recording#edit page, I had independent controls for CRUD operations on the associated models which would route to different controllers through AJAX calls. This worked because each associated model had a valid recording_id to use.
The various controllers would return HTML fragments which would be written into the main recording page.
This enabled inline editing of all the fields on the Recording page, even though these fields mapped to different (associated) models. Thus the user would be able to upload multiple files, add notes while they were uploading, play back already uploaded files, and cancel uploads at will.
As a result the whole user experience was a lot smoother. This would never have been achievable with Nested forms by definition.

App for signing PDF's and categorizing them on a webserver

I've been researching the best way to implement an application for my brother's business, and have been pretty stumped in terms of how to structure my application. The application will be run on iPad 2's deployed in the field, sometimes without readily available network access (due to spotty cell coverage in the area).
Here is the abstract on what it needs to do:
1) Load a template PDF file (its a contract to sign up for what is basically cable service) that has editable fields, such as:
a) Name b) Street address c) Dates
2) be able to collect a drawn signature (very similar to any credit card app, such as Square, etc), which is then overlaid onto the PDF.
3) Save the PDF, containing drawn signature and other edited fields, as a new file. Then, upload it to a backend server, using the name of the individual and date/time as meta data for sorting into specific folders.
Without this third aspect, an employee would have to spend 30 minutes to 2 hours a day categorizing all of the app submissions, so step number 3 is a pretty important aspect to the development, even though most of the work is outside the realm of objective C. Still, i need to send the PDF file off with as much information attached to it as I can...
I'd appreciate any guidance related to the best course of action in developing this. Are there any open source applications that you guys know of that I can reference to? I have searched Apple's Developer member center and Google to no avail.
How could i implement iText properly here? Is that even the best option?? It does digital signatures as opposed to those drawn with UI Kit...
Sounds like you should have a web service with a database for storing the meta information and the path to the generated PDF with the signature and other entries.
Your app would essentially generate the PDF, make a web service call and insert information such as the client's name, date/time, whatever else you want, and then the name or path of the PDF file. The PDF file would subsequently be uploaded to a designated location with a unique file name to prevent overwriting another PDF. You could formulate the name of the file off of the corresponding Key/Id of the record in the database or you could use a GUID as the filename and for good measure concatenate the EPOCH timestamp when the file was generated. Both approaches should guarantee filename uniqueness. Another possible file name scheme Device UUID+epoch timestamp, many options available.
If you have to actually edit the PDFs, it sounds like a pretty hard requirement. Another approach would be to show the user what they need to see (ie what they have to sign) and then generate the PDF with the signature and fields populated. Since you want to upload it anyway you would probably save yourself headaches if you offload this from the iPad and do it using a remote server (as Chris suggested) generating the PDF as you need it. I've been involved in helping out an iPad app development doing property inspections - it used Docmosis to do the document generation in preview and then in submitted forms. Hope that helps even though it's a few months down the track.

Resources