How to post parameters to a url using Ajax/Javascript between two website


I am working a new project and I recently ran into an interesting problem. One of the web site that I keep up at work was supposed to take the user to another website which required me to add post parameters.

EX – http://www.mywebsite.makeapayment.com ==> Collects Billing information ex – name, amount, address etc.==> Post this information to http://www.vendor-website.com.

I did not realize the problem until I started coding and my colleague pointed out that as soon as http://www.mywebsite.makeapayment.com goes to my servlet, the servlet will not pass params to external web site if use “POST”, I had to use “GET” because servlet will look up relative path only and the HTTPServletRequest/Response object is specific to an application. So if I wanted to send parameters using servlet I could only that using action = GET. Now since I was passing sensitive information so I did not want to use GET.

A couple of solutions were discussed as follows:

1. Insert the params in database and use servlet get from the mywebsite.com to pass the primary key of the database. Ex – http://www.mywebsite.makeapayment.com ==>  www.vendor-website.com?key=10001. The vendor application look up the required params from the database.

2. Create a new JSP and use JavaScript onLoad() to pass the params as Hidden Input and submit as post to  www.vendor-website.com.

Ex – http://www.mywebsite.makeapayment.com==>; Servlet==> New Blank JSP with Hidden params loaded on onLoad() and submitted to vendor website ==> http://www.vendor-website.com.

3. Third approach is interesting and I had not tried this ever but looked promising and this is what I eventually implemented. Make an Ajax call to from the JSP page to your servlet and when the Ajax Call returns, post it to vendor web site.

Ex – http://www.mywebsite.makeapayment.com on hitting submit==> calls the JS, uses DWR to post to call the servlet==> Servlet does back ground processing like saving the records etc ==> Returns the control back to the JavaScript ==> Upon return in Ajax Call ==> Post to http://www.vendor-website.com.

I implemented the combination of one and three but here I am going to show you how post params to a different URL – i.e. solution 3

Let’s say I have a submit form with Name and address which needs to be saved in database when I submit the form and then I need to post the same information to different web site.

PersonalInformation.jsp

<html>

<head>

    <script>

       // I am not showing the code for DWR. You will need to include dwr and engine.js. Add dwr.xml in your web-inf and specify the class name and method you want to use as dwr call. This method is called in the dwr Ajax call back.


