7 Useful VS Code Extensions for React Node Projects

Code writing

  1. VS Code ES7 React/Redux/React-Native/JS snippets
    This extension provides you JavaScript and React/Redux snippets in ES7 with Babel plugin features for VS Code.



Iconography

2. vscode-icons
Bring icons to your Visual Studio Code.



NPM Related

3. Import Cost
This extension will display inline in the editor the size of the imported package.



CSS Related

4. Autoprefixer
This plugin for VS Code provides an interface to autoprefixer.



GIT Related

5. GitLens — Git supercharged
GitLens supercharges the Git capabilities built into Visual Studio Code. It helps you to visualize code authorship at a glance via Git blame annotations and code lens, seamlessly navigate and explore Git repositories, gain valuable insights via powerful comparison commands, and so much more.



File Viewers

6. SVG Viewer
SVG Viewer for Visual Studio Code












7. Excel Viewer
This extension provides read-only viewers for CSV files and Excel spreadsheets within the current Visual Studio Code workspace.


Publish the chatbot on Microsoft azure and setup Continuous deployment

Let's continue from the previous chatbot post and publish it to Microsoft azure.

1. Infra setup

Go to https://portal.azure.com/
Go to 'Create a resource and create a Web App Bot.


For bot template, I am choosing below settings to start with.


After you deployment success message in notifications, open the web app bot and click 'Test in Web Chat' to test.

2. Continuous deployment

Next, go to continuous deployment.
Setup the repository where your code resides. In my case, I specified github.com


Now your continuous deployment with GitHub setup is complete. Whenever you commit to the source code repository, your changes will automatically be deployed to the Azure Bot Service.

Very soon, the deployment will automatically trigger.

To test the new deployment, go back to azure's Test in webchat feature. Just in case, you find any issues, enable application logs.


Anything unclear, leave a comment or check out related documentation for Microsoft Bot Framework.



Creating a basic Echo bot locally using Microsoft bot framework


We will use Azure Bot Service v3.

1. Setup version control

Create a new git repository. I did it on https://github.com/new. I chose various settings as shown in below image:

Clone the repository locally, create a new branch and push it to server. I did via following commands:
  git clone git@github.com:monish001/superbot.git
  cd superbot
  git checkout master
  git checkout -b dev
  git push --set-upstream origin dev

2. Create a basic echobot using yeoman. 

I named my bot 'superbot' and select Echobot when asked.
  npm install -g npm
  npm install -g yo generator-botbuilder
  cd ..
  yo botbuilder
  cd superbot
  npm start

Now open the bot file in Microsoft Bot Framework Emulator to test the echobot.

3. Push to back to github.

git push

You can find the resulting code at https://github.com/monish001/superbot/releases/tag/0.0.1.

Any more questions, please leave a comment or check out related documentation for Microsoft Bot Framework.

Up and running with BrowserMob Proxy in a 30 seconds and start recording webpage HARs

BrowserMob Proxy is a free (Apache 2.0 license) utility that can capture performance data for web apps (via the HAR format), as well as manipulate browser behavior and traffic, such as whitelisting and blacklisting content, simulating network traffic and latency, and rewriting HTTP requests and responses.

To setup the BrowserMob Proxy, here are the quick steps:
  • Download the BrowserMob Proxy zip file from their website and unzip it. In my case, I have unzipped to /Users/guptam/Documents on a mac machine.
  • Open terminal in the directory in which the unzipped folder resides.
  • Run BrowserMob service at port 8080 (choose different port if required) by running:
      ./browsermob-proxy-2.1.0-beta-6/bin/browsermob-proxy -port 8080
  • Setup the proxy on port 9099 (again, choose different port if required) by running from a different terminal:
      curl -X POST -d 'port=9099' http://localhost:8080/proxy
If everything goes as mentioned above without errors, we should have a proxy running locally at port 9099. Configure your browsers (or any other software) with the proxy.

To record and retrieve HAR (HTTP archive format), here the further steps:
  • Running the following statement would give network calls recorded so far in HAR format and starts a new session.
      curl -X PUT http://localhost:8080/proxy/9099/har
  • Now proceed and complete the activity for which you need network logs.
  • Run the following statement (its same as above one) to retrieve the network logs in HAR format. It would also start a new session.
      curl -X PUT http://localhost:8080/proxy/9099/har
That's it.

Troubleshooting
In case you also get the below error, just run the statements below that fixed the issue in my case.

Error:
  Error: JAVA_HOME is not defined correctly.

Fix:
  export JAVA_HOME=$(/usr/libexec/java_home)
  export PATH=$JAVA_HOME/jre/bin:$PATH



How to add I18N for an angularJS app - Step by step - Hands-on

In this post, you will get to know how to add L10n(Localization) support in your angularJS apps.

First things first, difference between I18n and L10n [1]

Localization refers to the adaptation of a product, application or document content to meet the language, cultural and other requirements of a specific target market (a "locale").
Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.

Assumptions before you start

You have a angularJS app up and working.
You have using gulp (grunt setup will be similar)
You have nodeJS installed for npm and bower packages.

Let's start

Part A: Generating the string files for different locales.

1. Decorate the strings that needs to be translated with 'translate' directive

Simply add translate angularJS directive to the HTML elements that have text you would like to localize.
For example:
<div translate>Hello world!</div>
translate directive is defined in angular-translate that we will install in a bit.

2. Install angular-gettext

bower install --save angular-gettext

3. Add gulp tasks to create localization files [2]

