https://mrvautin.com mrvautin 2024-02-26T07:37:41.221Z squido mrvautin https://mrvautin.com/favicon.png <![CDATA[React Native - Change folder of App.js or App.tsx into subfolder]]> https://mrvautin.com/react-native-change-folder-of-app.js-tsx-for-app-to-subfolder/ 2024-02-26T11:00:00.000Z React Native - Change folder of App.js or App.tsx to subfolder

Introduction

You may want to next your app within a different folder to make your dev environment cleaner. You can do this by moving your App.js or App.tsx into a /app folder.

Setup

I'm going to move my app into a /app folder but you may use /src etc.

Say my structure is currently like this:

.expo/
App.tsx
ios/
node_modules/
.gitignore
app.json
package.json
...

First we will create our /app folder.

We can then move our App.tsx (App.js) and the rest of my app /assets etc to this folder.

Within that folder we will create an AppEntry.tsx file:

import registerRootComponent from 'expo/build/launch/registerRootComponent';

import App from './App';

registerRootComponent(App);

Lastly, we need to tell the app where the entrypoint is. We will need to update our package.json file by setting the main:

{
  "name": "my-app",
  "version": "1.0.0",
  "main": "app/AppEntry.tsx",
  "scripts": {
    "start": "expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },
  ...
}

You will end up with a structure like:

.expo/
app/App.tsx
app/AppEntry.tsx
app/assets/logo.png
ios/
node_modules/
.gitignore
app.json
package.json
...

That's it, start your app with npm run ios and away you go. Good luck!

]]>
<![CDATA[Setting Up Home Assistant on Apple CarPlay - A Step-by-Step Guide]]> https://mrvautin.com/setting-up-home-assistant-on-apple-carplay-a-step-by-step-guide/ 2024-01-31T11:00:00.000Z Setting Up Home Assistant on Apple CarPlay: A Step-by-Step Guide

Introduction

Home Assistant is a powerful open-source platform for smart home automation, and with the increasing integration of technology into our daily lives, having access to your home automation system while on the go can be incredibly convenient. If you're an Apple CarPlay user, you can now extend the reach of Home Assistant to your car, allowing you to control various smart devices on the move. In this guide, we'll walk you through the process of setting up Home Assistant on Apple CarPlay.

Prerequisites

Before you begin, ensure you have the following:

  1. An Apple CarPlay-compatible vehicle or head unit.
  2. An iPhone running iOS 12 or later.
  3. Home Assistant instance set up and accessible from the internet.

Step 1: Install the Home Assistant Companion App

  1. Open the App Store on your iPhone.
  2. Search for "Home Assistant" and download the official Home Assistant Companion App.
  3. Open the app and log in with your Home Assistant credentials.

Step 2: Enable CarPlay Integration

  1. In the Home Assistant app, navigate to "App Configuration" from the sidebar.
  2. Tap on "CarPlay" to access CarPlay settings.
  3. Toggle the switch to enable CarPlay integration.

Step 3: Configure CarPlay Dashboard

  1. Connect your iPhone to your CarPlay-compatible vehicle or head unit.
  2. Open the CarPlay interface, and you should see the Home Assistant icon.
  3. Tap the Home Assistant icon to launch the CarPlay dashboard.

Step 4: Customize CarPlay Dashboard

  1. Once in the CarPlay dashboard, you can customize the interface by adding or removing cards.
  2. Press and hold on a card to enter edit mode.
  3. Use the on-screen options to add cards, rearrange them, or remove unwanted ones.

Step 5: Control Your Smart Home On the Go

  1. With Home Assistant on CarPlay, you can now control your smart devices from the dashboard.
  2. Use voice commands via Siri to perform actions like turning off lights, adjusting thermostat settings, or locking doors.

Conclusion

Setting up Home Assistant on Apple CarPlay brings your smart home control to the driver's seat, providing a seamless and convenient way to manage your devices while on the move. With the integration of CarPlay, Home Assistant continues to demonstrate its commitment to making home automation accessible wherever you are. Try out this guide, and enjoy the convenience of controlling your smart home right from your car. Safe driving!

]]>
<![CDATA[Why to use Nodejs - Top 6 advantages of using NodeJs]]> https://mrvautin.com/why-to-use-nodejs-top-6-advantages-of-using-nodejs/ 2023-03-05T01:00:00.000Z Node.js is a popular open-source, cross-platform runtime environment that is designed to run JavaScript on the server-side. It is built on top of the Google V8 JavaScript engine and provides developers with a powerful platform for building scalable and high-performance applications. In this blog post, we will explore why you should use Node.js and its advantages.

1. JavaScript Everywhere

One of the primary advantages of Node.js is that it allows developers to use the same programming language, i.e., JavaScript, on both the server-side and client-side. This means that developers can use the same programming language for both front-end and back-end development, which reduces the learning curve and makes it easier to switch between different development tasks.

2. High Performance

Node.js is known for its high performance and scalability. It is designed to handle a large number of simultaneous connections and requests, making it ideal for building real-time applications such as chat applications, online games, and collaborative tools. Additionally, Node.js uses an event-driven, non-blocking I/O model, which makes it highly efficient and able to handle large amounts of data without slowing down or crashing.

3. Large Community

Node.js has a large and active community of developers, which means that there is a wealth of resources available for developers to learn from and leverage. The Node.js community has created a vast ecosystem of modules, packages, and tools that make it easier to build and maintain Node.js applications.

4. Easy to Learn

As mentioned earlier, Node.js uses JavaScript, which is one of the most popular programming languages in the world. This means that developers who are already familiar with JavaScript can easily learn Node.js and start building applications. Additionally, Node.js has a simple and intuitive API, making it easy for developers to get started quickly.

5. Cross-Platform

Node.js is a cross-platform runtime environment, which means that developers can use it on Windows, macOS, Linux, and other operating systems. This makes it easier to build and deploy applications across different platforms without having to make significant changes to the code.

6. Scalability

Node.js is designed to handle large-scale applications and can easily scale to meet the needs of growing businesses. It uses a modular approach to building applications, which means that developers can add new functionality and features as needed without having to rewrite the entire application.

Conclusion

In conclusion, Node.js is an excellent choice for building high-performance, scalable, and real-time applications. Its ease of use, cross-platform compatibility, and vast ecosystem of modules and tools make it an ideal platform for developers to build applications quickly and efficiently. So, if you are looking for a powerful and flexible platform for your next project, consider using Node.js.1.

]]>
<![CDATA[Home Assistant - A Comprehensive Guide to install Home Assistant on Your Computer]]> https://mrvautin.com/a-comprehensive-guide-install-home-assistant-on-your-computer/ 2023-03-04T01:01:00.000Z Home Assistant is an open-source platform that allows you to control various smart devices in your home from a single location. It is a popular home automation system that is easy to install and use. In this guide, we will walk you through the steps of installing Home Assistant on your computer.

Prerequisites

Before you begin, you will need the following:

  • A computer running Windows, macOS, or Linux
  • Python 3.8 or higher installed on your computer
  • A virtual environment set up on your computer (optional but recommended)

Step 1: Install Home Assistant

To install Home Assistant, follow these steps:

  1. Open a terminal or command prompt on your computer.
  2. Activate your virtual environment (if you have set one up).
  3. Enter the following command to install Home Assistant:
pip install homeassistant
  1. Wait for the installation to complete.

Step 2: Set Up Home Assistant

Once Home Assistant is installed, you need to set it up. Here are the steps:

  1. Enter the following command to start Home Assistant:
hass
  1. Wait for Home Assistant to start up. This may take a few minutes the first time you run it.
  2. Open a web browser and go to http://localhost:8123.
  3. Follow the instructions to set up Home Assistant.

Step 3: Add Devices and Integrations

Once you have set up Home Assistant, you can start adding devices and integrations. Here's how:

  1. Click on Configuration in the Home Assistant sidebar.
  2. Click on Integrations and then click the + button.
  3. Select the integration you want to add and follow the instructions.
  4. Once you have added an integration, you can start using it in Home Assistant.

Conclusion

Congratulations! You have successfully installed and set up Home Assistant on your computer.

Now you can start adding devices and integrations to control your smart home from a single location. If you encounter any issues during the installation process, refer to the Home Assistant documentation or seek help from the Home Assistant community.

]]>
<![CDATA[Home Assistant - A Comprehensive Guide to Your Smart Home]]> https://mrvautin.com/home-assistant-a-comprehensive-guide-to-your-smart-home/ 2023-03-04T01:00:00.000Z With the increasing popularity of smart home technology, managing all of your devices and automating your daily routines can be a daunting task. However, with Home Assistant, you can easily control all of your smart home devices and customize your home automation to fit your unique needs.

What is Home Assistant?

Home Assistant is an open-source home automation platform that allows you to control all of your smart home devices from a central location. With Home Assistant, you can integrate all of your smart devices into a single platform, create customized automations, and monitor your home's status and activity.

Home Assistant supports a wide range of smart home devices, including lights, thermostats, sensors, cameras, and more. It also supports popular smart home protocols like Zigbee, Z-Wave, Wi-Fi, and Bluetooth.

Getting Started with Home Assistant

Getting started with Home Assistant is easy, but it does require some technical know-how. To get started, you will need to download and install the Home Assistant software on a device like a Raspberry Pi or a dedicated server.