function submitAndGoToVendorSite()
{
var form = document.createElement(“FORM”);
form.method = “POST”;
form.style.display = “none”;
document.body.appendChild(form);
var url=”www.vendor-website.com”;
form.action = url;

            //My dwr ajax call gets a Json string from the servlet response.
var jsonString =      ‘{“transactionId”:”1368505156670″,”requesterType”:”APP”,”billingEmail”:”null@cybersource.com”,”billingState”:”NC”,”amount”:”42.7699999999999999433786257441170164384″,”refund”:”N”,”billingCity”:”CONCORD”,”billingLine1″:”Progress Pl”,”billingFirstname”:”test”,”billingLine2″:”",”shopperIP”:”127.0.0.1″,”application”:”OEP2″,”currencyCode”:”USD”,”billingCompany”:”ACN”,”revenueSource”:”",”billingLastname”:”test”,”countryCode”:”US”,”billingAddrNum”:”1000″,”cardType”:”VISA”,”businessPurpose”:”TOOL”,”profileConfig”:”cybersource-MLTEST1″,”language”:”en”,”billingZip”:”28025″,”repOrCustID”:”1233836″,”user”:”DARORATEST”,”paymentMethod”:”CC”,”billingPhone”:”"}’

     // Create a JSON object from the JSON String

     var jsonObj = jQuery.parseJSON(jsonString);

//Iterate over Json object and set them as hidden input params to the form
for(obj in jsonObj){
var input = document.createElement(“INPUT”);
input.type = “hidden”;
input.name = obj;
input.value = jsonObj[obj];
form.appendChild(input);
}

//Submit the form
form.submit();

}
</script>

</head>

<body>

     <form>

            <label>Name:</label><Input type=”text”/>

            ……….

            <input type=”button” onclick=”submitAndGoToVendorSite();”/>

    </form>

</body>

That’s It!

~Keep Coding

| Tagged , , , , , | Leave a comment

Using multiple profiles in Maven + Eclipse


It’s possible that many of you already knew this but if not then here’ some basic info on Maven profiles. I have been using maven for over 2 and half years now, and have been copy pasting assembly and install files. I never bothered to know how Maven figures out how to read assembly and install file names. For example-

PROBLEM:

For all my projects I have been using assembly-jboss.xml to put the file/directory information and telling maven about my desired directory structure i.e. Pick files from a/b directory and put it in out directory c/d. The second file install-jboss.xml where I specify my panels, target files etc. It never occurred to me what happens if I change the file names to assembly-zzz.xml and intsall-zzz.xml.

Image 1

Well to cut the story short I checked out a fellow developer code on my machine and the command “mvn clean install” threw build error which said -

[1] [INFO] Searching for file location: C:\Dinesh\workspace\prov-ld-anin-trunk\artifacts\src\assembly\assembly-jboss4.xml

[2] [INFO] File: C:\Dinesh\workspace\prov-ld-anin-trunk\artifacts\src\assembly\assembly-jboss4.xml does not exist.

[3] [INFO] File: C:\Dinesh\workspace\prov-ld-anin-trunk\src\assembly\assembly-jboss4.xml does not exist.

 

Now I was using IZPack plugin and always thought the assembly and install xmls are part of IZPack configuration, so for half an hour I was searching “IZPack assembly descriptor”. Needless to say I did not get any releveant search result. After scratching my head a little and doing a text search in Eclipse to figure out how am I telling maven to find the specific files (in my case the fellow developer had named them as assembly-wso2carbon40.xml and install-wso2carbon40.xml). No results.

SOLUTION:

In Maven you set up a profile in your .m2/settings.xml. For example my settings.xml looks like this

<settings>
    <profiles>
        <profile>
            <id>jboss4</id>
            <properties>
                <java.home></java.home>
                <compileSource>1.5</compileSource>
                <server>jboss4</server> 
            </properties>
        </profile>
            </profiles>
  </settings>

If you will notice I have specified that <id>jboss4</id> tag has value jboss4. When maven is building your app, it looks for two files assemby-xxx.xml and install-xxx.xml. Here xxxin assembly-xxx.xml is the profile name. So in my case it looks in the settings.xml and sees that profile is jboss, so it uses to find a file assembly-jboss.xml and install-jboss4.xml.

So now the problem was that my developer friend had named the files as assembly-wso2Carbon40.xml and install-wso2Carbon40.xml. The first thing that came to my mind was let’s change the <id>jboss4</id>to <id>wso2</id>, that would resolve my issue. However I had other application where the file was named assembly-jboss.xml and install-jboss4.xml, which meant that my other application will error out on maven clean install and throw error message could not locate assembly file assembly-wso2Carbon40.xml .

Here’s comes the neat part, you can have multiple profiles in your settings file. So I updated my .m2/settings.xml

<settings>
    <profiles>
        <profile>
            <id>jboss</id>
            <properties>
                <svn.username></svn.username>
                <svn.password></svn.password>
                <java.home></java.home>
                <compileSource>1.5</compileSource>
                <server>jboss4</server>
                <server.home>C:\Program Files\jboss-eap-4.3</server.home>
                <server.port>80</server.port>
            </properties>
        </profile>
        <profile>
            <id>wso2</id>
            <properties>
                <compileSource>1.5</compileSource>
                <server>wso2carbon40</server>
            </properties>
        </profile>
    </profiles>
  </settings>

Now when you build the project using Eclipse, just got to Run As ==> Maven Build …  and enter Goals = clean install and Profile = wso2

Image 4

 

That’s it!

 

~~Cheers!

| Leave a comment

How to send email in PhoneGap (Android) using a gmail account


For the last one month, I have been working on an android app for a grocery store.
I have been using PhoneGap to develop the solution as the client wanted both Android and Iphone version.
I have tried building the app in native Android but going through the hassle of designing css was just too much for me and plus I did not had time to learn Iphone development.

There was a short learning phase for PhoneGap and the results were awesome. However there was one area where I spent hours and ran into several issues. The customer wanted a Feedback section where the user could fill in feedback in a TextArea and hits Submit, which would send an email to customer in the background.

Now PhoneGap has plugin called WebIntent which will open a Email composer where you have to hit Send. This is not what I wanted as customer would have to hit a SUBMIT button, which would open a Email composer window on Phone and then hit Send again. Also this solution also meant user’s email address would be displayed to Grocery store.
I wanted to send the feedback in the background anonymously to Grocery store. I decided to use Java email Api and create a dummy email for grocery store which would be used to send feedback to the Grocery store’s main email address.

I did not find any good tutorial except this one. This is an incomplete tutorial and did not tell you how to create Java classes for Plugin or that you had to make entries in config.xml. So here is the actual tutorial.

Before I begin, let me tell you that I am using latest version of Cordova 2.1.0. This is will not work for Cordova 1.9.0(I will explain the issue below).

Step 1: Add cordova-2.1.0.jar in the project classpath

Step 2: Add cordova-2.1.0.js in the assets/www/js folder.

Step 3: create a new Java class called EmailComoposer.java

package com.dinesh.pb;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.apache.cordova.api.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONException;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.text.Html;
import com.dinesh.pb.utility.Mail;
 
@SuppressLint("ParserError")
public class EmailComposer extends Plugin {
public final String ACTION_SEND_EMAIL = "sendEmail";

 @Override
 public PluginResult execute(String action, JSONArray arg1, String callbackId) {
 PluginResult result = new PluginResult(Status.INVALID_ACTION);
 if (action.equals(ACTION_SEND_EMAIL)) {
 try {
 String message = arg1.getString(0);
 this.sendEmailViaGmail(message);
 result = new PluginResult(Status.OK);

 }
 catch (JSONException ex) {
 result = new PluginResult(Status.JSON_EXCEPTION, ex.getMessage());
 } catch (Exception e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } 
 }
 return result;
 }

 private void sendEmailViaGmail(String body) throws Exception{
 Mail m = new Mail("From_email_address@gmail.com", "your password");
 String[] toArr = {"TO_EMAIL_ADDRESS@gmail.com"};
 m.set_to(toArr);
 m.set_from("FROM_EMAIL_ADDRESS@gmail.com");
 m.set_body(body);
 m.set_subject("TEST SUBJECT");
 boolean sendFlag = m.send();

 }

}

Step 4. copy this Mail.java in package of your choice. My package name is com.dinesh.pb.utility.

package com.dinesh.pb.utility;
import java.util.Date;
import java.util.Properties;
import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.BodyPart;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
public class Mail extends javax.mail.Authenticator { 
 private String _user; 
 private String _pass; 

 private String[] _to; 
 private String _from; 

 private String _port; 
 private String _sport; 

 private String _host; 

 private String _subject; 
 private String _body; 

 private boolean _auth; 

 private boolean _debuggable; 

 private Multipart _multipart; 

 public Mail() { 
 _host = "smtp.gmail.com"; // default smtp server 
 _port = "465"; // default smtp port 
 _sport = "465"; // default socketfactory port 

 _user = ""; // username 
 _pass = ""; // password 
 _from = ""; // email sent from 
 _subject = ""; // email subject 
 _body = ""; // email body 

 _debuggable = false; // debug mode on or off - default off 
 _auth = true; // smtp authentication - default on 

 _multipart = new MimeMultipart(); 

 // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
 MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
 mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
 mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
 mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
 mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
 mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 
 CommandMap.setDefaultCommandMap(mc); 
 } 

 public Mail(String user, String pass) { 
 this(); 

 _user = user; 
 _pass = pass; 
 } 

 public boolean send() throws Exception { 
 Properties props = _setProperties(); 

 if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
 Session session = Session.getInstance(props, this); 

 MimeMessage msg = new MimeMessage(session); 

 msg.setFrom(new InternetAddress(_from)); 

 InternetAddress[] addressTo = new InternetAddress[_to.length]; 
 for (int i = 0; i < _to.length; i++) { 
 addressTo[i] = new InternetAddress(_to[i]); 
 } 
 msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

 msg.setSubject(_subject); 
 msg.setSentDate(new Date()); 

 // setup message body 
 BodyPart messageBodyPart = new MimeBodyPart(); 
 messageBodyPart.setText(_body); 
 _multipart.addBodyPart(messageBodyPart); 

 // Put parts in message 
 msg.setContent(_multipart); 

 // send email 
 Transport.send(msg); 

 return true; 
 } else { 
 return false; 
 } 
 } 

 public void addAttachment(String filename) throws Exception { 
 BodyPart messageBodyPart = new MimeBodyPart(); 
 DataSource source = new FileDataSource(filename); 
 messageBodyPart.setDataHandler(new DataHandler(source)); 
 messageBodyPart.setFileName(filename); 

 _multipart.addBodyPart(messageBodyPart); 
 } 

 public String[] get_to() {
 return _to;
 }
public void set_to(String[] _to) {
 this._to = _to;
 }
public String get_from() {
 return _from;
 }
public void set_from(String _from) {
 this._from = _from;
 }
public String get_body() {
 return _body;
 }
public void set_body(String _body) {
 this._body = _body;
 }
@Override 
 public PasswordAuthentication getPasswordAuthentication() { 
 return new PasswordAuthentication(_user, _pass); 
 } 

 private Properties _setProperties() { 
 Properties props = new Properties(); 

 props.put("mail.smtp.host", _host); 

 if(_debuggable) { 
 props.put("mail.debug", "true"); 
 } 

 if(_auth) { 
 props.put("mail.smtp.auth", "true"); 
 } 

 props.put("mail.smtp.port", _port); 
 props.put("mail.smtp.socketFactory.port", _sport); 
 props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
 props.put("mail.smtp.socketFactory.fallback", "false"); 

 return props; 
 }
public String get_subject() {
 return _subject;
 }
public void set_subject(String _subject) {
 this._subject = _subject;
 }

 // more of the getters and setters ….. 
 }

