Adam O'Grady

re:mind Journal Project

On the weekend past I decided to see if I could build a small project I had in mind and get it into production on the World Wide Web before I started at my new job. I decided to try building a journal system that reminds you to update on a daily basis by sending you a nightly email with a link to the latest entry for that day. I ended up getting it working in a very basic format (with user accounts/authentication) which I uploaded to some hosting I have through Digital Ocean. All in all, great success. There were a few basic things missing and a couple of bugs but now (since I’ve had some time to work on it); they’ve been added or quashed respectively and I’m pretty happy with what I’ve got.

You can find the current version online at re:mind Journal where you’re able to create an account and start diarising.

The system itself runs on Ruby On Rails, uses devise for authentication with some custom views and a custom registration controller which automatically creates a blank post when you build your account as well as picking up your timezone (from one of the custom views) to know when to create new daily posts and reminder emails. It also uses whenever for creating new blank posts on user accounts as well as reminder emails through the use of a schedule.rb file which is translated into a suitable format and automatically loaded into cron through a shell command. Post editing can include Markdown formatting thanks to the redcarpet gem.

As one of the requested extra features, I also created the ability to allow a user to download all of their posts in .xml files stored within a .zip (thanks to rubyzip there). To facilitate this, I created a route which led to a special method in the posts_controller.rb file. If the user does have posts attached to their account it collects them all, then opens a .zip Tempfile and for each post, adds the file name (the date + “.xml”) then writes in the post data translated to .xml format. Lastly it sends the whole zip file to the user (and cleans up after itself):

def download
  require 'zip'

  @posts = Post.where(user_id: current_user.id).all
  if @posts.count < 1
    redirect_to index
  end
  begin
    @z = Tempfile.new(['zip', '.zip'], 'tmp')
    Zip::OutputStream.open(@z.path) do |zip|
      @posts.each do |post|
        zip.put_next_entry(post.date.to_s + '.xml')
        zip.write post.to_xml
      end
    end

    send_data @z.read, :type => 'application/zip', :filename => "collected-posts.zip"
  ensure
    @z.close
    @z.unlink
  end
end

You can check it out online on Github or on my Gitlab. As I mentioned earlier, the live version of the service is also available at re:mind Journal.