Once you have installed Home Assistant, you can start adding your smart devices to the platform. Home Assistant supports a wide range of devices and protocols, but you will need to ensure that your devices are compatible with the platform before you start adding them.

Customizing Your Smart Home Automation

One of the great benefits of Home Assistant is the ability to customize your smart home automation. With Home Assistant, you can create complex automations that trigger based on a variety of conditions and events.

For example, you can create an automation that turns on your living room lights when you enter the room and turns them off when you leave. You can also create automations that adjust your thermostat based on the time of day or the weather outside.

In addition to creating automations, Home Assistant also supports custom scripts that can be triggered by voice commands or other events. This allows you to create custom actions that are not supported by your smart home devices out of the box.

Monitoring Your Smart Home

Home Assistant also provides a dashboard that allows you to monitor your smart home devices and activity. The dashboard provides real-time information about your home's status, including the temperature, humidity, and energy usage.

You can also set up alerts and notifications that notify you when certain conditions are met. For example, you can set up an alert that notifies you when the front door is opened or when a motion sensor is triggered.

Conclusion

Home Assistant is a powerful home automation platform that provides a comprehensive solution for managing your smart home devices. With Home Assistant, you can integrate all of your devices into a single platform, create custom automations, and monitor your home's status and activity.

If you're looking to take your smart home to the next level, Home Assistant is definitely worth checking out. While it does require some technical know-how to get started, the customization and control it provides over your smart home devices is unparalleled.

]]>
<![CDATA[helpkb - An open-source and easy to use knowledge base / FAQ]]> https://mrvautin.com/helpkb-open-source-and-easy-to-use-knowledge-base-faq/ 2022-07-03T01:00:00.000Z

helpkb is a superfast and easy to use knowledge base / FAQ to help your customers get the info they need, when they need it most.

It's been proven that empowering your customers and staff to self serve and access information quickly and easily will boost customer satisfaction, reduce queries and make everyone's life easier. We've created helpkb to do just that. A FREE, super fast and easy to use knowledge base or FAQ so information is always on hand.

So checkout the documentation / demo, and follow our guide to get started building your knowledge base / FAQ today!

Screenshot:

helpkb screenshot

]]>
<![CDATA[taxily - An Australian Income Tax, Net Pay, Superannuation and Savings calculator]]> https://mrvautin.com/taxily-an-australian-income-tax-net-pay-superannuation-savings-calculator/ 2022-03-29T01:00:00.000Z taxily allows you to calculate your Australian annual Income, Net pay, Superannuation and Savings with a few simple inputs using the official ATO tax rates.

taxily inputs

Once you've entered your income and your income cycle you will get a beautiful report showing all the calculated values:

taxily inputs

Access taxily.markmoffat.com

]]>
<![CDATA[Deploying your Next.js website without any downtime]]> https://mrvautin.com/deploying-your-nextjs-website-without-any-downtime/ 2022-03-15T01:00:00.000Z In an ideal world, you'd build your Next.js app locally, check it works then deploy the built app to your production server.

Sometimes you just want to deploy your Next.js website on the server and not build locally as stated above. To do this we are going to setup a simple shell script and use PM2 to deploy with no downtime.

An example PM2 ecosystem.config.js file in the root of your project:

module.exports = {
   apps: [
      {
         name: 'my-app',
         script: 'npm run start',
         cwd: '/Users/mrvautin/Documents/Code/my-app/',
         env: {
               NODE_ENV: 'development'
         },
         env_production: {
               NODE_ENV: 'production'
         }
      }
   ],
   deploy: {
      production: {
         user: 'my-user',
         host: 'my-server',
         key: '/Users/mrvautin/.ssh/id_rsa',
         ssh_options: 'ForwardAgent=yes',
         ref: 'origin/main',
         repo: 'git@github.com:mrvautin/my-app.git',
         path: '/var/www/html/my-app',
         'post-deploy': 'sh nextjs-pm2-deploy.sh'
      }
   }
};

An example package.json with our deploy script:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "deploy": "pm2 deploy production"
  },
  "dependencies": {},
  "devDependencies": {}
}

Now the contents of the nextjs-pm2-deploy.sh shell script referenced in the post-deploy section of the ecosystem.config.js file above:

echo "Deploy starting..."

npm run install || exit

BUILD_DIR=temp npm run build || exit

if [ ! -d "temp" ]; then
  echo '\033[31m temp Directory not exists!\033[0m'  
  exit 1;
fi

rm -rf .next

mv temp .next

pm2 reload all --update-env
pm2 reset all

echo "Deploy done."

Summary

Basically, this script will install our app, set the build path to /temp, build the app into /temp, check the /temp directory exists then move the contents over and reset our PM2 instance.

All this happens in an instant and should see your app deployed with no noticeable downtime.

]]>
<![CDATA[Setup Wifi and SSH on Raspberry Pi without a monitor]]> https://mrvautin.com/setup-wifi-and-ssh-on-raspberry-pi-without-a-monitor/ 2022-01-30T01:00:00.000Z Setting up Wifi and SSH on a Raspberry Pi can be a bit of a pain in the ass. Luckily Raspberry Pi Imager has made things simple with a new config panel to setup before writing the image.

  1. Download Raspberry Pi Imager here
  2. Install Raspberry Pi Imager on your OS
  3. Open Raspberry Pi Imager

Raspberry Pi Imager

  1. Windows - Press: CTRL+SHIFT+X
    MacOS - Press: CMD+SHIFT+X or CTRL+SHIFT+X
  2. You will be presented with a config to enter your Wifi details, SSH, Locale, Hostname, Keyboard layout and more.

Raspberry Pi Imager

]]>
<![CDATA[squido - A dead simple no-code static HTML website builder]]> https://mrvautin.com/squido-a-dead-simple-no-code-static-html-website-builder/ 2021-04-13T01:00:00.000Z

squido is a dead simple static website builder which can be hosted anywhere for super fast static HTML websites and very little effort.

The advantage of squido is that is has all the basics to build and deploy a static website built into the core. This means you don't have to waste time learning the ins and outs, writing code and play around with deployment. You simply do the writing and customization of style / layout and hit deploy.

Static websites have many benefits seen here but sometimes it's best to simply try for yourself.

So checkout the documentation, clone one of the demo repos and get started building your website today!

squido screenshot

]]>
<![CDATA[Advantages and disadvantages of a static html website vs a complex dynamic website]]> https://mrvautin.com/advantages-and-disadvantages-of-a-static-html-website-vs-a-complex-dynamic-website/ 2021-04-12T01:00:00.000Z What is a static website?

A static website is comprised entirely of HTML, CSS and Javascript code. In the past static websites were coded by hand but now there are a few builder tools which can compile and build a static website for you.

Advantages

  1. Speed: Static website generally render much faster than a dynamic website due to not having complex rendering, database queries etc.

  2. Cheap: Static websites can be developed and designed by almost anyone meaning there is reduced costs employing a developer to setup and maintain your website.

  3. Simplicity: Code is easy to read, easy to write and and easier to maintain. Templates/themes are normally provided and can easily be altered to suite your website needs.

  4. Hosting: There are more hosting options available for a static website, many of which are even free - eg: Github pages or Netlify which grab your code, build it and host it right from your Git repository. Server hosting needs less resources too due to only serving static content and not needing a Database and server processing.

Disadvantages

  1. Simplicity: Simplicity comes at a cost. Static websites lose the ability to do complex processing, database queries etc.

  2. Limitations: There are certain things you simply cannot do making static websites suited to certain website types.

When are static websites a good choice?

Whilst static websites are not suited for all situations, there are some really good instances where a static website is a good alternative to a complex dynamic one. Such as:

  • Blogs
  • Business websites
  • Community information
  • Documentation
  • Personal website
  • Resume
  • Portfolio
  • Photographer website

Getting started

The easiest way to get started is to grab yourself a builder like squido. There is some boiler plate / template examples for a blog or a documentation website to get you started.

You can simply clone these repositories, edit the template files, add your colors to the CSS and add your content. You can then follow the steps to deploy to a hosting provider.

]]>
<![CDATA[A dead simple module for storing and managing your environment variables in a simple and easy to read yaml file]]> https://mrvautin.com/a-dead-simple-module-for-storing-and-managing-your-environment-variables-in-a-simple-and-easy-to-read-yaml-file/ 2021-03-18T10:30:00.000Z Managing your environment variable in your different environments can be a pain. The idea behind envz is that this process is made super simple and easy to understand leading to less mistakes.

# with npm
npm install envz

# or with Yarn
yarn add envz

Repo: https://github.com/mrvautin/envz

Usage

You should use envz as early on in the entry point of your app as possible. Eg: app.js or index.js file which loads your app.

Rather than override process.env.x object, envz will return a new object to use throughout your app.

const { envz } = require('envz');

Create a env.yaml or any other named file and load it:

const env = envz('env.yaml');

env YAML file structure

The idea is that the process.env will be merged with loaded yaml file.

env uses a cascading (sequential order) configuration method which is easier to understand looking at an example.

base:
  PORT: 1234
  config:
    default: test

development:
  PORT: 3000
  DATABASE: dev
  config:
    token: 12345
    secret: fwdsdgl

production:
  PORT: 80
  DATABASE: prod
  config:
    token: 67890
    key: puwndklf
    truthy: true
    allowed:
      - card
      - phone

The idea here is that the values in base are loaded, anything in development overrides that and finally production overrides that depending on the NODE_ENV set.

For example, when a NODE_ENV of development is set the following env object is returned:

PORT: 3000,
config: { 
    default: 'test', 
    token: 12345, 
    secret: 'fwdsdgl' 
},
DATABASE: 'dev'
...

Eg: Where the PORT of 3000 from development overrides the base setting of 1234. If the NODE_ENV is set to production, then the PORT will be set to 80.

The idea behind base (or whatever you want to call it) is that you don't need to redefine defaults over and over for each environment.

Options

You can set the environment manually rather than using NODE_ENV by adding an environment object. Eg:

const env = envz('env.yaml', { environment: 'production' });

By default the values set in process.env overrides what is set in your yaml file. You can change this so that the yaml file is king by adding the following flag:

const env = envz('env.yaml', { yamlFileOverride: true });

Save / Update config

Sometimes you may want to store changes back to your envz config. You can easily do this by importing save:

const { save } = require('envz');

The save method takes an object with two values:

  • envfile: The yaml file you are wanting to update
  • data: The object you want to update back to the file. See tests and example below.
// In this case we will be adding to the `base` config but you can easily
// replace `base` with `production` or whatever environment.
const saveObj = await save({
    envfile: 'test.yaml',
    data: {
      base: {
        config: {
            default: 'default-key'
        }
      }
    }
});

This will result in the test.yaml being updated:

base:
  PORT: 1234
  config:
    default: default-key
...
]]>
<![CDATA[Visual Studio Code helpful snippets]]> https://mrvautin.com/visual-studio-code-helpful-snippets/ 2021-03-11T19:17:00.000Z If you are using VS Code its a huge shame if you aren't making use of the amazingly helpful snippets feature.

Setting up snippets is easy as:

Mac

Code > Preferences > User Snippets > Select a file or create a new one

Windows

File > Preferences > User Snippets > Select a file or create a new one

Once setup, snippets are triggered by pressing:

CTRL+Space

Snippet menu

Sometimes its easier to look at an example for the Snippets syntax.

A simple console.log can be sped up using the following syntax. Once triggered the snippet will create a console.log line and drop your cursor into the middle with single quotes wrapping.

{
    "Console log": {
        "scope": "javascript,typescript",
        "prefix": "log",
        "body": [
            "console.log('$1');"
        ],
        "description": "Log output to console"
    }
}
  • Scope: The file types this snippet is used for
  • Prefix: The snippet name when the snippet menu is opened
  • Body: The main part of the snippet driving the code
  • Description: The description of the snippet

Console logging

Simple console logging of text:

{
    "Console log": {
        "scope": "javascript,typescript",
        "prefix": "log",
        "body": [
            "console.log('$1');"
        ],
        "description": "Log output to console"
    }
}

Quick and easy logging of the variable in your clipboard.

{
    "Console log variable": {
		"scope": "javascript,typescript",
		"prefix": "log var",
		"body": [
			"console.log('${CLIPBOARD}', ${CLIPBOARD});"
		],
		"description": "Console log variable"
	}
}

Loops

Quick for loop

{
    "For Loop": {
        "prefix": ["for", "for-const"],
        "body": ["for (const ${2:element} of ${1:array}) {", "\t$0", "}"],
        "description": "A for loop."
    }
}

Wrapping text

Wrapping code blocks in the markdown code block syntax

{
    "Syntax highlighting": {
        "scope": "markdown",
        "prefix": "highlight",
        "body": [
            "``` javascript",
            "${TM_SELECTED_TEXT}",
            "```"
        ],
        "description": "Markdown highlight syntax"
    }
}

For more information on variables available see the official snippet docs.

]]>
<![CDATA[Interface with Arduino board using Node.Js]]> https://mrvautin.com/interface-with-arduino-board-using-node-js/ 2021-01-14T03:17:00.000Z There are many cheap and solid Arduino compatible boards on the market which can be interfaced/controlled using Node.Js. Today we are going to focus on the WeMos D1 R2 board which can be purchased here.

a2958102-5e39-4700-aab8-d56d49e67ab2

This guide assumes you know your way around Node.Js and have it installed along with NPM.

Firstly you are going to want to setup your board in the Arduino IDE. We will be flashing some simple Wifi firmware to get it on your Wireless network then we can talk to it using Node.Js.

  1. Select the board in the Arduino IDE:

    Tools > Board > ESP8266 Boards > WeMos D1 R2

  2. Plugin your board using a USB cable

  3. Open the Wifi firmware:

    File > Examples > Firmata > StandardFirmataWifi

  4. You are going to need to setup your Wifi SSID and Passphrase in the WifiConfig.h file. You shouldn't need to touch the StandardFirmataWifi.h file at all.

  5. Scroll to the section which has the Wifi SSID configuration and enter the name of your Wifi network (SSID):

        // replace this with your wireless network SSID
        char ssid[] = "your_network_name";
    
  6. Scroll to the section which has the Security configuration and enter your passphrase or Wifi password:

        #ifdef WIFI_WPA_SECURITY
        char wpa_passphrase[] = "your_wpa_passphrase";
        #endif //WIFI_WPA_SECURITY
    
  7. Thats it. You can now compile and upload the code to your board using the Upload button

  8. Once that is complete, your board will reset and hopefully connect to your Wifi network.

  9. You can now login to your router to check the Wireless clients and determine the IP address of your board. At this point you might like to reserve an IP address using the MAC address for your board so it doesn't change on restart and kill your Node.Js code.

  10. Now we are going to setup our Node.Js code to do some simple requests/commands.

    Install our dependencies
    npm i etherport-client johnny-five --save

  11. Your package.json should look something like this:

    {
        "name": "nodejs-test",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "author": "",
        "license": "ISC",
        "dependencies": {
            "etherport-client": "^0.1.4",
            "johnny-five": "^2.0.0"
        }
    }
    
  12. Now to our Node.Js code. We are going to make the little blue light flash which sits next to the silver WeMos chip on our board:

    You will need to change the IP address to the one you found in step 9.

    
        const { EtherPortClient } = require('etherport-client');
        const { Board, Led } = require('johnny-five');
        
        const board = new Board({
            port: new EtherPortClient({
                host: '192.168.0.201',
                port: 3030
            }),
            repl: false
        });
        
        const LED_PIN = 2;
        
        board.on('ready', () => {
            console.log('Board ready');
            var led = new Led(LED_PIN);
            led.blink();
        });
    
  13. Now run your code and check the output in the console and the light action on your board.

    You should see some output like this:

        1610519728478 SerialPort Connecting to host:port: 192.168.0.201:3030
        1610519728496 Connected Connecting to host:port: 192.168.0.201:3030
        Board ready
    

And some light action here:
IMG_0809

]]>
<![CDATA[La Marzocco - Machine Vector Art & logos]]> https://mrvautin.com/la-marzocco-vector-art/ 2021-01-08T06:21:44.000Z La Marzocco Linea Mini (SVG)

La Marzocco GS3 (SVG)

Logos

La Marzocco Logo

La Marzocco Lion

La Marzocco cursive logo

]]>
<![CDATA[Ghost - You are recommended to have at least 150 MB of memory available]]> https://mrvautin.com/ghost-you-are-recommended-to-have-at-least-150-mb-of-memory-available/ 2019-06-10T01:25:32.000Z Sometimes running Ghost on lower powered server like a Digital Ocean $5 droplet can cause the Ghost CLI to complain about lack of memory: Message: You are recommended to have at least 150 MB of memory available for smooth operation. It looks like you have ~87 MB available.

Screenshot

Adding the --no-mem-check quickly bypasses this error and gets you on your way.

Command: ghost update --no-mem-check

]]>
<![CDATA[Bank Loan repayment and interest calculator]]> https://mrvautin.com/bank-loan-repayment-and-interest-calculator/ 2019-04-05T23:54:42.000Z Ever wanted to calculate the repayments on a loan? Ever wanted to know how much interest you will pay over the term of your loan? You are not alone!

We have created a very simple and beautiful loan calculator so you can quickly and easily see these figures before taking the big step and applying.

Enjoy! Loan calculator

]]>
<![CDATA[Connecting to MongoDB Atlas with Robo 3T / Robomongo]]> https://mrvautin.com/connecting-to-mongodb-atlas-with-robo-3t/ 2018-10-10T13:09:18.000Z Sometimes you may want to do development on your database and connect via a GUI to test results. Connecting to MongoDB Atlas is very easy with Robo 3T / Robomongo, simply follow these steps.

  1. Setup your first DNS in your cluster

  2. Fill in Database as "admin", Username/Password as per the user setup in MongoDB Atlas.

  1. Skip SSH tab

  2. Click "Use SSL protocol" then select "Self-signed Certificate" from the dropdown.

  1. Click "Test" button and then "Save"and you are done!
]]>
<![CDATA[The best free blog software]]> https://mrvautin.com/the-best-free-blog-software/ 2018-05-20T05:20:56.000Z Fortunately there are a lot of options for free software to host your shiny new blog. You have definitely heard about Wordpress but is it the best option? Well in my option.. no, it's not.

Sure Wordpress has all the bells and whistles with plugins for just about everything but they generally take your website from a blog to a shopping cart or CMS etc. You need to ask yourself, do I really need this stuff? If the answer is no and you just need a blog then Ghost is the way to go.

Ghost allows you to quickly and easily setup a beautiful and powerful blog within minutes. There is a cloud hosted option (cost) or a free host your own option.

