Program & Design Tips, tricks, tutorials, and tools on programming & web design

29Oct/130

Installing node-canvas on Windows

There's an article here that describes the process, but it's a bit vague in some areas and didn't work for me.

If you're on 64-bit Windows, you will need the 64-bit version of GTK which comes bundled with Cairo if you get the all-in-one package. Somewhere under the mile of text on this page you should find a link to it; here's a direct link for version 2.22.

It's a zip. Extract it to c:/GTK. I don't even what to consider what's involved making it work from a different location.

You also need node-gyp. Install it via

npm install -g node-gyp

Once you've got all the dependencies you can attempt to install node-canvas. "CD" into your project directory and then run

npm install canvas --msvs_version=2012

Adjust the version number for whatever version of Visual Studio you have. The Wiki says to use VC++ 2010 Express which is also a bitch to find on Microsoft's website as they push you towards 2013. Here's a direct link which may or not work.

Even after installing VS2010 though, npm/gyp wouldn't pick it up automatically, which is why I had to specify the version manually. Even then 2010 didn't work, but 2012 did, so, whatever.

If you get some linker errors, you probably have an old version of Cairo.

If you get something about cairo-features, it's probably the same deal. Those can be fixed by opening the .sln in Visual Studio and updating the include dirs to include C:/GTK/includes/cairo, but then you'll be left with a new error, and they'll probably never end, so just try different versions of the GTK bundle until you find one that works. Maybe try 32-bit if the 64-bit one doesn't work for you (32 didn't work for me).

Filed under: C++, node.js No Comments
4Sep/130

Selenium, PhantomJS, Node, Screenshots and Sizzle

Without going into too much detail, I just wanted to post a snippet of how to get all these technologies playing nicely together:

var webdriver = require('selenium-webdriver');
var fs = require('fs');

var driver = new webdriver.Builder()
    .withCapabilities(webdriver.Capabilities.phantomjs())
    .build();

webdriver.WebDriver.prototype.saveScreenshot = function(filename) {
    return driver.takeScreenshot().then(function(data) {
        fs.writeFile(filename, data.replace(/^data:image\/png;base64,/,''), 'base64', function(err) {
            if(err) throw err;
        });
    })
};

webdriver.By.sizzle = function(selector) {
    driver.executeScript("return typeof Sizzle==='undefined'").then(function(noSizzle) {
        if(noSizzle) driver.executeScript(fs.readFileSync('sizzle.min.js', {encoding: 'utf8'}));
    });
    return new webdriver.By.js("return Sizzle('"+selector.replace(/"/g,'\\"')+"')[0]");
};

driver.get('http://google.com/');
driver.findElement({sizzle:'input[name=q]'}).sendKeys('cheese\n');
driver.saveScreenshot('cheese.png');
driver.quit();

Node that you will need to start the Selenium server before you can run this example. Do so via:

java -jar selenium-server-standalone-2.35.0.jar

 

Filed under: JavaScript No Comments
22Jul/130

Two-way implicit casting

I'm presently writing a framework that wraps a C API using interop. Many of the classes/structs defined in the C library already exist in .NET, but I have to re-implement them anyway so that I can interface with the library. People accustomed to the .NET classes won't be fond of this because they already have a set of classes that work well, and the new ones won't work with existing .NET methods. There is a simple solution to this, however! Implicit casting!

Here's a sample of how I made my Color struct compatible with the one defined in System.Drawing.Color:

[StructLayout(LayoutKind.Sequential)]
public struct Color
{
    public byte R, G, B, A;

    public static implicit operator System.Drawing.Color(Color c)
    {
        return System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B);
    }

    public static implicit operator Color(System.Drawing.Color c)
    {
        return new Color {R = c.R, G = c.G, B = c.B, A = c.A};
    }
}

Note that System.Drawing.Color uses ints instead of bytes for its colors, and they aren't necessarily stored in the same memory location, so I couldn't use that class directly. You can, however, convert back and forth between the two classes without any loss of data, so this is a perfect case for implicit casting. If the two classes aren't convertible without some data changing, you should use explicit casting instead, or perhaps a static factory method.

I was curious, however, to know what would happen if an implicit casting method was defined in both classes. Here's an example:

class A
{
    public static implicit operator B(A a)
    {
        Console.WriteLine("A::B");
        return new B();
    }
}

class B
{
    public static implicit operator B(A a)
    {
        Console.WriteLine("B::B");
        return new B();
    }
}

class Program
{
    public static void F(B b)
    {
        Console.WriteLine("F()");
    }

    static void Main(string[] args)
    {
        var a = new A();
        F(a);
        Console.ReadLine();
    }
}

How does it know which method to call? The answer: it doesn't! This actually gives the following error:

Ambiguous user defined conversions 'ImplicitTest.A.implicit operator ImplicitTest.B(ImplicitTest.A)' and 'ImplicitTest.B.implicit operator ImplicitTest.B(ImplicitTest.A)' when converting from 'ImplicitTest.A' to 'ImplicitTest.B'

There is a way you can still utilize one of conversion methods, but it isn't pretty. Here's the solution work-around:

static void Main(string[] args)
{
    var method = typeof (A).GetMethod("op_Implicit", new[] {typeof (A)});
    var converter = (Func<A, B>) Delegate.CreateDelegate(typeof (Func<A, B>), method);
    var a = new A();
    F(converter.Invoke(a));
    Console.ReadLine();
}

[credit]

The real solution would be to just delete one of the methods, if you can!

Filed under: C# No Comments
2Apr/132

Compile all Jade files to a single client-side JavaScript file

Jade is "a high performance template engine heavily influenced by Haml and implemented with JavaScript for node".

One of it's nice features is that it lets you compile your Jade templates into JavaScript functions which can be ran client-side. This is particularly useful when you want to pass JSON data back from an AJAX call and render it; it keeps you have from having to pass HTML "over the wire" or from writing complex JavaScript to rebuild your DOM elements. It's also super fast.

After installing Jade, you can compile a single template via the command-line by running jade -c template.jade. This will generate a *.js file that looks like this:

function anonymous(locals, attrs, escape, rethrow, merge) {
    ...
}

Which is great, except that it's just about unusable as-is. If you try including that to your page, you now have access to a single function called "anonymous" -- not very helpful. The problem gets worse if you want to have access to more than one template.

Wouldn't it be nicer if all of your templates got compiled to a single object with a sensible name, which you could use the access all your template functions? That's why I wrote a script to compile all your Jade files into a single .js file that looks like this:

var Templates = {
"login":
  function anonymous(locals, attrs, escape, rethrow, merge) {
      ..
  },
"change_password":
  function anonymous(locals, attrs, escape, rethrow, merge) {
      ..
  }
};

Now you just need to include that Jade runtime plus this file that got generated via:

<script type="text/javascript" src="/js/jade/runtime.js"></script>
<script type="text/javascript" src="/js/templates.js"></script>

You can find runtime.js inside node_modules/jade after you install it.

Here's the script:

var Jade = require('jade');
var FileSystem = require('fs');
var Path = require('path');
var _ = require('underscore');

var outName = 'public/js/templates.js';
var viewsDir = 'views';

files = FileSystem.readdirSync(viewsDir);
var templates = {};
files.forEach(function(filename) {
    if(/\.jade$/.test(filename)) {
        var name = Path.basename(filename, '.jade');
        var path = Path.join(viewsDir, filename);
        console.log('compiling', path);
        var fileContents = FileSystem.readFileSync(path, {encoding: 'utf8'});
        templates[name] = Jade.compile(fileContents, {
            debug: false,
            compileDebug: true,
            filename: path,
            client: true
        });
    }
});
console.log('writing', outName);

var properties = [];
_.each(templates, function(value, key) {
    properties.push(JSON.stringify(key) + ':\n  ' + value.toString());
});
var sourceCode = 'var Templates = {\n' + properties.join(',\n\n') + '\n};';

FileSystem.writeFile(outName, sourceCode);

I called mine "compile_jade.js". You run it via "node compile_jade.js". You will probably need to adjust your paths as necessary (see "outName" and "viewsDir" near the top). I will probably expand on this script in the future, but this should be enough to get you started with client-side Jade!

If you're using PhpStorm or WebStorm like me, you can set up a File Watcher to watch your Jade files have it automatically re-run this script whenever you edit one of them:

jade-compiler

Filed under: JavaScript, node.js, PHP 2 Comments
10Feb/130

Meteor, Blade + Windows 8

Introductions

Meteor is a hot new Node-based web development framework.

Blade is a templating language based on Jade, which is a bit similar to Haml.

Windows 8 is an operating system that no one but me likes.

Installation

I'm assuming you're already up and running with Node.

Meteor isn't officially supported on Windows yet, so you have to install it a bit differently than suggested on their docs. Fortunately, someone has created an .msi installer for us. Run it.

If you haven't done so,

npm install -g blade

. If "npm" isn't a registered command, check your Start Screen for "Node.js Command Prompt" and use that instead of that standard

cmd.exe

. It should have all the paths set up correctly for you.

Now find your

npm/node_modules/blade

and

Meteor/packages

folders. Mine are located at

C:\Users\Mark\AppData\Roaming\npm\node_modules\blade

and

C:\Program Files (x86)\Meteor\packages

respectively.

Inside the

node_modules/blade

folder there should be another folder called "meteor". Copy and paste this in-place to make a duplicate, then rename your copy to "blade". We want to rename it before we move it because there is a folder in the meteor packages called "meteor" already. Now cut-and-paste your new folder into Meteor/packages.

Now go into

npm/node_modules/blade/lib

and copy all the files inside there into your newly created

Meteor/packages/blade

.

Now edit

Meteor/packages/blade/package.js

and change this line:


blade = require('../../packages/blade/node_modules/blade');

To point to the proper node module, e.g.,


blade = require('C:/Users/Mark/AppData/Roaming/npm/node_modules/blade');

That's it.

Adding blade to your Meteor project

Just

cd

into your project folder and

meteor add blade

.

Usage is explained on the official Blade wiki.

(Sorry for the terrible formatting, those are supposed to be inline code blocks... I hate WordPress)

Filed under: Uncategorized No Comments
6Dec/120

Find devices on your network

I have a NAS device on my network which has a web interface, but I didn't know it's IP. Running this simple command from cmd.exe gave me a handful of IPs to try which lead me to finding it very quickly:

arp -a

The results should look something like this:

C:\Users\Mark>arp -a

Interface: 192.168.0.12 --- 0xa
  Internet Address      Physical Address      Type
  192.168.0.1           78-cd-8e-7a-b5-f7     dynamic
  192.168.0.15          00-01-55-31-0c-29     dynamic
  192.168.0.17          1c-4b-d6-cf-e3-2d     dynamic
  192.168.0.255         ff-ff-ff-ff-ff-ff     static
  224.0.0.2             01-00-5e-00-00-02     static
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.252           01-00-5e-00-00-fc     static
  225.0.0.1             01-00-5e-00-00-01     static
  230.0.0.3             01-00-5e-00-00-03     static
  239.255.255.250       01-00-5e-7f-ff-fa     static
  255.255.255.255       ff-ff-ff-ff-ff-ff     static

Interface: 192.168.56.1 --- 0xf
  Internet Address      Physical Address      Type
  192.168.56.255        ff-ff-ff-ff-ff-ff     static
  224.0.0.2             01-00-5e-00-00-02     static
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.252           01-00-5e-00-00-fc     static
  225.0.0.1             01-00-5e-00-00-01     static
  239.255.255.250       01-00-5e-7f-ff-fa     static

It was one of the dynamic IPs; I'm not sure if that's always the case.

Filed under: Windows No Comments
1Dec/120

WAMP: Apache won’t start/icon stays green

I have a non-standard installation of WAMP. I've installed it to my

Z:/wamp

. Recently it stopped working. All the suggestions I found on the web told me to check port 80, or check the

apache_error.log

but that didn't help. I've already moved apache to port 81, and nothing was written to the log.

The solution was to open up a command prompt (

cmd.exe

),

cd

into the apache bin directory (

Z:\wamp\bin\apache\apache2.2.22\bin

for me), and run

httpd.exe

manually. As soon as I did that, it told me:

Syntax error on line 22 of Z:/wamp/bin/apache/apache2.2.22/conf/extra/httpd-auto index.conf:

&lt;Directory "c:/Apache2/icons"&gt;

path is invalid.

Which was an easy enough fix; just point it to

Z:/wamp\bin/apache/apache2.2.22/icons

. Bam! Works again. Just close out of the console and restart WAMP via the icon.

tl;dr If your apache won't start, and the error log isn't giving you any information, start it manually and check there if you get any error messages.

Edit: I know this blog post is formatted stupidly, I have to figure out what's going on with WordPress.

Filed under: Web No Comments
25Nov/120

PHP: Generate a unique filename for a given directory

This function will generate a filename unique to specified directory. If you're using it to create filenames for uploaded images, for example, you can give it a path to your upload folder an extension such as 'jpg'.

It will generate the filename using the characters specified in the function, you can modify it as desired. I chose to omit uppercase letters in case you are running this on a Windows system (case insensitive).

/**
 * Converts large hexidecimal numbers into decimal strings.
 *
 * @param string $hex Hexidecimal number
 * @return string Decimal number
 * @see http://stackoverflow.com/a/1273535/65387
 */

function bchexdec($hex)
{
    $dec = 0;
    $len = strlen($hex);
    for ($i = 1; $i <= $len; $i++) {
        $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
    }
    return $dec;
}

function base_encode($val, $base=62, $chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
    if(!$base) $base = strlen($chars);
    $str = '';
    do {
        $m = bcmod($val, $base);
        $str = $chars[$m] . $str;
        $val = bcdiv(bcsub($val, $m), $base);
    } while(bccomp($val,0)>0);
    return $str;
}

function unique_filename($dir, $ext='') {
    do {
        $filename = $dir.'/'.base_encode(bchexdec(uniqid()), null, '0123456789abcdefghijklmnopqrstuvwxyz_-');
        if($ext) $filename .= '.'.$ext;
    }while(file_exists($filename));
    return $filename;
}
Filed under: PHP No Comments
10Sep/122

High quality image resize (C#)

You can use this class to resize images proportionally (maintaining aspect ratio), or to resize an image to an exact size and crop off excess (useful for making nice thumbnails):

public static class ImageExt
{
    public static Image Resize(this Image img, int srcX, int srcY, int srcWidth, int srcHeight, int dstWidth, int dstHeight)
    {
        var bmp = new Bitmap(dstWidth, dstHeight);
        using (var graphics = Graphics.FromImage(bmp))
        {
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                var destRect = new Rectangle(0, 0, dstWidth, dstHeight);
                graphics.DrawImage(img, destRect, srcX, srcY, srcWidth, srcHeight, GraphicsUnit.Pixel, wrapMode);
            }
        }
        return bmp;
    }

    public static Image ResizeProportional(this Image img, int width, int height, bool enlarge=false)
    {
        double ratio = Math.Max(img.Width / (double)width, img.Height / (double)height);
        if (ratio < 1 && !enlarge) return img;
        return img.Resize(0, 0, img.Width, img.Height, M2.Round(img.Width / ratio), M2.Round(img.Height / ratio));
    }

    public static Image ResizeCropExcess(this Image img, int dstWidth, int dstHeight)
    {
        double srcRatio = img.Width / (double)img.Height;
        double dstRatio = dstWidth / (double)dstHeight;
        int srcX, srcY, cropWidth, cropHeight;

        if (srcRatio < dstRatio) // trim top and bottom
        {
            cropHeight = dstHeight * img.Width / dstWidth;
            srcY = (img.Height - cropHeight) / 2;
            cropWidth = img.Width;
            srcX = 0;
        }
        else // trim left and right
        {
            cropWidth = dstWidth * img.Height / dstHeight;
            srcX = (img.Width - cropWidth) / 2;
            cropHeight = img.Height;
            srcY = 0;
        }

        return Resize(img, srcX, srcY, cropWidth, cropHeight, dstWidth, dstHeight);
    }
}
Filed under: C# 2 Comments
10Sep/120

Convert decimal numbers to any base (C#)

You can use this little function to convert a decimal to any base. I use it for compacting large numbers.

public static class BaseConverter
{
    public static string Encode(BigInteger value, int @base=0, string chars="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
    {
        if (@base <= 0) @base = chars.Length;
        var sb = new StringBuilder();
        do
        {
            int m = (int)(value % @base);
            sb.Insert(0, chars[m]);
            value = (value - m) / @base;
        } while (value > 0);
        return sb.ToString();
    }
}

Or you can use it to make a nice GUID:

private static BigInteger UnsignedBigInt(byte[] bytes)
{
    if ((bytes[bytes.Length - 1] & 0x80) != 0) Array.Resize(ref bytes, bytes.Length + 1);
    return new BigInteger(bytes);
}

private static string GetUniqueFileName(string extension)
{
    return BaseConverter.Encode(UnsignedBigInt(Guid.NewGuid().ToByteArray()), 0, "0123456789abcdefghijklmnopqrstuvwxyz_-") + extension;
}
Filed under: C# No Comments