Step 5: Update the config.xml and add the details about the new plugin class EmailComposer.java.
Mine looks like this – <plugin name=”EmailComposer” value=”com.dinesh.pb.EmailComposer”/>. Please update the package name value=”com.dinesh.pb.EmailComposer” with your package path.

<?xml version="1.0" encoding="utf-8"?> 
<cordova>
    <access origin="http://127.0.0.1*"/> <!-- allow local pages --> 
    <access origin=".*"/> 
    <log level="DEBUG"/>
    <preference name="useBrowserHistory" value="false" />
    <preference name="exit-on-suspend" value="false" />
<plugins>
    <plugin name="App" value="org.apache.cordova.App"/>
    <plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
    <plugin name="Device" value="org.apache.cordova.Device"/>
    <plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
    <plugin name="Compass" value="org.apache.cordova.CompassListener"/>
    <plugin name="Media" value="org.apache.cordova.AudioHandler"/>
    <plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
    <plugin name="Contacts" value="org.apache.cordova.ContactManager"/>
    <plugin name="File" value="org.apache.cordova.FileUtils"/>
    <plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
    <plugin name="Notification" value="org.apache.cordova.Notification"/>
    <plugin name="Storage" value="org.apache.cordova.Storage"/>
    <plugin name="Temperature" value="org.apache.cordova.TempListener"/>
    <plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
    <plugin name="Capture" value="org.apache.cordova.Capture"/>
    <plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
    <plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
    <plugin name="Echo" value="org.apache.cordova.Echo" />
    <plugin name="EmailComposer" value="com.dinesh.pb.EmailComposer"/>
 </plugins>