Best of all, Ghost is powerful but not vulnerable and requiring updates every 10 minutes for the 50 Wordpress plugins you have installed.

So next time you are looking for some blogging software, give Ghost a go!

]]>
<![CDATA[Screenshot to clipboard on Apple Mac OSX]]> https://mrvautin.com/screenshot-to-clipboard-on-apple-mac-osx/ 2018-05-20T04:43:28.000Z To copy a portion of the screen to the clipboard, press Command-Control-Shift-4. A cross-hair cursor will appear and you can click and drag to select the area you wish to capture. When you release the mouse button, you can paste the screen shot to another application.

]]>
<![CDATA[Nodejs - Re-use MongoDB database connection in routes]]> https://mrvautin.com/re-use-mongodb-database-connection-in-routes/ 2018-04-12T20:55:22.000Z Quite often when you are writing an application you will need access to one or more database connections. Maybe MongoDB for data storage and Redis for cache. You will need to re-use that database connection throughout your application. I'm going to go through a simple way of re-using the connection in modules, Express routes etc.

Creating the helper

Firstly you will want to create your db.js file which will export some handy database related functions.

File: db.js

    const mongoClient = require('mongodb').MongoClient;
    const mongoDbUrl = 'mongodb://127.0.0.1:27017';
    let mongodb;

    function connect(callback){
        mongoClient.connect(mongoDbUrl, (err, db) => {
            mongodb = db;
            callback();
        });
    }
    function get(){
        return mongodb;
    }

    function close(){
        mongodb.close();
    }

    module.exports = {
        connect,
        get,
        close
    };

After creating this file you can simply require it and you now have few functions at our disposal. connect, get, close.

Connecting

File: app.js

You will then want to call connect() before your application starts and the server starts listening. Eg:

    db.connect(() => {
        app.listen(process.env.PORT || 5555, function (){
            console.log(`Listening`);
        });
    });

Now you have access to your database connection anywhere in your application by simply requiring the db.js file and using the get() function.

Using the connection

File: users.js (routes file for example)

const db = require('./db');

router.get('/users', (req, res) => {
	db.get().collection('users').find({}).toArray()
	.then((users) => {
            console.log('Users', users);
        });
});

It just makes everything much cleaner and easy to handle this way. I hope this helped you in some way.

]]>
<![CDATA[Dokku - Could not read from remote repository on digital ocean]]> https://mrvautin.com/dokku-could-not-read-from-remote-repository-on-digital-ocean/ 2017-02-17T08:44:11.000Z Firing up a digital ocean droplet with one-click dokku should be easy right? Yeah well if you get this error it's due to your SSH keys not being added correctly either when setting up the droplet or if you did it yourself.

You simply need to run:

cat ~/.ssh/id_rsa.pub | ssh root@droplet_ip_address "sudo sshcommand acl-add dokku laptop"

]]>
<![CDATA[Adding new lines to your IFTTT recipes]]> https://mrvautin.com/adding-new-lines-to-your-ifttt-recipes/ 2017-01-28T06:30:01.000Z Adding breaks or new lines to your ifttt recipes can be a difficult task. Facebook seems to be particularly picky with it's new line characters where standard new lines like \r \r\n and <br> are ignored.

The solution:

<br>&nbsp;<br>&nbsp;<br>

No worries, glad I could help!

]]>
<![CDATA[Enabling custom domain for SaaS application on Heroku]]> https://mrvautin.com/enabling-custom-domain-for-saas-application-on-heroku/ 2017-01-24T23:40:29.000Z If you are running a SaaS application on Heroku you might notice that it's difficult enabling the users of the SaaS application to bring their own custom domain using a DNS CNAME. When the request comes into Heroku the platform will return the "No such application" error. The Heroku support team suggests adding a custom domain to the Heroku dashboard for each SaaS user. I could see this getting out of hand so I decided to implement a proxy server to fix the issue.

Firstly you will want to add your own wildcard custom domain to your Heroku application and also create a CNAME with your DNS provider.

Adding your CNAME with your DNS provider to point to Heroku:

Hostname: *.mydomain.com
Path: my_heroku_app_name.herokuapp.com

Adding your domain to the Heroku dashboard:

Domain Name: *.mydomain.com
DNS Target: my_heroku_app_name.herokuapp.com

You will then want to setup your proxy server. I spun up a new Digital Ocean droplet and setup Nginx to proxy the requests.

The Nginx config would look like this:

server {
    listen 80 default_server;

    server_name proxy.mydomain.com;

    location / {
        proxy_set_header    Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    Host $host-customdomain.mydomain.com;
        proxy_redirect      off;
        proxy_pass          http://my_heroku_app_name.herokuapp.com;
    }
}

Basically what is happening is your Nginx server is adding the Host header and proxing the request onto Heroku. The Heroku router will then read the Host header and determine which application to select. It's then that your application will need to determine the domain in the request and serve the correct SaaS user.

You will then need to setup an A DNS record with your DNS provider to point to the new proxy server:

Hostname: proxy.mydomain.com
Path: 192.168.0.1 (This IP is your Digital Ocean droplet IP)

You will then want your users of your SaaS application who are wanting a custom domain to point their DNS to proxy.mydomain.com.

Your Saas application will then need to get the Host header, remove -customdomain.mydomain.com and determine who the customer of your SaaS application is.

]]>
<![CDATA[Building a reliable and scalable Node.JS SaaS application]]> https://mrvautin.com/building-a-reliable-and-scalable-node-js-saas-application/ 2017-01-22T03:50:10.000Z The SaaS app we built is an FAQ/Knowledge base and support ticketing platform called ezyFAQ - www.ezyfaq.com

Having built many Node.Js projects, this would be our first venture into building a scalable SaaS app. After our initial investigation on where we should start, we couldn't find much advice on where to start and things to look out for. We found vague articles on various projects built many years ago but nothing using modern tech, in particular Node.JS.

We are intending this article to be helpful to anyone wanting to build a SaaS app using Node.Js.

Hosting

Up until this project we built our apps on self managed Digital Ocean VM's. This was fine in isolation but we found it difficult to find any information on scaling and load balancing to grow with the app user base.

We decided to go with a dedicated Node.Js host (Heroku) which used the Dyno type approach. This seemed like the best approach to easily scale as the customer base and load grows.

Database

Generally our database of choice to pair with Node.JS is MongoDB. After trying and considering various other databases, we decided to stick with MongoDB.

Hosting MongoDB yourself is easy enough but we wanted something more reliable with load balancing/redundancy, scaling and backups. There are various options from MongoDB Atlas, Compose.io, mLab etc. After some consideration, we went with mLab for easy of use, scalability and best price.

Application structure

This is where we spent most of our time trying to figure out the best approach. There are two parts to the app: the front and backend. The frontend is the part of the app which would see all the public traffic. Each customer of our app would have their own FAQ with a subdomain (and optional custom domain) which would see significant traffic. The backend is the management side for our customers where they would manage settings, content, style and more. The backend would receive minimal traffic in comparison to the public facing frontend and so would have much less of a need to scale.

Instead of creating one big app we decided to split them out and run on seperate Heroku plans. This way we can scale the frontend easily whilst leaving the backend as it. It also means we can easily do maintenance, add features etc without affecting the public facing side of the app.

Conclusion

We learnt a lot. First of all, we learn't that making a standalone app into a SaaS is not as easy as it sounds. There are many different aspects which need to be considered and worked through. We found that scalability and being flexible was the key to our success and this is where we spent most of our time. We also found that doing everything and managing everything is not the always the best thing. Leave the server and DB hosting to a dedicated company to manage it for you. As a startup, you can't possibly be professional and perfect at everything. You can always bring services back in house as you grow and your available skill set grows too.

We would love to hear feedback from others who have faced similar hurdles getting their SaaS app off the ground and how they dealt with them.

]]>
<![CDATA[ezyFAQ An easy-to-use yet beautiful and powerful FAQ/Knowledge base]]> https://mrvautin.com/ezyfaq-an-easy-to-use-yet-beautiful-and-powerful-faq-knowledge-base/ 2016-11-18T23:27:00.000Z ezyFAQ is a very powerful yet affordable solution to setup a FAQ/knowledge base without all the complexities (and cost) of Zendesk and other solutions. Studies have shown that most customers would much prefer to quickly find the solution themselves rather than wait on an email response or make a phone call.

ezyFAQ allows for customising your FAQ/knowledge base with branding, CSS and HTML. ezyFAQ also allows you to bring your own domain for a seamless integration with your existing website - e.g: help.mydomain.com. The live search, analytics, responsive design (also beautiful on Tablets and Phones), pre-built themes and templates allow you to customise a little or a lot!

ezyFAQ runs its own FAQ using the ezyFAQ platform which you can view here: http://support.ezyfaq.com

More information can be found at www.ezyfaq.com

]]>
<![CDATA[Writing your first Node.js module]]> https://mrvautin.com/writing-your-first-node-js-module/ 2016-09-03T01:14:52.000Z This isn't meant to be an exhaustive guide on how to write an NPM module. This guide is meant to be a simple working example where you can see a basic working module and easily adapt this to create your own module.

You can see the basic structure is really easy to understand. We are exposing the multiply() function as a public function by returning in the module.exports. The other function aptly named nonPublic() is called by the multiply() function but cannot be called publicly. More on this below.

You can see our multiply() function takes two values, multiplies them and returns a label from our nonPublic() function, followed by our multiplied value. Easy!

File: multiply.js

