Simple Node based Http Put simulator

It’s great what you can accomplish in a few lines of code. The Node based source code below uses express to create a mini view-based web server along with a mock Http Put file upload destination.


/**
* Module dependencies.
*/

var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path');

var app = express();

app.configure(function(){
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});

app.put('/upload/:fileUpload', function(req, res, next){
console.log('uploading!');
res.send('OK', { 'Content-Type': 'text/plain' }, 200);
});

app.configure('development', function(){
app.use(express.errorHandler());
});

app.get('/', routes.index);

http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});

Using WebStorm’s Node/Express template, I only added 4 lines:

app.put('/upload/:fileUpload', function(req, res, next){
console.log('uploading!');
res.send('OK', { 'Content-Type': 'text/plain' }, 200);
});

These 4 lines added a new route/path for uploading a file in the pattern of /upload/ {fileName}.

The response was “OK.”

I’d tried this same thing using ASP.NET MVC 4 (with Razor), but was stumped by the error when trying to use HttpPut on an Action in the controller.

I was using this end-point as a mock-upload destination for my SmugMug application, SnugUp. I wanted to eliminate the uploading process as it’s time consuming and messes up my SmugMug galleries! Smile

The C# code is simple as it uses HttpWebRequest:

HttpWebRequest uploadRequest = (HttpWebRequest)WebRequest.Create(ApplicationConstants.UploadUrl + "photo.jpg");

uploadRequest.Timeout = (int)10080 * 60 * 1000; // 7 days
uploadRequest.Method = "PUT";
uploadRequest.UserAgent = ApplicationConstants.UserAgent;
uploadRequest.ContentLength = fi.Length;
uploadRequest.KeepAlive = true;

(SmugMug grabs the file name from a custom Http Header, so, the put URL is always “photo.jpg”.)

Do your support organization a favor: create better error messages!

From Adobe Illustrator CS6:

SNAGHTML11cdf257

While it’s possible that Adobe has a codified error database for “CANT” … it would seem more likely that someone will need to search through source code to find out what operation cannot complete.

(To fix the above problem, I reset the settings for Illustrator by running as admin and holding down CTRL+SHIFT+ALT. Illustrator starts in a weird mostly not working state, but after shutting down that instance and restarting normally, the error went away).

This one is slightly better:

SNAGHTML11cffc55

Although, in a clean install of CS6, I don’t know why I’m getting this error.

Photoshop upon first run was giving me an error message:

Could not open a scratch file because the file is locked, you do not have necessary access permissions, or another program is using the file. Use the "Properties" command in the Windows Explorer to unlock the file.

You’ll note that it mentions a file being locked, but no clear action to take because of this issue.

Here’s what apparently is one cause of this error:

A non-default installation of Windows (or Macs), where your temporary and user folders are not on the installation disk for Photoshop. In my case, I have 3 disks in my computer:

  1. SSD  < Apps installed
  2. 600GB HD  < Users, temporary
  3. 600GB HD < Virtual Machines, backups, etc.

Photoshop (and Illustrator as well actually) try to create the scratch folder on the primary drive, even when they don’t have permission to do so. I changed the setting by:

  1. Run Photoshop as Administrator
  2. Immediately hold CTRL+ALT+SHIFT.
  3. Photoshop will ask if the Settings should be reset. Answer OK.
  4. Go to Edit > Preferences > Performance
  5. Make changes to Scratch Disks:
    SNAGHTML11d999cc[4]
  6. Click OK and Exit Photoshop
  7. Restart normally.

A bit of reflow, using TweenJS

Inspired by some modern applications (especially the “Metro” look and feel), I wanted to put together an animated tile reflow script for an HTML page I was creating.

As the size of the page changes, the tiles move into their new positions.

SNAGHTML113b633f[4]

You can try it here, if you’re using a modern browser (IE9+, Chrome, FF, Safari, etc.).

Dependencies:

  1. TweenJS
  2. EaselJS (for the ticker used in TweenJS)
  3. CSSPlugin (an add on to the the TweenJS library)
  4. jQuery (1.7.2)

Relayouts are queued (as to prevent multiple from running).

Only boxes that will be visible to the end user (either animating to the screen or off the screen) are animated. It does not animate elements that do not start or end in the current viewport including boxes that would animate “through” the current viewport. I considered the latter to not add anything to the overall experience and just uses more CPU to perform the animations, so I intentionally left it out.

In the layout loop, the code verifies that the animation needs to run:

// here's the final destination
pos = { left: Math.round(x), top: Math.round(y) };