</cordova>

Step 6: Create a new javascript file called email.js

var EmailComposer = function(){};
/*
cordova.addConstructor(function() {
    cordova.addPlugin("emailcomposer", new EmailComposer());
});
*/
EmailComposer.prototype.send = function (message){
console.log("Calling the send message");
cordova.exec(function(){ alert('feedback sent')}, 
    function(){ alert('feedback was not sent')}, 
    'EmailComposer', 
    'sendEmail', 
    [message]);
}
function sendFeedback(){
    window.EmailComposer.prototype.send("My message body");
}

Now as I mentioned earlier that I am using cordova-2.1.0.js/jar file there are subtle differences between the latest version and older version (cordova-1.9.0).  If you are using older version you will need to uncomment the section cordova.addConstructorabove and instead of calling

window.EmailComposer.prototype.send("My message body");
Use this:

window.plugins.emailComposer.prototype.send(body);

If you do not use it then you may get error which would say that window.plugins is not defined. If you run into such issues use firebug and see what variables are defined under “window” variable.

Notice the method called “feedback()”. I am simply passing the user text as message body by capturing the input from user feedback TextBox. For simplicity I have just pasted a default Email body.

Step 7: Include the js file in your index.html file

// <!–[CDATA[
javascript" src="js/email.js">
// ]]>

