Azure Node.js Visual Studio Publishing Error

Been doing a lot of Node.js of late as well as publishing to Azure. There are a couple kinks that I’ll share.

Issues Publishing Node Website to Azure From Visual Studio

First and foremost by far the easiest way to publish to Azure is probably WebMatrix 3. It’s rather idiot proof. Unfortunately its not nearly as intuitive to develop in as Visual Studio is. At least I don’t like it. If you’re in VS a lot you’ll probably feel the same. However with that said WebMatrix does a few things for you automatically. It also seems to ignore a glarring issue you’ll find in VS and that is the length of file paths. This is due to the structure of nesting in the node_modules directory for all your modules. Mongoose for one has an example folder that you’ll need to hide or exclude. If you open the folder as a web site you won’t have the exclude like you normally would in a VS project, hence the easiest way I found was to mark this folder as hidden directly from Explorer. For me this is no big deal as I always have hidden folders shown. I’m always monkeying with “C:\sers\profile\AppData” folder for one reason or another among others so I always have hidden files/folders set as visible.

Mark Folder as Hidden

Simply open the parent directory and right click on the folder you want to hide, select hidden

Once this is completed Visual Studio will ignore this directory when publishing

hidden folder

Mark Folder as Hidden

Advertisements

Apple TV 3 vs Roku 2 vs Popcorn Hour Streaming Media Servers

Its pretty simple really I’d go Roku 2. For a couple reasons. First the Apple TV 3 hasn’t yet been jailbroken. There are lots of groups claiming a release but none have come through to my knowledge. I suspect it might be some time. To find exploits takes time and often ipad, iphone have higher priority due to saturation in the market. If you’re a non geek type this may not matter to you however it may without you realizing it.

Here is what I mean. One of the things that is a bit frustrating with ATV is the supported codecs. What’s a codec? Well I won’t go into detail but in short its a way for the device to decode or understand the content. Movies, music and the like all have codecs they need to be played. ATV is limited in this area compared to other devices. The other gotcha with ATV is that you need iTunes to sync to it. I’m not a fan of iTunes in fact if that interface went away and it was more seamless I’d be rather pleased with ATV.

Moving on and I want to be clear, there is NOTHING wrong with AppleTV. However if you want any flexibility its not the device for you. A couple other options are the Roku 2 and the Popcorn Hour devices. Both are very good at what they do. I own both. The Popcorn Hour is probably the most universal of them all in that it will play anything. With that said it is not for the faint of heart in that its more of a geek device that you can tinker with, write code for etc.

One of the main reasons I like the Roku 2 is its form factor of course and that it supports Plex right out of the box. Plex folks is a must have moving forward as TV and the Internet continue to merge. For Plex alone I’d choose Roku 2 over AppleTV. In fact it is one of the major contributing factors to why ATV 2’s are so popular right now (they can be jailbroken and you can add Plex where ATV 3 you can’t…yet that is).

Winner: Roku 2 XS

Zepto.js Rakefile

This is a Rakefile to substitute the default in the Zepto.js mobile framework.

Note the extension on the download file is .doc. This is because WordPress limits the file types that can uploaded. Be sure to rename it with no extension.

Download Rakefile Here

Zepto.js Home Page

Zepto Source on GitHub

Deleted Twitter Post Still Visible to Followers Why?

How Does the Twitter API Work

Twitter is a REST based API. Which means various third parties have built applications that hit the Twitter servers via a URL. This is in the form of an HTTP Request. Imagine if every time a third party app wanted to update their information they requested everything in your timeline. That would bog down the Twitter servers and two it would mean a clumsy user interface. Hence there are some limits as to the requests you can make to Twitter including the number of requests. The point is there are limits. So essentially what that means is that if a third party creates a UI or interface such as HootSuite or TweetDeck they can’t just make unlimited requests constantly to update the application.

Why Is That Important

Bottom-line most third party apps use some sort of caching mechanism so as to limit heavy payloads of data that they’ve already requested. Which means you guessed it the third party app could actually have a cached view of your timeline. Which in turn means if you deleted something they may still be able to view it depending on how the third party application functions. Essentially because Twitter allows these third party apps to parse the data once they do Twitter has no control whatsoever with what is done with that data once downloaded.

What Can I Do

Really not much other than recommend trust worthy apps to your followers. If they are using some application that hasn’t accounted for this scenario they will see the deleted tweet if for anything a period of time after you delete it. So think before you tweet. Otherwise you’ll be like David Spade in Black Sheep as he describe the fly trying not hit the windshield. “No no not gonna, can’t stop, splat”.

Kendo UI MVC Grid Extention

Kendo UI MVC Grid Extention

Didn’t like how the MVC Destroy() method worked so I wired up my own. This is a simple function to help you get the row’s data when you fire off the custom event.