// require any modules

module.exports = {
	multiply: function (val1, val2, callback){
        var returnedValue = val1 * val2;
		callback(null, nonPublic() + returnedValue);
	}
};

function nonPublic(){
    return 'Result: ';
}

File: test.js

Using our new module locally for testing is easy:

var mod = require('./module');

console.log(mod.nonPublic());

mod.multiply(5, 10, function(err, result){
    console.log(result);
});

The first line requires our local module. Note: the ./ value for modules located in the same directory.

After we have required it we can go ahead and use it. First we call the nonPublic() function to show it doesn't work publicly (this outputs an error), then call the multiply() function.

We pass in 5 and 10 to be multiplied together and we write the result to the console.

To run our test.js script we simply run the following in our console and observe the output:

node test.js

Conclusion

This is a really basic module which outlines the basic steps to get started on writing your first NPM module.

One of my slightly (hardly) more advanced (has options etc) modules metaget can be found here as further reading: https://github.com/mrvautin/metaget

]]>
<![CDATA[Ensure Express App has started before running Mocha/Supertest tests]]> https://mrvautin.com/ensure-express-app-started-before-tests/ 2016-06-19T05:12:19.000Z Seems simple enough but when running tests, I ran into a problem where Mocha/Supertest was not waiting for my Express App to fully start running tests.

The relatively easy way to overcome this is to use an event emitter in your Express app and wait for that to complete before starting your tests. This doesn't appear to be documented anywhere obvious.

You will need to setup the event emitter in your Express app which is the final step before assuming the app has started and is ready. In my case, I had made the DB connection etc and now the call to app.listen was my final event.

Here is an example:

app.listen(app_port, app_host, function () {
    console.log('App has started');
    app.emit("appStarted");
});

The specific line is:

app.emit("appStarted");

This creates an event which we can wait on called appStarted (this can be changed to whatever you want).

Next we need to wait for this event in our Mocha/Supertest tests (test.js).

First we will require our Express app. Note: app is my main Express file, some people use server.js and this value would then become require('../server'):

app = require('../app');

We then need to create a Supertest agent using our Express instance:

var request = require("supertest");
var agent = request.agent(app);

Then we wait for our Express event using before():

before(function (done) {
    app.on("adminMongoStarted", function(){
        done();
    });
});

Then we can kick off all our tests. A full test example:

var request = require("supertest");
var assert = require('chai').assert;

app = require('../app');
var agent = request.agent(app);

before(function (done) {
    app.on("appStarted", function(){
        done();
    });
});

describe("Add config",function(){
    it("Add a new connection",function(done){
        agent
            .post("/add_config")
            .expect(200)
            .expect("Config successfully added", done);
    });
});
]]>
<![CDATA[markdownTables - Convert your HTML tables into Markdown syntax online]]> https://mrvautin.com/markdowntables-convert-your-html-tables-into-markdown-syntax-online/ 2016-05-17T06:47:08.000Z markdownTables is an online tool which enables you to paste in your HTML table code and convert it to Markdown table syntax.

markdownTables

]]>
<![CDATA[authorStats - Get your NPM package download statistics in an easy to read command line table]]> https://mrvautin.com/authorstats-get-your-npm-package-download-statistics-in-an-easy-to-read-command-line-table/ 2016-05-06T10:37:13.000Z authorStats fetches your daily/weekly/monthly download stats for all your authored NPM packages and outputs a nice table right in your command line.

Installation

It's best to install the package globally:

npm install author-stats -g

Usage

authorStats <npm username>

Where <npm username> is the username on the NPM website. My profile is: https://www.npmjs.com/~mrvautin and username is mrvautin.

A nice command line table with the daily, weekly and monthly download numbers of all your packages will be output to your terminal.

Note: If you have a lot of packages you will need to be patient while authorStats fetches the data.

]]>
<![CDATA[expressCart - A Nodejs Shopping Cart application]]> https://mrvautin.com/expresscart-a-nodejs-shopping-cart-application/ 2016-04-29T05:19:49.000Z expressCart is a Shopping Cart built with Nodejs and ExpressJS. The application has PayPal Express Checkout, Stripe checkout and Authorize.Net built-in. expressCart uses MongoDB database backend.

The application is designed to be easy to use and install and based on search for simplicity rather than nested categories. Simply search for what you want and select from the results. expressCart uses powerful lunr.js to index the products and enable the best search results.

Website: https://expresscart.markmoffat.com/

Demo: https://expresscart-demo.markmoffat.com

Features

  • Payments: expressCart has built in PayPal Express Checkout or Stripe checkout.
  • Search: expressCart is a search based Shopping Cart backed by Lunr.js indexing to create the best possible results on searches.
  • Backend: expressCart uses MongoDB for a database.
  • Design: expressCart has a simple flat and responsive design.
  • Responsive: expressCart is built using Bootstrap, allowing it to be responsive and work on all devices.
  • Themes: expressCart allows for custom themes to style the cart exactly how you like it.

Screenshots

Homepage: Homepage

Admin manage settings: Admin manage settings

Popout cart: Popout cart

Dashboard: Dashboard

Running in production

Using PM2 is the easiest and best option for running production websites. See the PM2 for more information or a short guide here: https://mrvautin.com/running-nodejs-applications-in-production-forever-vs-supervisord-vs-pm2/.

]]>
<![CDATA[ghostStrap - A minimalist and responsive Bootstrap theme for the Ghost blogging platform]]> https://mrvautin.com/ghoststrap-a-minimalist-and-responsive-bootstrap-theme-for-the-ghost-blogging-platform/ 2016-04-18T07:34:48.000Z Upon setting up my Ghost blog, I wanted a themewhich was compatible with Bootstrap as I'm familiar with the layout and it's rock solid in terms of responsive design. I was surprised to find that either the Bootstrap themes was really old and out of date or were way over the top and not a good starting point to add my touches.

This pushed me to design ghostStrap which can easily be used as a starting point for anyone wanting to create a theme using the Bootstrap standard.

Installation

Some commands may need sudo

  1. From the root of your Ghost install: cd content/themes/
  2. git clone https://github.com/mrvautin/ghostStrap.git
  3. Restart Ghost
  4. Visit the admin panel: http://localhost:2368/ghost
  5. Select General
  6. Select ghostStrap from the Theme dropdown
  7. Have fun

Please leave a comment if you use the theme or have any feedback.

Screenshots

Homepage

Homepage

Single post

Single Post

Menu

Menu

Mobile layout

Mobile layout

Menu

Mobile layout menu

]]>
<![CDATA[How to add search functionality to your Ghost blog]]> https://mrvautin.com/how-to-add-search-functionality-to-your-ghost-blog/ 2016-04-17T00:34:38.000Z Adding search to your Ghost blog is relatively simple but requires a small amount of skill to edit your theme files. You can see how search works on the homepage of this blog.

First of all, you need to turn on the Ghost Public API (which by default is turned off). You will want to jump into your Ghost admin www.myblog.com/ghost, select Labs from the menu, scroll to the bottom and check the box Public API.

Now this is turned on, our code will be able to interact with the API to index and search posts.

We are going to use the following Github repository by Windyo here: https://github.com/Windyo/ghostHunter/ this is a Fork of the popular ghostHunter module but has been updated to use the Ghost API, rather than using and hacking RSS feeds. Ghosthunter uses the extremely powerful Lunr library to index your posts and provide the best, weighted keyword search results.

You will need to download the file jquery.ghostHunter.min.js from the Github repository and add it to your theme: /content/themes/mytheme/assets/js/.

You will then need to add a reference to that file in: /content/themes/mytheme/default.hbs

{% raw %}
 <script type="text/javascript" src="{{asset "js/jquery.ghostHunter.min.js"}}"></script>
 {% endraw %}

Note: Add it at the bottom of the file after the jQuery reference

Once you have done that you can start adding the search box to your page(s).

You will need some javascript which calls the Ghosthunter module to display the results of the search. You will need to add the following code to your /content/themes/mytheme/assets/js/index.js file.

There are various options on the Ghosthunter module. I've decided to display results as they are typed and have set the onKeyUp to true and have chosen to hide the number of results by setting displaySearchInfo to false. Check the Github repository for more options.

$(".search-results").addClass("results-hide");
$("#search-field").ghostHunter({
    results: "#search-results",
    onKeyUp: true,
    displaySearchInfo: false,
    result_template : "<a href='{{link}}'><li class='list-group-item'>{{title}}</li></a>",
    before: function(){ 
        $(".search-results").removeClass("results-hide");
    }
}); 

Note: My theme is using Twitter Bootstrap so you will see references to list-group-item etc which you can remove and add your own CSS styling.

Next thing you need to do is add some simple CSS to your /content/themes/mytheme/assets/js/screen.css to format the search and results box.

.search-box{
    margin-bottom: 10px;
}

.search-results {
    position:absolute;
    z-index: 1000;
}

.search-button{
    background-color: #1B95E0;
    color: white;
}

.results-hide{
    display: none;
}

Note: You can edit styling as you wish.

Lastly you will need to add the search box to your template file: /content/themes/mytheme/index.hbs. You can also add this to your post.hbs view too if you wish.

<div class="row">
    <div class="search-box col-xs-12 col-sm-12 col-md-4 col-md-offset-4 col-lg-4 col-lg-offset-4">
        <div class="input-group">
            <input type="text" id="search-field" class="form-control input-lg" placeholder="Search for...">
            <span class="input-group-btn">
                <button class="btn btn-default search-button btn-lg" type="button">Search!</button>
            </span>               
        </div>
    </div>