Step 8: Include cordova js file in index.html

// <!–[CDATA[
javascript" src="js/cordova-2.1.0.js">
// ]]>

Step 9: Add three jar files for Java mail api – namely, Activation.jar, Mail.jar and Additional.jar in the libs folder and add it to the classpath. You can these files here.

Cheers!!

UPDATE: A lot of people commented that they could not find mail.jar,additional.jar and actication.jar so I have uploaded them on 4shared.com. You can download them from the link below.

Activation.jar

Additional.jar

Mail.jar

| Tagged , , , , , , | 19 Comments

Share any folder on mac via built-in web server


So what’s new here? Well I was playing around with Phonegap to build a small android and ios app. I was able to build a small weather app using Yahoo weather api but then I came across Sencha Touch 2.

I wanted to build the same app in Sencha Touch and compare the two platforms for developing mobile apps and as ap part of its get started tutorial I had to drop the  Sencha Touch in a web server. Now as it always happens with me the most simplest of things don’t work properly for me. I turned on apache server on my mac and added my directory on /etc/apache2/httpd.conf along with and Alias but that did not work out. I constantly ran in forbidden 403 error and tried everything described in various forums but nothing worked and then I came across a post which showed me an alternative way to run a webserver and access my folder without the hassle of apache2 httpd.conf file changes.

It’s really simple, all you need to do is figure out which folder you want to get access to on web server. In my case I wanted to share /Users/dinesharora/Desktop/Mydocument/softwares/sencha-touch-2

so here are the steps:

1. Open the terminal

2. cd /Users/dinesharora/Desktop/Mydocument/softwares/sencha-touch-2

3. type python -m SimpleHTTPServer

4. Hit enter

You will see a message - Serving HTTP on 0.0.0.0 port 8000 …

Now if for some reason you are a stickler and like the old-fashioned 8080 port then just type python -m SimpleHTTPServer 8080.

That’s it. Now access your folder via http://localhost:8000/. If you want to get access to this over another machine then just type http://.local:8080, so for example in my case it would be http://dinesharora.local:8080.

Now you know how to fly a plane, but do you know how to do a safe landing?? Just hit control +c to shut down the server. Dumb!!

Cheers!!

 

| Tagged , , , , , , , , | 1 Comment

Saving files in Amazon S3 using Carrierwave and Fog Gem


