Playing By Programming

My mind has an endless capacity for useless information.

How to Solve a 403 Nginx File Download Permission Error

Once the basic functionality of our assignment.io website was implemented, one of the features that we wanted to implement was file upload and download. The basic upload functionality was surprisingly easy to implement using a gem called CarrierWave. The Github page has a pretty thorough walk-through, but if you’re looking to display the content on your website there is a Railscast on the file upload process. Both will walk you through the steps of setting it up, and it took us about 20 minutes.

File download was a bit more complex. While an individual user would only upload one file to be associated with an assignment, the person who assigned the assignment would probably want a way to download all of the submitted work at once. For this, we implemented a gem called RubyZip. If you’re writing a rails app, you don’t need to require ‘rubygems’, but you DO need to require ‘zip/zip’ in your application.rb file.

The RubyZip documentation(http://rubyzip.sourceforge.net/) is pretty dense, but thorough. With a few modifications, we passed it an array of files, specified the file names, and created a file tree structure so that when the user downloaded the files, they were organized by submitter and named appropriately.

[Submission Model Code] []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def self.zip_files(submissions)
    zipfile_name = "#{Rails.public_path}/download/assignments/assignment_#{submissions.first.user_assignment.assignment.id}.zip"
    File.delete(zipfile_name) if File.exists?(zipfile_name)
    zip_file = Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
      submissions.each do |submission|
        # Two arguments:
        # - The name of the file as it will appear in the archive
        # - The original file, including the path to find it
        file = submission.submitted_file
        if file.path
          filename = file.path.gsub(/.+\/[^\/]/,'')
          zipfile.add("assignment_#{submissions.first.user_assignment.assignment.id}/#{submission.user_assignment.user.name}/#{filename}", file.path) if file.url
        end
      end
    end
    zipfile_name
  end

Everything worked on our local host, but when we deployed to our server we got an Nginx 403 permissions error. Nginx Error Once we SSH’ed into the server, we saw that the file was being created, but while the owner of the file was allowed to read and write the file, no one else could do anything with it.*

Bad Permissions

Much like you can run chmod in your bash window, Ruby also contains a chmod command. By adding one line to our code, we modified our permissions and allowed the user to download the file appropriately.

[Submission Model Code with permissions] []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def self.zip_files(submissions)
    zipfile_name = "#{Rails.public_path}/download/assignments/assignment_#{submissions.first.user_assignment.assignment.id}.zip"
    File.delete(zipfile_name) if File.exists?(zipfile_name)
    zip_file = Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
      submissions.each do |submission|
        # Two arguments:
        # - The name of the file as it will appear in the archive
        # - The original file, including the path to find it
        file = submission.submitted_file
        if file.path
          filename = file.path.gsub(/.+\/[^\/]/,'')
          zipfile.add("assignment_#{submissions.first.user_assignment.assignment.id}/#{submission.user_assignment.user.name}/#{filename}", file.path) if file.url
        end
      end
    end
    File.chmod(0775, zipfile_name)
    zipfile_name
  end

Returning to the server, you can see that the permissions were appropriately modified, and the user can now download the Zip file of all the files for an assignment. Good Permissions The built-in site functionality works as well.

This is a great explanation of file permissions in Unix. For purposes of simplicity, I’ve abstracted away the routing and controller functionality that calls the above method.

How to Create a Github Feed for Your Website

Octocat Rocks

When we were designing our student pages at the Flatiron School, one of our major questions was what to include. As programmers, one of the best ways that we can get noticed is to have our open-source projects available in as many places as we can find them. Github allows you to show your code to the world. The Octopress sidebar has built-in functionality of a list of your current Github repos, but wouldn’t it be cooler to have public activity feed that shows which of your repos have the most current commits?

1. Find your Github RSS key.

Github provides an RSS key to all of your public activity. This format of your key will be:

https://github.com/USERNAME.atom

Replace USERNAME with your username. For example, my public github key would be https://github.com/cjbrock.atom. If you subscribe to your own RSS feed, the key generated will be your private RSS feed. It looks something like this: https://github.com/username.private.actor.atom?token=somehextoken. Unless you would like to expose your private key to the rest of the world, please do not use this key.

How to Fix a RedCloth Error While Installing Octopress

Octopress is a great blogging platform for coders. (Full disclosure: This blog is run on Octopress.) However, when installing, sometimes strange errors come up. A few weeks ago while setting up our blogs, my classmate Jenya ran into a strange RedCloth error while running bundle install following the otherwise very comprehensive setup instructions provided by Octopress.

1
2
An error occured while installing RedCloth (4.2.9), and Bundler cannot continue.
Make sure that `gem install RedCloth -v '4.2.9'` succeeds before bundling.

This was a little intriguing, but not hard to fix. However, after trying to run gem install RedCloth, we got another error.

1
2
3
4
5
6
7
ERROR:  Error installing RedCloth:
ERROR: Failed to build gem native extension.

    /usr/bin/ruby1.9.3 extconf.rb
    /usr/lib/ruby/1.9.3/rubygems/custom_require.rb:36:in `require': cannot load such file -- mkmf (LoadError)
from /usr/lib/ruby/1.9.3/rubygems/custom_require.rb:36:in `require'
from extconf.rb:1:in `<main>'

Since gem install had never failed for me when I ran it, I decided to do a little more research. What actually is RedCloth? Why do we need it?

5 Easy Guides to Help You Get Started With GitHub

When you first start coding, storing things on your local hard drive is fine. But eventually the nightmares will start visiting you. What happens if your hard drive crashes? How do you collaborate with other people?

Enter Git and GitHub. Git is a version control system that helps you branch your code and bring it back together effectively, with a timeline that you can follow easily. GitHub is a web-based hosting system for projects that use Git. To date, it’s the most popular system online. But learning to use Git isn’t easy. These folks have put together some resources to help get you over that hump a little easier.

1. Try GitHub

Try Git The amazing people at Code School and GitHub have collaborated to make the great GitHub simulator Try GitHub to get you familiar with the Git syntax. It runs you through basic commands like git init, git status, git add, git commit, and git push. After you’ve run through this, the syntax doesn’t feel so foreign anymore.