</div>
<section class="search-results col-xs-12 col-sm-12 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2" >    
        <ul id="search-results" class="search-results col-md-12" class="list-group"></ul>
</section>

Please let me know in the comments what you think.

]]>
<![CDATA[How to setup HTTPS on your Ghost blog and avoid redirect loop]]> https://mrvautin.com/how-to-setup-https-on-your-ghost-blog-without-redirect-loop/ 2016-04-15T00:05:00.000Z If you are wanting to setup your Ghost blog URL to be HTTPS (SSL), you will need to ensure your Web Server is sending the correct Headers to Ghost. Failing to do so can cause your Blog to go into a endless redirect loop and fail to work.

The production section of your Ghost config.js will look something like this:

production: {
	url: 'https://mrvautin.com',
	mail: {},
	database: {}
}

Depending on your web server the setting is slightly different. We are going to cover off Apache and Nginx as they are most popular.

For Nginx

A simple Nginx config would look like:

server {
	listen 443 ssl;
	server_name mrvautin.com www.mrvautin.com;
	# SSL STUFF

	location / {
		proxy_set_header        X-Real-IP $remote_addr;
		proxy_set_header        Host    $http_host;
		proxy_pass              http://127.0.0.1:2368;
		proxy_set_header        X-Forwarded-Proto $scheme;
	}
}

The important line above is:

proxy_set_header X-Forwarded-Proto $scheme;

This line ensures the Header which Ghost reads has the correct protocol set.

For Apache

A simple Apache virtual host config would look like:

<VirtualHost *:443>
    RequestHeader set X-Forwarded-Proto "https"
    ProxyPreserveHost On
    ServerName mrvautin.com

    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/server.crt
    SSLCertificateKeyFile /etc/apache2/ssl/server.key

    <Location/>
        SSLRequireSSL
    </Location>

    ProxyPass / http://127.0.0.1:2368
    ProxyPassReverse / http://127.0.0.1:2368
</VirtualHost>

The important line above is:

RequestHeader set X-Forwarded-Proto "https"

This line ensures the Header which Ghost reads has the correct protocol set.

]]>
<![CDATA[How to change the post excerpt of your Ghost theme to HTML]]> https://mrvautin.com/how-to-change-the-excerpt-text-to-html-formatting/ 2016-04-12T00:50:52.000Z The Casper theme by default has an excerpt with all HTML tags / formatting removed. You can change this in your theme by editing the /content/themes/mytheme/partials/loop.hbs file of your theme.

In the loop.hbs file you will see:

{% raw %}
{{excerpt words="26"}}
{% endraw %}

You will need to change the word excerpt to content. The new code will be:

{% raw %}
{{content words="26"}}
{% endraw %}

If you are wanting to change the length (amount of words) of the excerpt please see here.

]]>
<![CDATA[How to change the post excerpt length in your Ghost theme]]> https://mrvautin.com/how-to-change-the-excerpt-length-in-your-ghost-theme/ 2016-04-12T00:26:52.000Z Changing the post excerpt length (teaser text) of your theme is relatively simple. You will need to edit the /content/themes/mytheme/partials/loop.hbs

When opening your loop.hbs file you will see code like the this:

You can change the default Casper value of 26 to any value you want:

You can play around and change this value and see what length best suits your writing style and theme.

]]>
<![CDATA[metaget - Nodejs module to fetch remote Meta Tags (including Open Graph) from URL]]> https://mrvautin.com/metaget/ 2016-04-11T06:02:50.000Z A Node.js module to fetch HTML meta tags (including Open Graph) from a remote URL

Installation

npm install metaget --save

Usage

var metaget = require("metaget");
metaget.fetch('https://wordpress.com', function (err, meta_response) {
	if(err){
		console.log(err);
	}else{
		console.log(meta_response);
	}
});

Response will be a Javascript Object containing all the meta tags from the URL. All tags are output in the example above. Some tags with illegal characters can be accessed by:

meta_response["og:title"];

Options

It's possible to set any HTTP headers in the request. This can be done by specifying them as options in the call. If no options are provided the only default header is a User-Agent of "request".

This is how you would specify a "User-Agent" of a Google Bot:

var metaget = require("metaget");
metaget.fetch('https://wordpress.com',{headers:{"User-Agent": "Googlebot"}}, function (err, meta_response) {
	if(err){
		console.log(err);
	}else{
		console.log(meta_response);
	}
});

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D
]]>
<![CDATA[adminMongo]]> https://mrvautin.com/adminmongo/ 2016-04-04T00:05:00.000Z adminMongo is a Web based user interface (GUI) to handle all your MongoDB connections/databases needs. adminMongo is fully responsive and should work on a range of devices.

adminMongo connection information (including username/password) is stored unencrypted in a config file, it is not recommended to run this application on a production or public facing server without proper security considerations.

Installation

  1. Clone Repository: git clone https://github.com/mrvautin/adminMongo.git && cd adminMongo
  2. Install dependencies: npm install
  3. Start application: npm start
  4. Visit http://127.0.0.1:1234 in your browser

Features

  • Manage from a connection level for easy access to multiple databases
  • Create/Delete databases
  • Create/Delete/Edit collection
  • Create/Delete/Edit documents
  • Create/Delete indexes
  • Query documents
  • Collection statistics
  • Export collections in JSON format

Limitations

  • Documents need to have an "_id" value which is a string, integer, or MongoDB ObjectId. Documents using Composite ID indexing is currently not supported.

Configuration

adminMongo will listen on host: localhost and port: 1234 by default. This can be overwritten by adding a config file in /config/app.json. The config file can also override the default 5 docs per page. The config file options are:

{
    "app": {
        "host": "10.0.0.1",
        "port": 4321,
        "docs_per_page": 15
    }
}

Usage

Create a connection

After visiting http://127.0.0.1:1234 you will be presented with a connection screen. You need to give your connection a unique name as a reference when using adminMongo and a MongoDB formatted connection string. The format of a MongoDB connection string can form: mongodb://<user>:<password>@127.0.0.1:<port>/<db> where specifying to the <db> level is optional. For more information on MongoDB connection strings, see the official MongoDB documentation.

Note: The connection can be either local or remote hosted on VPS or MongoDB service such as MongoLab.

Connection/Database admin

After opening your newly created connection, you are able to see all database objects associated with your connection. Here you can create/delete collections, create/delete users and see various stats for your database.

Collections

After selecting your collection from the "Database Objects" menu, you will be presented with the collections screen. Here you can see documents in pagination form, create new documents, search documents, delete, edit documents and view/add indexes to your collection.

Searching documents

You can search documents using the Search documents button on the collections screen. You will need to enter the key (field name) and value. Eg: key = "_id" and value = "569ff81e0077663d78a114ce".

You can clear your search by clicking the Reset button on the collections screen.

Documents

Adding and editing documents is done using a JSON syntax highlighting control.

Indexes

Indexes can be added from the collection screen. Please see the official MongoDB documentation on adding indexes.

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D
]]>
<![CDATA[Winterboard theme iOS9 common Bundle ID / Icon list]]> https://mrvautin.com/winterboard-theme-ios9-common-bundle-id-icon-list/ 2015-11-21T21:48:00.000Z Common App Bundle ID list (case sensitive)

These are used in your mytheme.theme/Bundles folder.