Long long time ago in a far far away land….. I am just kidding. So I needed a gem to do file uploads(in my case images but you can upload anything) and I was looking at various options. Paperclip is a popular option but there is a new kid on the block (so i read in various forums)… Carrierwave.

Now I have not used Paperclip but what I read was that Carrierwave is more flexible and powerful than Paperclip so if are interested then keep reading. Now let me tell you that you may need to do some additional settings, I will not get into details because the wiki page of Carrierwave is pretty intensive. The purpose of writing this post is to highlight a couple of issue that I ran into and some settings which were not explained.

Step 1: Install the Carrierwave gem

  gem install carrierwave

Step 2: Update the gem file

gem carrierwave

Step 3: Now you need a uploader. This is the file which has all the settings like which folder the image will be saved, setting the image quality, caching etc. I wanted to call my uploader class as ImageUploader

rails generate uploader ImageUploader

Step 4: Install fog gem

gem install fog

Step 5: Update gem file

gem ‘fog’, ‘~> 1.3.1′

bundle install

Step 6: Choose the storage type

class ImageUploader < CarrierWave::Uploader::Base

     storage :fog

end

Step 7: Create model. Mine was called Photo so I create photo.rb. Notice the line number 10.

class Photo < ActiveRecord::Base

#Attributes or fileds
attr_accessible :image,:pic_name,:description,:albums_id

#associations
belongs_to :albums

#carrier wave
mount_uploader :image,ImageUploader

#Validations
validates :description,:pic_name,:albums_id, :presence=>true
validates_uniqueness_of :pic_name
end

Step 7: How to upload file and show uploaded file in the html page

Upload page:

<%= form_for @user, :html => {:multipart => true} do |f| %>
  <p>
    <label>My Avatar</label>
    <%= f.file_field :avatar %>
    <%= f.hidden_field :avatar_cache %>
  </p>
<% end %>

View uploaded image

<%= form_for @user, :html => {:multipart => true} do |f| %>
  <p>
    <label>My Avatar</label>
    <%= image_tag(@user.avatar_url) if @user.avatar? %>
    <%= f.file_field :avatar %>
    <%= f.hidden_field :avatar_cache %>
  </p>
<% end %>

Step 8: Now comes the most important part. Setting up fog. Now if you follow the documentation on  Carrierwave then you will run into issue(I will explain the issue and fix below). The wiki page said create a file fog.rb in the lib/carrierwave/storage/fog.rb and that’s what I did. I created the file with the contents below.

CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider               => 'AWS',       # required
    :aws_access_key_id      => 'xxx',       # required
    :aws_secret_access_key  => 'yyy',       # required
    :region                 => 'eu-west-1'  # optional, defaults to 'us-east-1'
  }
  config.fog_directory  = 'name_of_directory'                     # required
  config.fog_host       = 'https://assets.example.com'            # optional, defaults to nil
  config.fog_public     = false                                   # optional, defaults to true
  config.fog_attributes = {'Cache-Control'=>'max-age=315576000'}  # optional, defaults to {}
end

Now before you start you need to have a S3 account on Amazon S3. So get your Amazon access key and secret access key. For example mine was …. hehehe no I am not going to share my access keys with you :-) . Anyway if you forgot to note down your access key and incase you are wondering where I can find that and are guessing that it will be on S3 Dashboard then you are mistaken just like me. You can find that on your account settings –> Security credentials.

So after you have noted down your key and access key. Go ahead create a bucket on S3. A bucket is nothing but a directory. It’s just a fancy shimancy name for directory that Amazon came up with. You can further create sub directories.

Now coming back to the meaty part and fog.rb file. I updated the below fields in the fog.rb

:aws_access_key_id      => 'xxx',       # required
    :aws_secret_access_key  => 'yyy',       # required

I commented out the below lines as they are optional

#:region                 => ‘eu-west-1′  # optional, defaults to ‘us-east-1′

I was not sure what was my region so if you are not sure as well then go ahead and comment it.

#config.fog_host = ‘https://s3.amazonaws.com&#8217; # optional, defaults to nil
#config.fog_public = true # optional, defaults to true