Essential “e” is the event that is fired from the custom command event in your Kendo UI grid. It takes the target and turns it into a JQuery object. It grabs the uid of the row and then matches it with the uid in the data. Its very quick and works nicely. Sure there are other ways to skin this cat but this seemed to be very smooth. Seems to me there should be a JQuery data object for the row but all I saw was the uid hence this function below. Anyway thought I’d share.

   function getRowData(e) {
        var target, grid, uid, row, data;
        target = $(e.target);
        uid = target.parent().parent().data().uid;      
        grid = $('#Grid').data('kendoGrid');        
        row = grid._data;
        for (var i = 0; i < row.length; i++) {
            if (row[i].uid == uid) {
                data = row[i];
            }
        }
        return data;
    }

What you’ll get is your data for the row as an object so you can simple do:
// note below assumes you have a custom column command that on .click() is attached to the “deleteRow” function “e” is the event that the click event will pass in.

function deleteRow(e){
	var data = getRowData(e);
	var name = data.full_name // where full_name is a column in your grid. 
	alert('Are you sure you want to delete ' + name);
	// TODO: wire up your delete event passing in an id or something
	$.post('/your/path', {}, function (result) {
		if(result.deleted){
			// load your UI or whatever
		}
	});
} 

The getRowData function you can copy/paste but the above “deleteRow” is just an example you’ll need to modify to your needs.

KnockoutJs and Ifragistics JQuery IgGrid

The Problem

Ran into a problem with the extensions shipped from Infragistics for use with the IgGrid and KnockoutJs. JQuery kept breaking complaining about “object not a function”.

After doing some digging and messing around I realized there was a problem with the shipped extension. I noticed a demo on Infragistics site that referred to a CDN version. So I grabbed it and it worked just fine. No more “object not a function” errors in my console using Google Chrome. So if anyone else runs into this issue just grab the download below and overwrite the shipped file and all should be well.

Knockout and the support from Infragistics is relatively new so I’m sure there will be updates in the meantime this works. as of the date of this article. If you are checking this a month or two from now they’ve probably resolved the problem.

Download Update

infragistics.ui.grid.knockout-extensions.js

Blurred Coupon Code using JQuery

Securing a Coupon Code

Got asked to create a way to blur out a coupon code until a link is clicked today. Stop now if you’re looking for some eye popping, earth shattering effect because it’s not here..LOL. However it is kind of cool to see how it works, or at least one way you can do it.

The Concept

Blurred out Coupon Code

First let me say that I think if you really want to secure it up you may want to make a quick ajax call or something. Essentially never having the coupon code touch the DOM until you need it. That might be overkill and since I was adding this as kind of a widget for someone, not having direct access to the site, this worked well.

Secured Until Clicked Coupon Code

First thing I did was create a couple buttons. Nothing special they could even be just a link. The next they I did is create an image that had a code then I blurred the text using Photoshop. So basically our blurred out or secured code is the same each time but to the user it just looks like an unreadable code. So here we go. Let’s start with just a touch of css.


.blur { background-image: url('your_fake_blurred_coupon_code.jpg'); }

I’m assuming you understand what JQuery is and how to add a reference to the library either local or CDN. Now that we have that out of the way lets look at some markup. Below we have an anchor wrapped around an image. Again you could do without the image if you wanted. Take note of the two classes here that we’ll be using with our JQuery. That being “getcode” and “code”

Secure/Blurred Html Markup

Next lets look at the actual JQuery. When the page is ready JQuery iterates of “.code” essentially storing the actual coupon code in the element’s data cache. Hence preventing the typical user from just viewing source. Mind you this isn’t locked down as I mentioned. As the page loads if you were to look at the raw data you’d see these codes before JQuery iterates over them but we’re not trying to thwart that caliber of user. We’re trying to make sure Joe blow click the link so we get paid. So JQuery stores each code in data cache then makes the element’s text empty. These examples are more verbose than what I actually used, but should help be clear what’s actually happening.

When an element is clicked it retrieves the data from cache shows the coupon by appending a new element that fades in with our original code. and then opens the link to wherever its going with an assumed query param or something that the third party sees.


$(document).ready(function () {

$(‘.code’).each(function () {
var code = $(this).text();
$(this).data({ secure: true, code: code });
$(this).text(”);
$(this).addClass(‘blur’);
});

$(‘.getcode’).click(function (e) {

e.preventDefault();
var hasCode, url, code, data, showCode;
hasCode = false;
showCode = $(‘

‘);

url = $(this).attr(‘href’);

if ($(this).next(‘div.code’).length > 0) {
hasCode = true;
code = $(this).next(‘div.code’);
data = code.data();
}

if (hasCode) {

showCode.text(data.code);
code.append(showCode);
code.removeClass(‘blur’);
showCode.fadeIn(800);

// change window open settings to whatever you prefer
window.open(url, ‘Get Coupon’, ‘width=600, height=400, top=200, left=300’);
}
});
});