App Name Bundle ID
1Password com.agilebits.onepassword-ios
500px com.500px
9gag com.9gag.ios.mobile
Activator libactivator
Airbnb com.airbnb.app
Amazon com.amazon.Amazon
App Store com.apple.AppStore
Ask Fm fm.ask.askfm
BiteSMS com.bitesms
Calculator com.apple.calculator
Calendar com.apple.mobilecal
Camera + com.taptaptap.cloudphotos
Camera com.apple.camera
Chase Mobile com.chase
Circle the Dot com.ketchapp.circlethedot
Clock com.apple.mobiletimer
CNN com.cnn.iphone
Compass com.apple.compass
Contacts com.apple.MobileAddressBook
Digg com.digg.Digg
Dropbox com.getdropbox.Dropbox
Ebay com.ebay.iphone
Edline com.alecgorge.Brebeuf-Edline
Engadget com.aol.engadget
ESPN SportsCenter com.espn.ScoreCenter
eTrade com.etrade.mobileproiphone
ETSY com.etsy.etsyforios
Evernote com.evernote.Evernote
Evernote com.evernote.iPhone.Evernote
Facebook Groups com.facebook.Groups
Facebook Page Admin com.facebook.PageAdminApp
Facebook Paper com.facebook.Paper
Facebook com.facebook.Facebook
Facetime com.apple.facetime
FB Messenger com.facebook.Messenger
Find my iPhone com.apple.mobileme.fmip1
Firefox org.mozilla.ios.Firefox
Flappy Bird com.dotgears.flap
Fleksy com.syntellia.Fleksy
Foap com.foap.foap
Game Center com.apple.gamecenter
Gamestop com.gamestop.powerup
Google + com.google.GooglePlus
Google Chrome com.google.chrome.ios
Google Chromecast com.google.Chromecast
Google Docs com.google.Docs
Google Drive com.google.Drive
Google Gmail com.google.Gmail
Google Inbox com.google.inbox
Google Maps com.google.Maps
Google Photos com.google.photos
Google Search com.google.GoogleMobile
Google Translate com.google.Translate
Health com.apple.Health
iBooks com.apple.iBooks
iFile eu.heinelt.ifile
iMessage com.apple.MobileSMS
iMovie com.apple.iMovie
Instagram com.burbn.instagram
iTunes Connect com.apple.itunesconnect.mobile
iTunes Store com.apple.MobileStore
Kickstarter com.kickstarter.kickstarter
LinkedIn com.linkedin.LinkedIn
Mail com.apple.mobilemail
Make it Rain com.SpaceInch.LoveOfMoney
Maps com.apple.Maps
Medium com.medium.reader
ModMyi com.modmyi.ModMyi
Music com.apple.Music
Myspace com.myspace.iPhone
Netflix com.netflix.Netflix
Notes com.apple.mobilenotes
Ookla Speedtest com.ookla.speedtest
Oovoo com.oovoo.iphone.free
Outlook com.microsoft.Office.Outlook
outube com.youtube.ios.youtube
Pandora com.pandora.pandora
Passbook com.apple.Passbook
Paypal com.yourcompany.PPClient
Phonto com.youthhr.Phonto Y
PhotoMath com.microblink.PhotoMath Xbox
Photos com.apple.mobileslideshow
Photoshop Express com.adobe.PSMobile
Piano Tiles com.umonistudio.tapTile
Podcasts com.apple.podcasts
Quizup com.plainvanillacorp.quizup
Reddit com.tyanya.reddit
Reeder ch.reeder
Release Slow Shutter com.cogitap.SlowShutter
Reminders com.apple.reminders
Remote Mouse com.remotemouse.remoteMouse
Remote com.apple.Remote
Safari com.apple.mobilesafari
Settings com.apple.Preferences
Skype com.skype.skype
Smartglass com.microsoft.xboxavatars
Snapchat com.toyopagroup.picaboo
SoundHound com.melodis.midomi
Spotify com.spotify.client
Square Cash com.squareup.cash
Stay in the Line com.six8t.StayInTheLine
Stocks com.apple.stocks
Stop Motion com.cateater.funapps.stopmotion
Swing Copters com.dotgears.swing
Teamviewer com.teamviewer.teamviewer
Terminal com.googlecode.mobileterminal.Terminal
Testflight com.apple.TestFlight
Things com.culturedcode.ThingsTouch
Tinder com.cardify.tinder
Tips com.apple.tips
Tumblr com.tumblr.tumblr1Password
Tweetbot 3 com.tapbots.Tweetbot3
Tweetbot 4 com.tapbots.Tweetbot4
Tweetbot iPad com.tapbots.TweetbotPad
Tweetbot com.tapbots.Tweetbot
Twitter com.atebits.Tweetie2
Ultimate Guitar Tabs com.ultimateguitar.tabs100
Viber com.viber
Videos com.apple.videos
Vidgets com.lesscode.widgetcenter
Vimeo com.vimeo
Voice Memos com.apple.VoiceMemos
Weather com.apple.weather
WhatsApp net.whatsapp.WhatsApp
Winterboard com.saurik.Winterboard
WWDC developer.apple.wwdc
WWDC developer.apple.wwdc-Release
Yahoo Weather com.yahoo.weather
YouTube com.google.ios.youtube

Common icon names and sizes (px):

Icon name Size
AppIcon76x76~ipad.png 76x76
AppIcon29x29@2x.png 58x58
AppIcon40x40@2x.png 80x80
AppIcon60x60@2x.png 120x120
AppIcon76x76@2x~ipad.png 152x152
AppIcon29x29@3x.png 87x87
AppIcon40x40@3x.png 120x120
AppIcon60x60@3x.png 180x180
]]>
<![CDATA[Cydia - Live NBA scores right on your iPhone lockscreen]]> https://mrvautin.com/cydia-live-nba-scores-right-on-your-iphone-lockscreen/ 2015-11-16T21:54:00.000Z I admit, I'm addicted to following the NBA scores live. The problem I was having was either leaving my iPhone unlocked on the ESPN or NBA app and killing my battery or unlocking my phone (pin/fingerprint) every 5 seconds to see the scores! This is where the "NBA Lockscreen scores" package (Free on Modmyi repo) comes in. You can simply hit the home button to bring up your lockscreen and the updated scores and right there waiting.

[Cydia link](cydia://search/nba lockscreen scores)

]]>
<![CDATA[Easy way of moving notes from iPhone to iCloud]]> https://mrvautin.com/easy-way-of-moving-notes-from-iphone-to-icloud/ 2015-10-02T10:21:00.000Z You may experience an issue where older notes are considered "ON MY IPHONE" and not backed up to iCloud you have two options. 1: manually copy all notes into new ones which by default sit on iCloud. 2: follow the steps below.

  1. Select "Notes" section below "ON MY IPHONE".

notes on my iPhone

  1. Select "edit" (top right), select notes manually or select "Move All" (bottom left)

select notes

  1. Select "Notes" under "ICLOUD" section to copy notes.

select iCloud

NOTE: The app may not update the number of notes until it's closed and reopened.

]]>
<![CDATA[openKB - Open Source Nodejs Markdown based knowledge base (FAQ) app]]> https://mrvautin.com/openkb-an-open-source-nodejs-knowledge-base-application/ 2015-08-02T23:55:00.000Z openKB is an open source Markdown based Knowledge base application (FAQ) built with Nodejs and ExpressJS. The application uses an embedded database (nedb) for easy installation without a full Database server. The application is designed to be easy to use and install and based around search rather than nested categories. Simply search for what you want and select from the results.

Demo: http://openkb.mrvautin.com

Installation

  1. Clone Repository: git clone https://github.com/mrvautin/openKB.git && cd openKB
  2. Install dependencies: npm install
  3. Start application: npm start
  4. Go to http://127.0.0.1:4444 in your browser

Features

  • Search: openKB is a search based Knowledgebase (FAQ) backed by Lunr.js indexing to create the best possible results on searches.
  • Backend: openKB uses the pure javascript nedb embedded database. This means no external databases need to be setup.
  • Design: openKB is meant to be simple flat design. With that said, openKB is very customisable by adding your CSS file to /public/stylesheets/ and adding a link in /views/layouts/layout.hbs you can add your own styling and graphics.
  • Responsive: openKB is built using Bootstrap allowing it to be responsive and work on all devices. The admin can be a little difficult editing Markdown on smaller screens.
  • Mermaid: openKB allows for Mermaid charts in articles.
  • Editor: openKB uses Markdown-it which is based off the CommonMark spec. This allows for the very best Markdown experience.
  • Image management: openKB allows for drag and drop of images into articles. The image is automatically uploaded to the server in the background. Google Chrome users can also paste images directly from the clipboard.

Screenshots

Homepage Editor Article view Article filtering Files

Admin

Visit: http://127.0.0.1:4444/login

A new user form will be shown where a user can be created.

Config

There are are a few configurations that can be made which are held in /routes/config.js. If any values have been changed the app will need to be restarted.

Running in production

Using PM2 seems to be the easiest and best option for running production websites. See the PM2 for more information or a short guide here: http://mrvautin.com/Running-Nodejs-applications-in-production-forever-vs-supervisord-vs-pm2.

]]>
<![CDATA[Running Nodejs applications in production forever vs supervisord vs pm2]]> https://mrvautin.com/running-nodejs-applications-in-production-forever-vs-supervisord-vs-pm2/ 2015-05-04T10:23:00.000Z There are a few aspects to think of when setting up a Nodejs application in production. I'm going to cover off Process management and Webservers.

Process management

One of the aspects you need to think about is keeping your app alive. When running PHP, when your app process crashes or server restarts the application WILL come back online automatically. With Nodejs, if the process crashes or the server restarts the process will NOT start itself. This is where a process manager comes into play, luckily there are a few good ones to choose from.

I will run through some of them and detail their pros and cons but to summarise: I like PM2 for easy setup of personal projects but I definitely recommend setting up systemd for a proper production environment.

supervisord (Link)

Pros

  • Mature software
  • Works on many different environments

Cons

  • Not Nodejs specific
  • Harder to setup
  • limited options

SETUP GUIDE

forever (Link)

Pros

  • Mature software (7.5k Github stars)
  • Works on many different environments
  • Easy to setup

Cons

  • I found it was unreliable recovering my Nodejs apps
  • Had issues with apps being auto started after a system reboot
  • Limited options (at the time of writing)

SETUP GUIDE

pm2: my pick for personal (Link)

Pros

  • Mature software (12.5k Github stars)
  • Can be used with an enterprise (paid) add-on service called Keymetrics
  • Works on many different environments
  • Super easy to setup
  • Many different options to scale apps in cluster mode etc
  • Command pm2 list give an easy to read table of all apps

Cons

  • A little difficult setting up as a non root user
  • None that I've found so far. Rock solid.

SETUP GUIDE

SystemD: my pick for proper applications (Link)

Pros

  • Mature software
  • Is the default process manager on most linux environments
  • Easy to setup
  • Rock solid and proven software
  • Can also run and mange other processes like Databases

Cons

  • None that I've found. Rock solid for production environments.

SETUP GUIDE

Webserver

I'm not even going to suggest others, I'm a Nginx man through and through and this in my opinion is the best and only choice in running a Nodejs webserver.

Here is a short guide on setting up Nginx for your Nodejs app:

Firstly need to install Nginx. Eg: Ubuntu: $ sudo apt-get install nginx