If you leave config.fog_host to https://s3.amazonaws.com then I ran into issues which said -

“LoadError (Expected /Users/dinesharora/Desktop/Mydocument/ruby-proj/album/app/uploaders/image_uploader.rb to define ImageUploader):”

So I commented that field. 

The next part that I was not sure about was how to tell fog which folder or directory I want to upload my files. I had created a bucket(directory) called myalbums and had created a sub folder called devlopment.

So I updated

config.fog_directory  = ‘myalbums/development‘, which did not work. The right way to do is

config.fog_directory  = ‘myalbums’ and also in ImageUploader  update the line

def store_dir
“development/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}”
end

That’s it. Now just start the server and start uploading, that’s what the forums said but as it always happens with me(nothing works for me the first time) I ran into error(as I mentioned earlier that you will if you create the fog.rb in lib/carrierwave/storage/ folder) which said -

ActionController::RoutingError (uninitialized constant CarrierWave::Storage::Fog):
app/uploaders/image_uploader.rb:11:in `<class:ImageUploader>’
app/uploaders/image_uploader.rb:3:in `<top (required)>’
app/models/photo.rb:10:in `<class:Photo>’
app/models/photo.rb:1:in `<top (required)>’
app/controllers/photo_controller.rb:1:in `<top (required)>’

To get rid of this error, just copy the file in config/initializers and now I could finally say – That’s it!!!! :-)

~~~ Cheers!

| Tagged , , , , , , , , | Leave a comment

Installing Rails on Mac OSX


I struggled a lot doing this on my mac. I prepared steps and notes while I was upgrading. here are the steps for mac osx. This works for Mac OSX 10.6+

============ Section 1 =================
Install and update Ruby 1.9 on MAC OSX Snow leopard 10.6.5

1. Install RVM
Installation instruction: http://rvm.beginrescueend.com/rvm/install/

- In Treminal Run the following command:
bash < <( curl http://rvm.beginrescueend.com/releases/ … all-latest )

- type in terminal: version=$(curl http://rvm.beginrescueend.com/releases/ … sion.txt);

- type in terminal:
mkdir -p ~/.rvm/src/ && cd ~/.rvm/src/ && curl -O http://rvm.beginrescueend.com/releases/ … on}.tar.gz | tar zxf – && cd rvm-${version} && ./install

- The first time you install RVM, you must put the following line into your ~/.bash_profile at the very end, after all path loads etc:
(If you do not have .bash_profile then open terminal.
Start up Terminal
•    Type “cd ~/” to go to your home folder
•    Type “touch .bash_profile” to create your new file.
•    Edit .bash_profile with your favorite editor (or you can just type “open -e .bash_profile” to open it in TextEdit.
•    Type “. .bashrc” to reload .bashrc and update any functions you add.
)

- Update the .bash_profile and add this text.
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . “$HOME/.rvm/scripts/rvm”  # This loads RVM into a shell session.

- Close the terminal and open a new terminal.
- Check if rvm is installed correctly by typing
type rvm | head -1
This should show result : “rvm is a function ”
- type : source ~/.rvm/scripts/rvm
- type: rvm notes
-

=========== Section 2: After you have done section 1 above ======

II Upgrade to ruby 1.9

- Make sure that you installed rvm
Instruction URL- http://asciicasts.com/episodes/200-rails-3-beta-and-rvm

- type: rvm install 1.9.2

- Check which version of ruby is installed so far by typing “rvm list”.

- The new version of ruby will be active only until the terminal is open. To make ruby 1.9.2 as default version. Type: rvm  1.9.2 –default

- If we want to return to previous version of the system. Then type: rvm system –default

III INSTALL RAILS 3
- Type: gem install rails

IV INSTALL FRESH COPY OF MYSQL
- INSTRUCTION URL: http://weblog.rubyonrails.org/2009/8/30 … ow-leopard

- First Stop the mysql server if it is running :
sudo /opt/local/share/mysql5/mysql/mysql.server stop

- Now download a fresh copy from this URL:
http://weblog.rubyonrails.org/2009/8/30 … ow-leopard

- Next Install the mysql.pkg → Next install MySQLStartupItem.pkg -→ Install MySQL.prefPane

- The Mac OS X PKG of MySQL installs itself into
`/usr/local/mysql-VERSION’ and also installs a symbolic link,
`/usr/local/mysql’, that points to the new location. If a directory
named `/usr/local/mysql’ exists, it is renamed to
`/usr/local/mysql.bak’ first. Additionally, the installer creates the
grant tables in the `mysql’ database by executing `mysql_install_db’.

- Start the MySql server from the System Prefernce pane and make sure that it runs.

-  Go to /usr/local/mysql/bin and type: ./mysql, This should start start the MYSQL prompt and you can execute the SQl statements.

- Let us now secure the database by giving it a user id and password.
In the same package type: ./mysqladmin –u root password <your password>

ISSUES:
Access Denied for local host after you have set root and password then you need to reset the password..

1. Stop the Server from preference pane.
2. From /usr/local/mysql/bin folder type the following the terminal:
  sudo ./mysqld_safe — –skip-grant-tables . This will start the server.
3. Type : ./mysql -u root mysql
4. type: UPDATE user SET Password=PASSWORD(‘admin’) where USER=’root’;  — This will set the password as admin.
5. Restart the server from prefernce pane.

Hope this helps. I used the exact same steps to upgrade to Rails 3.0.3 and ruby 1.9.2

—Cheers!!!

14 dinesh19aug

| Tagged , , , , , , , | Leave a comment

Setting up IMAP settings for hotmail account on Iphone and android


Yes, there are still a few lost soul who still have a Hotmail account  and I am one of them :-) .

I have used Iphone in the past and use an android phone now, however I always complained that I was not able to set up an IMAP account for Hotmail. I always had a POP3 account :-(

What does IMAP and POP3 mean? – For beginner who do not understand what is IMAP and POP3, here’s a small description.

a) POP3 – is a one way email checking. When you setup account on your iPhone, android or Microsoft outlook or any other email client and you download an email on your phone or on your desktop, it just downloads a copy of that email. So when you hit delete or read an email on your phone or desktop, it does not affect the email in the Hotmail account. Now most of us use Iphone o android phone these days to check emails. Now when you delete the email on phone, you still need to login on your Hotmail account to really delete email. As result when I login to Hotmail account after a month, there are hundreds of emails which I deleted on my phone and I have to go through each email to make sure that I do not delete an important email.

b) IMAP – is a two-way email checking. When you read or delete and email on phone or any other email client such as OUTLOOK, the email is updated in your account as well. For example if you delete an email on your phone, it will be deleted from your account as well.

So here’s a run down of the process.

IPHONE SETUP:

  1. Go to Settings – Mail, Contact, Calendars
  2. Click on Add Account…
  3. Choose Microsoft Exchange
  4. Fill in the fields shown (Leave domain blank and your login should be your email address)
  5. Click next and it will ask for server. Use m.hotmail.com
  6. Choose if you want your email, contacts or calendar synced.http://www.sirslur.com/wp-content/uploads/2010/09/photo.png

ANDROID PHONE SETUP:

1. Open the Mail app.
2. Hit the menu button > Add account
3. Enter your hotmail e-mail address and password.
4. Press Manual setup (don’t press Next!)
5. For account, select Exchange.
6. On the Server settings page, clear out the DomainUsername field and enter your hotmail address.
7. Change the Server to m.hotmail.com (without the quotes).
8. Keep the checkboxes the way they are (Use secure connection enabled, but don’t accept all SSL certificates)
9. Press Next.
10. Once the server settings are confirmed, you’ll be asked for how far back you’d like to sync your e-mail, contacts and calendars.

Cheers!!!

| Tagged , , , , | 19 Comments