Sunday, February 21, 2016

Deploying mailman with daemon and capistrano


Recently, I wanted to store the contents of the email I receive on my email to database of my rails application. I was able to achieve my goal with mailman gem. I learned about it from railscasts. In this post, I will write about how I implemented it.

I added following to my Gemfile
gem mailman

After that, I ran bundle install from my terminal.

Then, I added the following code to my script/mailman_server.rb:
#!/usr/bin/env ruby require "rubygems"
require "mailman"
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))

Mailman.config.rails_root = '.'
Mailman.config.logger = Logger.new("log/mailman.log")
Mailman.config.pop3 = {
server: 'mail.your-server.de', port: 110,
username: 'your_username',
password: 'your_password'
}
Mailman::Application.run do
default do
begin
    MyModel.receive_mail(message)
rescue Exception => e
    Mailman.logger.error "Exception occurred while receiving message:\n#{message}"
    Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
I wanted to save the body of the mail to body attribute of my MyModel database. So, the model MyModel consists of receive_mail now looks like following:
def self.receive_mail(message)
message_text = message.multipart? ? (message.text_part ? message.text_part.body.decoded : nil) : message.body.decoded
my_model_params = { body: message_text}
MyModel.create!(my_model_params)
end
With the program written above, I stored the contents of the email that I received at username as mentioned in mailman_server.rb in my my_model table of the database.

Now, I wanted to run the mailman_script.rb script with daemons gem, so that I could run the script with just start, stop and restart commands.

In my Gemfile, I added the following line gem daemons and run bundle install.

I added a new file in the script folder called mailman_daemon.rb, that contains following code:
#!/usr/bin/env ruby

require "rubygems"
require "bundler/setup"
require "daemons"

Daemons.run('script/mailman_server.rb')
Now the hardest part that I had was setting up the capistrano with daemon. The main task is to start, stop and restart daemon with capistrano. So, that we don't have to start our daemon server with each deployment. I added the following to config/deploy.rb:
# Mailman configuration
namespace :mailman do
desc "Mailman::Start"
task :start, :roles => [:app] do
run "cd #{current_path};RAILS_ENV=#{rails_env} script/mailman_daemon.rb start"
end
desc "Mailman::Stop" task :stop, :roles => [:app] do
run "cd #{current_path};RAILS_ENV=#{rails_env} script/mailman_daemon.rb stop"
end
desc "Mailman::Restart" task :restart, :roles => [:app] do
mailman.stop mailman.start
end
end
before "deploy:cleanup", "mailman:restart"
Now, the rails application is ready to be deployed with capistrano, mailman and daemon. Have fun!

Sunday, November 22, 2015

Testing with Rspec


Test driven development (TDD) is a concept of software development in which a new feature is developed by writing tests first, making it fail, and writing the code to make the test pass. This process continues iteratively until all the tests pass.
Starting to code with TDD enables developers to think about the test cases first rather than diving immediately in writing the code for the feature. In this case, the requirements and the scenarios are thought about in advance. In this blog, I will go through installing rspec and adding doing TDD. Rspec is used for writing automated tests.
First of all, I will start with rspec-rails.
1) Add following to the Gemfile:
group :test do
gem 'rspec-rails'
end
2) bundle install
3) rails generate rspec:install
This will create certain files like spec_helper.rb in spec/. This file contains the configuration for the test. For instance, the database cleaner for cleaning test database is added in spec_helper. For more details, please refer here. Let us assume that, we have a model Post and it has attributes title and description. Add a file post_spec.rb: spec/models/post_spec.rb
require "spec_helper"
describe "Post", :type => model do
it "has attributes name and author" do
post = Post.new(title: "New Post", description: "This is a new post")
post.save
expect(post.attributes).to include("title")
expect(post.attributes).to include("description")
expect(Post.count).to be(1)
expect(Post.first.title).to be("New Post")
expect(Post.first.description).to be("This is a new post")
end
end
When you run the rspec test with command
bundle exec rspec
There will be an error:
Uninitialized constant Post
Then you create a model with
rails g model Post
Then when you run the test again it will give an error saying:
Undefined method title for Class
So add a new migration to add attributes title and description to the model Post with
rails generate migration CreatePosts title:string description:text
This will create a migration file in db/migrations/xxxxxxxxxxxxxx_create_posts.rb (xxxxxxxxxxxxxx is the timestamp the migration is created). When you open this file, it will look like:
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :description
t.timestamps
end
end
end
Then run the migration with:
bundle exec rake db:create
(for the first time)
and:
bundle exec rake db:migrate
Then, getting back to the test again. Now when you run rspec again, the tests again fail and it says as you will have to define the attributes in model as well.
Add the following lines in your app/models/post.rb
attr_accessible :title, :description
Now, when you run the test again with
bundle exec rspec
, your tests successfully pass. Congratulations, you just did TDD with rspec.

