Showing posts with label NodeJS. Show all posts
Showing posts with label NodeJS. Show all posts

Friday, August 15, 2014

How to create an image gallery with file upload into different folders (part 2)

This part is about setting the gallery live.
The configuration will be:

There is the fat cloud which contains my small host with a unique IP-Address.
I've been using digital ocean to setup the system at http://gallery.code-lounge.com.
To map the IP-Address to a more readable name I've booked an address at a DNS-Provider. Mine is hosteurope. Eventually the requested page will be delivered to the user.
The application stack on the server contains NodeJS, node-forever and nginx. Nginx is used as a proxy before nodejs. Forever makes sure the script runs forever and won't stop by an error.
I've chosen the distribution Ubuntu 14.04 for my host and my further description will be related to Ubuntu.

Copy the gallery script to the server

I've used the directory /usr/share/nginx/www/gallery for the gallery.
Clone the repository and create the required symlinks explained in part 1.

nginx

First I've added the recommended repository from the nginx wiki to my sources. This will make sure I have a more current version available than the repository that is included into Ubuntu by default.
apt-get install nginx will install nginx.
Now open the /etc/nginx/nginx.conf file and paste the following code into the http part.


upstream gallery.code-lounge.com {
    server 127.0.0.1:3002;
}

server {
    listen 0.0.0.0:80;
    server_name gallery.code-lounge.com;
    access_log /var/log/nginx/gallery.code-lounge.com;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://gallery.code-lounge.com/;
        proxy_redirect off;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
    client_max_body_size 10M;
}

Now replace all occurrences of gallery.code-lounge.com with your own hostname. Save the file and reload nginx with service nginx reload. Testing the host will provide a bad gateway response since nodejs is not setup yet.

NodeJS

Same like for nginx I want to have most current version. Therefor I've executed the curl command recommended in the official node js installation instructions.
apt-get install nodejs will do the installation.

Node-Forever

Now install forever with npm install -g forever.
The server can be started now with using forever start /usr/share/nginx/www/gallery/app.js

forever list will show you the currently running scripts
forever stop index will stop the script.

You should the the folders of your folders.json after typing the url into your browser.

Tuesday, August 12, 2014

How to create an image gallery with file upload into different folders (part 1)

You can checkout the github project here.
There is an example page here: gallery.code-lounge.com

Introduction

I wanted to have an easy to use image gallery with upload functionality.
The effort must be reduced to a minimum (since I have no time).
The article is splitted into two parts. In the first I'll explain how to setup the folder and gallery view including the upload.
The second part will be about setting the system live using nginx and securing the project with htaccess.

I decided to use existing projects of blueimp. 
The Bootstrap image gallery will make sure that the gallery is compatible with most devices. JQuery File Upload (also by blueimp) is responsible for a nice user experience during the upload process. The user must be able to use either drag and drop or select multiple files at once to make the upload process as convenient as possible.

The project in screenshots

I discovered (as always) that the complexity is much higher than previously assumed.
The result will look like this:

Up there you can see the gallery view. Folders are listed there. Blue folders are filled with pictures. Grey ones are empty.


This is the folder view. The images are responsively aligned. Also pictures taken in portrait mode should be handled nicely.


The upload process will look like this. As mentioned multiple files are possible with either using drag and drop or the dialog. After uploading the preview picture and loading animation will fly away (or get removed) with a fancy animation.

Technology

I've used twitter bootstrap, jquery and the two mentioned blueimp libraries for the frontend. Fontawsome provides nice icons.
In the backend I decided to use nodeJS or more specific expressJS.

Please keep in mind: I really needed to get this done as fast as possible. You won't find any new hipster technology like angularJS, unit tests or anything other alike.
The frontend part of the project is based on existing example code copied together.
I spend a little bit more time at the backend nodeJS part, but I think there could be lots of improvements there as well.

Folder Structure


Installing npm packages

Create a new folder, open the terminal and enter:
For initializing the project
npm init

For the file upload
npm install blueimp-file-upload --save

For the image gallery
npm install blueimp-bootstrap-image-gallery --save

For handling the webserver in nodeJS
npm install express --save

For creating smaller preview images in nodeJS
npm install gm --save

For handling file uploads in nodeJS
npm install busboy --save

The next part is system dependend.
An image conversion library is necessary. I decided to use imagemagick
For Ubuntu
sudo apt-get install imagemagick

For MacOSX
sudo port install imagemagick
or
sudo brew install imagemagick

Now I've created a public folder which contains static files delivered by the webserver.

mkdir public

Since I want to expose frontend libraries only I create symlinks to the frontend npm packages:
ln -s /Users/<user>/projects/image_gallery/node_modules/blueimp-bootstrap-image-gallery public
ln -s /Users/<user>/projects/image_gallery/node_modules/blueimp-file-upload public

Folder View

Backend

I kept it very simple: The folders are stored in a JSON file like this:


{
  "folder_1": "Folder 1",
  "folder_2": "Folder 2",
  "folder_3": "Folder 3"
}

The request is done to folder.json but will be catched by expressJS which will look into the photo-folders, check if they are empty and deliver something like this:



{
  "folder_1": {
    "title": "Folder 1",
    "isEmpty": false
  },
  "folder_2": {
    "title": "Folder 2",
    "isEmpty": true
  },
  "folder_3": {
    "title": "Folder 3",
    "isEmpty": true
  }
}


This is needed to show the colors in the frontend.

Frontend

The folder view contains some html and a small js part (which is directly included into html part).
The javascript does an ajax request to request folders.

Gallery View

Frontend

Well I already told you about my copy and paste approach.
So I did:
cp public/blueimp-bootstrap-image-gallery/index.html public/

Edited index.html and replaced lines
<link rel="stylesheet" href="css/bootstrap-image-gallery.css">
<link rel="stylesheet" href="css/demo.css">
<script src="js/bootstrap-image-gallery.js"></script>
<script src="js/demo.js"></script>

with

<link rel="stylesheet" href="blueimp-bootstrap-image-gallery/css/bootstrap-image-gallery.css">
<link rel="stylesheet" href="blueimp-bootstrap-image-gallery/css/demo.css">
<script src="blueimp-bootstrap-image-gallery/js/bootstrap-image-gallery.js"></script>
<script src="blueimp-bootstrap-image-gallery/js/demo.js"></script>

Doubleclicked index.html and check.
For the upload I simply copied lots of basic-plus.html included in the blueimp-file-upload project.
For more information check the github project.

Backend

The backend provides the image names for listing the images and he upload functionionality into different folders.

Setting up a test server

You could just use node app.js but a better approach would be to install nodemon:
(sudo) npm install -g nodemon

Nodemon has the advantage to check if files are modified and restart nodejs atomatically to ensure that the files are always up to date.

nodemon app.js
will start the server.
Open the browser and put http://127.0.0.1:3002 into the address field.