var gulp = require('gulp');
var gettext = require('gulp-angular-gettext'); gulp.task('pot', function () {
    return gulp.src(['src/partials/**/*.html', 'src/scripts/**/*.js'])
        .pipe(gettext.extract('template.pot', {
            // options to pass to angular-gettext-tools... 
        }))
        .pipe(gulp.dest('po/'));
});
gulp.task('translations', function () {
    return gulp.src('po/**/*.po')
        .pipe(gettext.compile({
            // options to pass to angular-gettext-tools... 
            format: 'json'
        }))
        .pipe(gulp.dest('dist/translations/'));
});
After defining the above tasks, run task 'pot'.
gulp pot
This would generate template.pot file. Install poedit[3] to open template.pot file. Add translation files for each locale from within poedit. The output would bunch of *.po files.

4. Convert *.po files to *.json files

From the previous step, you will end up with *.po files, one for each locale. Run following gulp task to convert *.po to corresponding *.json.
gulp translations
With this, you will get JSON files. For example en_US.json, ru_ru.json. Now these files would be used by your angular app as mention in Part B below.

Part B: Using the string files in angularJS app

1. Install angular translation packages

bower install --save angular-translate
bower install --save angular-translate-loader-static-files  

2. Inject it as dependency in your root module and define the locale.

app
.module('myApp', ['pascalprecht.translate'])
.config(function($translateProvider){
    $translateProvider.useStaticFilesLoader({
        prefix: 'dist/translations/',
        suffix: '.json'
    });

    $translateProvider.preferredLanguage('en_US'); // locale based on user input
});
The above code will look for dist/translations/en_US.json



[1] http://stackoverflow.com/a/754557/989139
[2] https://www.npmjs.com/package/gulp-angular-gettext
[3] https://download.poedit.net/Poedit-1.8.5-setup.exe

Implement callback on completion of multiple asynchronous functions

Lets say, you need to execute a function 'myCallback' after completion of 2 async functions apiCall1 and apiCall2. Following is how you can implement this. Lets define the 2 async functions first:
var apiCall1 = function(){
 var complete1 = $.Deferred();
 $.ajax({
  url: '/url1',
  success: function(){
   successHandler1();
   complete1.resolve();
  }
 });
 return complete1.promise();
}
var apiCall2 = function(){
 var complete2 = $.Deferred();
 $.ajax({
  url: '/url2',
  success: function(){
   successHandler2();
   complete2.resolve();
  }
 });
 return complete2.promise();
}
Here is how you can define 'myCallback':
var myCallback = function(){
 //do something
}
$.when(apiCall1, apiCall2).done(myCallback);
Check out a working sample on JSFiddle.

References:

Preventing Cross-site request forgery in ASP.NET MVC


Let us start with the problem called as XSRF (Cross-site request forgery). Later we will use the solutions and one specific to ASP.NET MVC.

XSRF: Lets assume you have an account with website example.com which uses cookie-based authentication. Following are the steps which shows how XSRF can be exploited:

  • When logging into this website, cookies are set in your browser by example.com which will be used for authentication. 
  • Somehow, you click on a link provided by hacker say, hacker.com. This page contains a form which submits any critical data to example.com. Now, your cookies will be sent along with it for authentication.
That's it, now hacker can change your recovery email address, password etc to hack your account

General Solutions:

  • Example.com should check the referral webpage link in the post request to check if the request is coming from same domain only. But this is not 100% safe as this can be spoofed.
  • Maintain a GUID as cookie and a hidden input field in form. Example.com will proceed with entertaining the request only if both have same value. 
Consider the example of forgery above in case of solution 2. Now, the GUID value as cookie will be sent in request from hacker.com by the browser. (Note that hacker.com can not read cross-domain cookies.) But that GUID value will not be a part of form. Hence, example.com will not serve the request.

Solution for ASP.NET MVC:
Use Html.AntiForgeryToken(). This sets a cookie with key __RequestVerificationToken and generates following HTML code:
<input name="__RequestVerificationToken" type="hidden" value="TdsFsfkdNddddzdfNh4YbZjmEG0sdqlUddqddiab/dfVgdd2swweFrVyeylvzuwR" />


Change apache server's default listening port

Tested on VPS hosting using ubuntu server 10.04.

Change the port number in the following files:
/etc/apache2/sites-enabled/example.com
/etc/apache2/ports.conf
/etc/apache2/sites-available/default
Finally, remember to restart apache server:
/etc/init.d/apache2 restart

Question Paper Downloader for Thaparians

Latest Software here
Latest Code here
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.net.URL;

public class FileDownloader
{
 public static void main(String args[])
 {
  if(args.length != 2 && !(args[0].equals(""))){
   System.out.println("Usage: <web-link> <new-filename>");
  }else{try{
   if((args[0].substring(7,10)).equals("172"))
    args[0] = "http://cl.thapar.edu/" + args[0].substring(20);
   System.out.println("FileDownloader: "+args[0]+" "+args[1]);
   URL url = new URL(args[0]);
   java.io.BufferedInputStream in = new BufferedInputStream(url.openStream());
   java.io.FileOutputStream fos = new FileOutputStream(args[1]+".pdf");
   java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
   byte[] data = new byte[1024];
   int x=0;
   while((x=in.read(data,0,1024))>=0)
   {
    bout.write(data,0,x);
   }
   bout.close();
   in.close();
  }catch(IOException e){
   System.out.println(e.toString());
  }}
 }
}