Sunday, October 18, 2015

Bootstrap datepickers on Rails application


I recently used bootstrap datepicker for selecting dates. As a gem, I used bootstrap3 datepicker rails for my rails application. I needed the datepicker and time picker separately. So, I had two input fields, one just as calendar and another for time. This blog is about the datepicker. The timepicker will follow shortly. To use this gem, I added following to my Gemfile:
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.14.30'
In the view, I include the datepicker as:
<div class="form-group col-md-6">
   <%= label_tag "date", "Date"%>
   <%= text_field_tag "date", nil, class:"form-control", placeholder: "From", required: true %>
   <span class="input-group-addon">       </span >
</div >
The above code shows only how the calendar will be displayed. To utilize the functionality of the calendar, we have to call datetimepicker() function of javascript. To use datepickers only as calendar use the following script:
<script>
$(document).ready(function() {
$(".date").datetimepicker({
viewMode: 'days',
format: 'DD/MM/YYYY'
});
});
</script>
It does the following:
1. Give the date with format day/month/year. If the format is not selected, the calendar gives both calendar and time selection options.
2. Does not show time option so that you can only use the calendar.
Other lot of options are possible to configure the calendar. Please refer to the documentation if you intend to use it. I have added a small datetimepicker project so that it gives you an idea about how to use it in your rails application.

Saturday, September 17, 2011

Playing with css: working with position absolute

If you always want an element at a certain place without relativity to any other element, then we use this property "position:absolute;". While playing around with "position absolute", I learned that we do not use "margin", instead we use properties such as "top, bottom, right and left".

For instance, I have an element with class "example", I use "position absolute" in it as:
Hello

We can also give "float" values to "absolute positions" like
float:left or float:right

Pfeed for mongoid

As pfeed was originally for ActiveRecord, I had some problem integrating it in the mongoid. However, I forked the original pfeed and made it compatible for mongoid. The modified version of pfeed for mongoid can be found https://github.com/sadiksha/pfeed. This is suitable for mongoid version 2.0.2 and rails 3.0.0.

Saturday, November 6, 2010

Cucumber test for select box!

The behavior driven development is really fun. First of all you determine the flow of the program and then only write real codes. This technique is really effective as it saves time while programming, since the flow is already determined, the chance of hindrance is very low.

A simple test for seeing something in select box is:
Given I am on the index page
And the "Nepal" should be selected for "Country"
(where "Nepal" is your selected value and "Country" is the id/label of the select box)

The step definition for this step is
Then /^"([^\"]*)" should be selected for "([^\"]*)"$/ do |selected_value, field|
find_by_id(field).value.to_s.should == selected_value
end

Using ajax call with file field!

Sometime ago I had real trouble using file field and ajax call together. I wanted to browse a file and display the contents in the same page. Then after some research I came across gem called "remotipart". This gem is really helpful.

To use this gem follow these simple steps
1. Include "gem remotipart" in your Gemfile
2. Bundle install
3. type this in your console: rails generate remotipart
4. Include jquery-1.4.2-min.js, rails.js, jquery.form.js and jquery.remotipart.js as your javascript files
5. Suppose you are using this in you new.html.erb file, then do this
<%= form_for @product, :html => { :multipart => true }, :remote => true do |f| %>
<%= f.label :file_upload %>
<%= f.file_field :file_upload %>
<%= f.submit %>
<% end %>
6. In your create controller include: format.js {} instead of format.html{}
7. In create.js.erb file :
<%= remotipart_response do %>
//Write your javascript code here.
<% end %>

If you have any confusions go to https://github.com/formasfunction/remotipart. This site really helped me a lot.