// check old and new positions, if either are in the viewport, we'll animate
if (isScrolledIntoView(pos.top + parentOfBoxesOffsetTop, boxH) || isScrolledIntoView(box.y + parentOfBoxesOffsetTop, boxH)) {
    Tween.get(box.e).to(pos, 500 + 500 * Math.random(), 
        Ease.quadInOut).call(function () {
            --layoutPending;
            if (!layoutPending && queuedLayout) { queueLayout(); }
    });
} else {

If it needs to animate, the code uses the static Tween method “get” to start an animation on the current element.

  1. Tween.get(box.e) creates a new instance of the Tween class (initialized with the element to tween).
  2. Using that Tween instance, the CSS attributes (thanks to the handy CSSPlugin), for left and top are animated for at least 500ms and up to a full second. The easing function I chose is quadInOut. Tip: Here’s a great way to visualize easing options using TweenJS.
  3. Finally, when the animation completes, an anonymous function is called which decrements the number of pending animations and if there are no remaining elements to animate, and there’s something queued, another cycle is started.

All the code used by the demo is in default.html.

Colors of the boxes were set using hsl (only available in modern browsers):

box.style.backgroundColor = "hsl(" + c + ", 100%, 50%)";

Where “c” is:

c = (i / boxes * 360).toFixed(1);

Adding an External Tool for Compiling LESS files in WebStorm (on Windows)

Interested in converting/compiling LESS files into their CSS counterparts?

Here are the steps (from version 4 of WebStorm from JetBrains).

1. Install Node JS

2. Install the node package (using npm) for less (remember where you install this as you’ll need the path later):

    npm install less

3. In WebStorm, File > Settings, then under the IDE Settings heading, select External Tools.

4. Click on the + icon to add a new tool:

image

5. You’ll see a dialog very much like this:

SNAGHTMLcd7f5f5

6. Fill it out like this (substitute whatever you’d like of course):

SNAGHTMLceae4a7

I chose not to have the console window open every time the compilation occurs.

The only things you’ll need to change is the path to the file lessc. That file is actually JavaScript file (minus the extension). So, replace the first quoted parameter in “Parameters” above with the location that you installed the package for less in.

As it’s a JavaScript file you need to be executed, the “Program” is set to the node executable. Provide the full path (when I didn’t, it sometimes wouldn’t work and would complain that a path didn’t exist).

"###YOUR PATH TO LESSC###\lessc" $FilePath$ "$FileDir$\$FileNameWithoutExtension$.css"

I tried using the Working Directory option and it also worked inconsistently with Node. So, I used the options you see above and it seemed to work more consistently.

7. I also added a shortcut so I could execute it on demand:

SNAGHTMLcdbd3f4

SNAGHTMLcdc51ca

I picked Ctrl+Alt+L, as it was memorable (and available!).

While this is not using a file watcher technique (you could do that if you’d like instead), it works well enough for my workflow.

SVG Setting Text Content Dynamically

Continuing on a theme of animating SVG, I’ve added a label in the center of the animation which contains the current angle of the ever-rotating marker (in fact in a centered horizontally and vertically SVG text node).

(Click image below to try it.)

image

At the bottom of the file from the previous post, I’ve added the following:

    <text id="currentValueAsText" x="300" y="300" 
        style="text-anchor: middle;alignment-baseline:middle" 
        fill="#FFFFFF" font-family="'Arial'" font-size="96" opacity=".6">0</text>

It’s a new text node. It’s set to centered both horizontally and vertically (using the text-anchor and alignment-baseline style properties respectively) at 300,300.

Setting the content is simple as well:

(function () {
    window.onload = loaded;
    function loaded() {
        var colorTemp = document.getElementById("color-temp");
        var reading = document.getElementById('current-reading');
        var currentVal = document.getElementById("currentValueAsText");
        var currentAngle = 0;
        var fill;

        var direction = 1;
        setInterval(function () {
            currentAngle += direction;
            if (currentAngle >= 120 || currentAngle <= -120) {
                direction *= -1;
            } else if (currentAngle === 0) {
                fill = direction === 1 ? "#BE1E2D" : "#10A2DC";
                colorTemp.setAttribute("fill", fill);
            }
            // adjust the opacity
            colorTemp.setAttribute("opacity", Math.abs(currentAngle) / 120.0);
            reading.setAttribute("transform", "rotate(" + currentAngle + ")");
            currentValueAsText.textContent = currentAngle.toString();

        }, 25);
    }
})();

Use the textContent property of the SVG text node to set the text.

Done. Smile