Wrap Up

Not rocket science but that’s one way you can do it. Below is the faked blurred out coupon code graphic.

Blurred coupon code mask.

Which Android Tablet Should I Buy

Initial Thoughts

I Tested a few recently and thought I’d share my findings before the article is released. The units tested were the Galaxy Tab 2 10.1, the Asus Transformer Infinity 10.1 and the Toshiba Excite 10.

Let me say going into this I thought hands down the Transformer Infinity would be the clear cut winner with its industry leading high resolution screen. I have to say though I find the Asus product although slick, slim and sexy not as functional as other tablets. What I mean is I experienced some odd scrolling problems, where content was very jerky. It looked great but if I’m constantly fighting that its a deal breaker for me.

Findings

Asus Transformer Infinity

As you might remember the Transformer Prime was a bit of a disaster. Due to the alum. back it caused issues with the GPS in the device. Now if that wasn’t something you’d be using I guess it wasn’t that big of a deal but to shell out $500.00 or more it should work nonetheless. I think Asus was pretty stand up about the issue. They didn’t run and hide by any stretch. Still the same scrolling issue I found with the Prime still exists in the Infinity. I can’t put my stamp on a device that is buggy like that. The screen does look great. Overall it feels rather snappy as well, but the lack of smooth responsiveness really turned me off.

Samsung Galaxy Tab 2

The Samsung overall is a solid device. There are some nice features with the Tab 2. Particularly the IR Blaster which is cool if you want to control your home theater devices. However I’m not sure how practical it really is. I found a remote with buttons is hard to beat. I’ve had touchscreen remotes with elaborate programming since the first Pronto. Have programmed Crestron and others and I still swear buy a high end Universal Remote with actual buttons. Maybe that’s just me. Of the three here I’d have to give the nod to Samsung for the software bundles included. Its a very nice presentation of software. Where the Samsung really falls off for me is they are still using the last gen processor as opposed to stepping up to the Tegra 3 as have others. Really a disservice to the customer in my opinion.

Toshiba Excite 10

First off to be clear this is the Excite 10 NOT the LE version. The Excite is a pretty straight forward device. For example you don’t have the software media share bundling like you have with the Samsung nor the Asus Storage Cloud service, however What it does have are super smooth transitions in the UI. With the Tegra 3 quad core processor it is rather speedy much like the Asus Infinity, but unlike the Infinity the scrolling and screens are quick to transition but in the same breath very smooth. I was happily surprised by its performance. Not flashy. Not as sexy but works well. Come to think of it every thing I’ve owned with the Toshiba name has been about the same. One knock on the Toshiba Excite that I must admit and at least with the audio/video I was testing it has the lowest audio output of the bunch. With that said if I’m watching a film or doing anything other than hearing haptics I’m using headphones.

The Winner Is Toshiba Excite 10

Now before you go saying this guy’s off his rocker understand that I’m a very picky buyer. Small things will get you big red marks with me. Functionality for me is far more important that buzz words and specs that say “I’m really good and I have more x than any other on the market”. What I mean is I want things to do the tasks they were designed to do and do them well. For me the winner here is the Toshiba Excite 10. It’s not the thinest. It doesn’t have the 1080p screen of the Asus Transformer Infinity, doesn’t have the bundling of the Samsung and ease of use but it does have the most responsiveness of the bunch and is rather smooth as I transition between tasks. Please keep in mind I’m a business user. I’m not playing Temple Run (although that was thoroughly tested on each by my 12 yr old, she gave them all +1’s ha ha) or smashing objects with birds. No I’m using it as a tool to check corporate mail, but to scan networks for security wholes, to browse the net to update applications and debug applications I’ve built. The point is if you’re a multimedia guy you might like the Samsung Galaxy Tab 2. If you want to watch great movies in super clear high resolution you may want to try out the Asus Transformer Infinity. If you’re a business user I strongly suggest the Toshiba.

Lastly the Toshiba for a quad core is rather reasonably priced. At just $400 bucks you can afford to use it for now and maybe go for a Nexus 10 once released. If you haven’t heard of the Nexus 10 take a look at the Nexus 7, look at the price tag, roll eyes and prepare to hit submit for the 10 when released I will. Oh and for the record I was able to stream HD .mkv files across my network from my NAS server with zero issues using Vplayer on the Toshiba Excite. It was a beautiful image, was clear and the audio was crisp. There are several video players out there, I’ve found the VPlayer when it comes to playing the .MKV container to be the best. More consistently decodes audio than say Mobo, MXPlayer or others.

Jquery Live Image Crop

Live Image Cropping