You the want to create the config for your application

$ sudo nano /etc/nginx/sites-available/myapp

The following is a very basic config to run your application. Basically it will listen for requests to mydomain.com on HTTP and forward those requests to our app (running with a process manager above) on port 4444. You will need to change that port to whatever port your app is running/listening on.

server {
    listen 80;
    server_name mydomain.com;

    location / {
        proxy_pass http://localhost:4444;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

You can then save this file and test your Nginx config with:

$ nginx -t

All going well, you should get something like this:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If not, check the error and adjust your config to resolve.

After a successful test, you now need to reload the new config into Nginx. You can either restart Nginx (will cause short downtime to all apps on server) or reload the config only. Best choice is to reload.

Reload: $ service nginx reload

Restart: $ service nginx restart

Thats it! You should be able to visit your app at: http:mydomain.com

]]>
<![CDATA[Adding Facebook Open Graph Metadata to your website]]> https://mrvautin.com/adding-facebook-open-graph-metadata-to-your-website/ 2014-12-31T21:44:00.000Z It is a good idea for the sake of SEO to ensure your website has all the necessary Meta tags. This ensures the search engines and other services can crawl or interact with your website in an efficient manner.

Some of the Meta tags you will want to set are called Open Graph Metadata. When someone shares a link to your website on Facebook, you are telling Facebook what title, description, image etc you want to show in a persons feed. This means when someone shares a status with a URL to your website, Facebook will look at the URL and pull all the Open Graph Metadata in order to show the title, description, and images etc.

All Metadata should be found within the <head> tag of your HTML document. The basic code of a Metadata is:

<meta property="property_value" content="content_value"/>

Where property_value is the actual Metadata we want to set and content_value is the actual value you would like.

A list of Open Graph properties can be found here: http://ogp.me/

The main ones you want to concentrate on are:

Property: og:url

The URL of the object being embedded into Facebook. This URL needs to be unique as it is used to collate Likes and shares on the object. The URL shouldn't include any session variables or GET parameters.

Example:

<meta property="og:url" content="http://mrvautin.com/Adding-Facebook-Open-Graph-Metadata-to-your-website"/>

Property: og:title

The title, headline or name of the object/article. This is shown when the URL/object is embedded into Facebook.

Example:

<meta property="og:title" content="Adding Facebook Open Graph Metadata to your website"/>

Property: og:description

A two sentence description/summary of the article/URL.

Example:

<meta property="og:description" content="A short two sentence description of the article."/>

Property: og:image

Here you can include a link to an image you want to show when a URL to your website is shared. Facebook recommends an image at least 600x315 pixels but recommends using a larger image and letting them scale it accordingly. They recommend using an image with a 1.91:1 aspect ratio to avoid cropping. Note: images cannot exceed 5MB in size.

Example:

<meta property="og:image" content="http://mrvautin.com/path_to_image.png"/>

Property: og:type

This is the type of URL being shared. Facebook outlines a long list of og:type options but for a general website/blog you will want to use article.

Example:

<meta property="og:type"   content="article" />

Full example

<html>
<head>
<meta property="og:url" content="http://mrvautin.com/Adding-Facebook-Open-Graph-Metadata-to-your-website"/>
<meta property="og:title" content="Adding Facebook Open Graph Metadata to your website"/>
<meta property="og:description" content="Adding Facebook Open Graph Metadata to your website"/>
<meta property="og:image" content="http://mrvautin.com/path_to_image.png"/>
<meta property="og:type" content="article" />
</head>
<body>
      Content
</body>
</html>
]]>
<![CDATA[Antlers]]> https://mrvautin.com/antlers/ 2014-12-29T21:58:00.000Z A light weight blogging platform built on Node.js and Express. The antlers platform is designed to have all the necessary features to get a blog up and running, with minimal fuss and beautiful clean design throughout. Best of all, it's free!

antlers allows for easy templating (themes) using the Handlebars templating engine and includes a few themes out of the box.

To get an idea of how your blog will look, take a look around! This blog is powered by antlers.

Installation

Using: npm

or

Manual:

  1. Install Node.js for your relevant server - There is a nice guide here: http://howtonode.org/how-to-install-nodejs
  2. Download antlers from here: https://github.com/mrvautin/antlers
  3. Extract the files and enter the directory via Command/Terminal
  4. Run npm install as an administrator (eg: sudo might be required)
  5. Then start the blog using node app.js
  6. You're done! You can then view the blog by opening http://localhost:3333 in a browser

Admin

You can enter the admin panel of your newly created blog by visiting the following URL in your browser: http://localhost:3333/admin. The default user login is: test@test.com and password is: password1. After logging in, you can change the email (username) and password using the "Users" menu.


Feel free to report any bugs on GitHub and give any feedback/suggestions by commenting below. ]]>
<![CDATA[fun_plug install Mediatomb on dns-320]]> https://mrvautin.com/fun_plug-install-mediatomb-on-dns-320/ 2013-10-06T22:00:00.000Z Mediatomb is apparently pre-installed.. It doesn't seem to be on my NAS.

The easiest way to install Mediatomb is via Optware.

To install Optware you simply need to run:

# wget http://wolf-u.li/u/233-O/ffp/start/optware.sh
# chmod a+x /ffp/start/optware.sh
# /ffp/start/optware.sh start

You can then install Mediatomb by running:

# /opt/bin/ipkg install mediatomb

Then copy the Mediatomb startup script to "start":

# cp /opt/etc/init.d/mediatomb /ffp/start/mediatomb.sh

Then set the correct permissions on the "mediatomb.sh file:

# chmod a+x /ffp/start/mediatomb.sh

You need to change one of the Mediatomb configs to allow autostart:

# vi /opt/etc/default/mediatomb

Ensure MT_ENABLE=true

You can now start Mediatomb by:

# sh /ffp/start/mediatomb.sh start

You can now browse Mediatomb via the Web Interface:

http://localhost:4915
]]>
<![CDATA[Adjust time on stereo clock for 2006 to 2012 Toyota Corolla]]> https://mrvautin.com/adjust-stereo-clock-on-2006-to-2012-toyota-corolla/ 2013-10-06T10:02:00.000Z Adjusting the clock on the 2006 to 2011 Corolla is not documented anywhere in the manual. I stumbled across how to do it by pushing all the buttons. The process to adjust is not logical and so I figured I would document it for someone else.

My stereo looks like this:

To adjust the time you need to hold the 'AM' button and at the same time press the number '1' button to adjust the hour or the number '2' button to adjust the minute.

I hope this helps someone.

]]>
<![CDATA[St George Bank WooCommerce Plugin for IPG Hosted Payment Page (HPP)]]> https://mrvautin.com/st-george-bank-woocommerce-plugin-for-ipg-hosted-payment-page--hpp/ 2013-10-02T04:07:00.000Z A St.George Bank IPG Hosted Payment Page (HPP) plugin for WooCommerce. This plugin will allow you to accept payments via your St.George Bank online Merchant Account using your WooCommerce shopping cart

Download the module here.

Here are the steps to install the module:

  1. Extract the contents of stgeorge-woocommerce-1.0.1.zip to: \wp-content\plugins\
  2. Login to WordPress and install the St.George Bank WooCommerce Plugin via the Plugins Menu
  3. Go to the WooCommerce > Settings via the left menu
  4. Click the Checkout tab
  5. Click on St.George Bank link at the top of the page.
  6. Click Enable St.George Bank checkbox
  7. Fill in the desired Title and Description which is shown when the user checks out in WooCommerce
  8. Copy the Response URL and past this link on the St.George Merchant Administration Console
  9. Enter the Gateway URL which is obtained via the St.George Merchant Administration Console > Payment Page Options > URL
  10. Save the changes and test a payment via your WooCommerce site.
]]>
<![CDATA[Convert HTML or a Website to an image file (C#)]]> https://mrvautin.com/convert-html-or-a-website-to-an-image-file-c/ 2013-03-08T09:34:00.000Z I was looking around for hours looking for the ability to create an image from some HTML I'd scraped from a Website. Note: This solution also works for Websites which are publicly accessible to don't require authentication.

It essentially dynamically sets up a WebBrowser control, loads a URL (waits for it to be completely loaded) and takes an image of the rendered HTML. The solution below creates an image which is the full size of the rendered HTML. You can add padding to the image by adding pixels to the wb.Width and wb.Height values.

It's quite simple really. Here is the function to render the HTML:

    public Bitmap GenerateScreenshot(string url)
    {
        // Load the webpage into a WebBrowser control
        WebBrowser wb = new WebBrowser();
        wb.ScrollBarsEnabled = false;
        wb.ScriptErrorsSuppressed = true;
        wb.Navigate(url);

        // waits for the page to be completely loaded
        while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }

        // Take Screenshot of the web pages full width + some padding
        wb.Width = wb.Document.Body.ScrollRectangle.Height;
        // Take Screenshot of the web pages full height
        wb.Height = wb.Document.Body.ScrollRectangle.Height;

        // Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
        Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
        wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, wb.Width, wb.Height));
        wb.Dispose();

        return bitmap;
    }

You can call it by:

    Bitmap thumbnail = GenerateScreenshot("www.google.com");
    thumbnail.Save("C:\image file.bmp", ImageFormat.Bmp);

Notes: You can also use C:\test.html rather than www.google.com and you can change the output file by adjusting the ImageFormat value.

That's it.

]]>