I’m sure by now you’ve seen similar tools. Nonetheless I wanted to post this demo for those that haven’t. This demo leverages Jcrop. I won’t get into the details here as their documentation is self explanatory. What I will do is cover what you can do with it after you crop the image. That is where some of the real magic shows up. Cropping itself is rather simplistic. Demo Here

Crop demo screenshot

Live JCrop Demo

Init JCrop


function initJcrop()//{{{
{
// where target is the target image.
$('#target').Jcrop({
onRelease: releaseCheck, // checks for release
onChange: getCoords, // gets the coords and updates the inputs.
onSelect: getCoords // same as above just a different callback.
}, function () {

jcrop_api = this;
jcrop_api.animateTo([259, 81, 469, 304]); // create the corp box at these coords (x, y, x2, y2)

// Set the default checkboxes
$('#resizeable').attr('checked', 'checked'); // whether or not you can resize crop.
$('#aspect').attr('checked', false); // should it be forced to a specific ratio.

});
};

Force Aspect Ratio example trigger using JQuery on checkbox

This is just one example but setting up these options are all very similar


$('#aspect').change(function (e) {
jcrop_api.setOptions(this.checked ?
{ aspectRatio: 4 / 3} : { aspectRatio: 0 });
jcrop_api.focus();
});

Saving the Crop

Here were are making a simple post passing a Json representation of the coords, then await response from server.


$.post(postPath, jData, function (result) {
if (result.saved) {
// here I'm check if in the json result if "saved" is true.
// if yes DO SOMETHING...
} else {
// if not show an error of some sort.
}
});

In the demo after the crop is saved, I simply update the path to the image, the newly cropped image that is.
You’ll notice a “view crop” button that shows it. This is all just for example. Normally when the dialog opens that you’ll see
you might have an input for new filename or perhaps save location or other criteria you want saved to your database. In
fact you don’t need the dialog at all but since this is a static representation/demo I needed somewhere to display the result
and didn’t want to leave the page.

Saving to File System

Unfortunately this is beyond the scope of this article. Mainly because I have no idea what platform you’re one so its pretty tough to give an example. What I can tell you is
that its actually rather trivial for the most part. For example in C# you might do something like this:


var img = Image.FromFile(imgPath, true); // get the image you were working on from file, you could also do this from stream.
Image newImg = new Bitmap(img); // now we have a new image to work with.

var netImage = NetImage.Crop(newImg, w, h, x, y); // here we are taking the coords from JCrop passed in our Json and cropping the image.
// note the above is a custom class that crops images in various ways.
// above result from our custom class is a System.Drawing.Image. we can now save it or do what we wish.

If you’re using say NodeJs(which is amazing stuff btw) or Rails you can investigate Node-Canvas or perhaps ImageMagick.

Conclusion

It really is rather simplistic to crop images. It really is up to you and your design how you want to go about it. What options or restrictions you want. Perhaps you’re wanting to keep each image cropped to a specific ratio or size. Live for profile photos that should only be say 100 x 100. All very easily obtainable.

This is not meant to be a complete start to finish tut. It is meant to point you in the right direction. You can also expand the source on the demo. As always you can send comments and questions and I’ll help if able. You can also hire us for your next project!

Jquery Tagit Extended

Took a few moments today and extended a popular plugin a bit. Use at your own risk as I haven’t tested this to the fullest however it seems to be fine. The modifications were minor as well.

About the Extension

Throughout the source you’ll notice the comments [MODIFICATION] that indicate where the source as been extended. You’ll also notice [END MODIFICATION] to let you know where the original authors source begins again. If you’d like to checkout the original author’s site please do so here. You can obtain my source with the below added features and extensions by DOWNLOAD. Note this is just the .js file and does not include the entire source with stylesheets. Please download this from the author’s site.

Features Added

    minTags – This will make sure no less than the number indicated can be removed. Default is 0.
    maxTags – No more than this many tags can be added. Default is 0 which is unlimited.
    requiredTags – This is an array of strings that must exist and cannot be removed if present. Perhaps a user group or something where there must be a default. Default is null.
    restrictToAvailable – Default is false. If enabled. Only tags in the “availableTags” object can be added.
    onTagRemoveFailed – When a tag cannot be removed due to one of the above constraints this callback is fired. Default null.
    onTagCreateFailed – This is called when a tag cannot be created due to a constraint. Default is null. Use this to give feedback to user if you will.

How to Use

I would encourage you to visit the author’s site for full details and instructions but this will get you going. The below assumes you have referenced the “jquery-tagit-mod.js” file in the header of your page and that you have referenced its companion css stylesheet as well.

$(document).ready(function () {
$('#mytags').tagit({
availableTags: ['tag1', 'tag2', 'tag3'],
onTagRemoveFailed: function (event, tag) { console.log(tag.children('span.tagit-label').text() + ' cannot be removed.'); }
});
});