Hugoware

The product of a web developer with a little too much caffeine

Posts Tagged ‘Project

Getting Organized With Toggl

with 3 comments

I’ve been really busy the past few weeks trying to get ready for my new job and wrapping up projects at my previous job — needless to say free time has been pretty limited.

Up until now I’ve managed my time and projects using ‘The Notepad System’… or basically I just write stuff down, get it done and then check it off… not really something that is going to cut it going forward. Having personal projects, work projects and contract work all being merged into a single list is going to quickly get out of control.

My solution? Toggl!

This, my friends, is a masterpiece of web design and functionality. The devs (and designers) at Toggl have done an incredible job at taking something difficult like time tracking and making it not only super simple… but also hosted on the web!

Toggl makes it simple to create multiple clients, projects and tasks and manage time for each of them. Even better, if you try to enter the name of a client or project that doesn’t exist, it will create it for you on the fly! Every action seems to have been streamlined so that it doesn’t interfere with you doing your actual work!

Tracking time spent on tasks can be handled using the menu on the right hand side by simply clicking the red button (you can even close the window and the timer keeps going). This starts the timer for that task so you know how much time is spent doing something. To take it a step further, if you start a timer for another task, Toggl automatically stops any running timers for you!

Toggl also allows you to open the timer management in a separate window called ‘Nano’ — Which works perfectly with Chrome Applications. (If you do this just make sure you point the url for your Chrome app to http://toggl.com/nano)

And to take it a step further, I wrote a script with jsshell to add some buttons to the view (of course, you can reach them in a menu but I wanted them along the top as well :)).

Toggl also works with a variety of the mobile platforms as well, which is really handy if you aren’t always sitting at a computer.

If you manage a lot of projects at the same time or just simply need to keep track of where your time is going, then I highly recommend Toggl. Signup takes almost no time at all and you get 30 days to try it for free (then it is only $5 a month after that).

I could ramble on about how awesome Toggl is but I’ve already spent 36 minutes and 26 seconds on this task – time to move on to something else!

Written by hugoware

September 19, 2010 at 7:32 pm

jLinq Update (2.2.1)

with 10 comments

I’m off from work this week so the first thing I did was get some work done on jLinq. I’ve had a few bugs I’ve needed to sort out along with a new feature I wanted to implement. I’m also going to be working on documentation this week. Previously, I had created a Wiki and was hoping that people might add to the documentation… but instead spam bots pretty much ruined it so I’ll be starting over from scratch… oh well..

New Features

jLinq itself doesn’t really have a new feature but instead a new way to get the jLinq library. Instead of simply downloading a standard jLinq library you can use the new online jLinq Framework Generator to select only the functionality that you want to include. You can still download the basic pack but this option gives you a little more control what goes into your version of jLinq.

Changes

The most notable change for jLinq is that all of the operator commands have been included as standard functions for the framework. Before, these functions were actually methods extended onto the framework. Since these functions are required for jLinq to work I’ve moved them so that they are in every jLinq framework by default.

Bug Fixes

orderBy with joined records would return incorrect results
jLinq uses eval to figure out the values of field names since you can provide methods, array indexes or whatever. The code used to sort the values wasn’t getting the values correctly so the sorted result was always wrong.

using 0 in certain comparisons would return incorrect results
Ah, this one was fun. So check out the code below…

var values = [ 0 ];
var index = 0;
var a = !values[index];
var b = values[index] == null;

So what is a and what is b? If you said true and false then give yourself a cookie.

jLinq uses the number of arguments passed to help determine if anything is being memorized (like the field name). jLinq makes a quick pass to select all values until it finds a null value… or at least that is what I meant for it to do. Unfortunately, I wasn’t thinking when I wrote that method and didn’t check explicitly for null.

Feedback

If you find any problems with jLinq or have any suggestions, please leave a comment or contact me directly.

Written by hugoware

November 23, 2009 at 9:03 pm

Creating CustomWebmail.com – Part 1

with one comment

CustomWebmail.com is a website that allows you to to create a custom login page for your Outlook Web Access by making changes to the colors, logo and layout of the page. This is a series of blog posts that discuss some of the more interesting parts of developing this project.

The Key Parts Of CustomWebmail.com

In order to develop CustomWebmail.com I had solve a few problems…

  • What is the correct address to post logon attempts to?
  • How can I be reasonably certain that the address is correct?
  • How do I create their custom OWA page with the correct colors and logo?
  • What is the best way to convert an theme image into an actual HTML web page?
  • How can I package their content into a single .zip file?

For the next few weeks I’ll be going over all the steps I used to allow visitors to create custom Outlook Web Access pages with this site.

Determine The Correct Address

Now, this part is probably not close to perfect yet. As it turns out OWA isn’t standard across the board. I’m not just referring to OWA 2003 compared to OWA 2007 — but even matching versions can have different setups. With that said, the application still needs to come up with the correct postback URL to for the final rendered page.

Asking the visitor for the correct URL is probably not really a good idea. They might not understand where to look inside the form or what the address should look like. Instead, the application simply asks them for the address of the Outlook Web Access login page and then uses a series of HTTP calls to determine the rest.

string path = "http://webmail.example.com/exchange";
HttpWebRequest request = HttpWebRequest.Create(path) as HttpWebRequest;

request.UserAgent = USER_AGENT;
request.CookieContainer = result._Cookie;

//get the response from the requester
response = request.GetResponse() as HttpWebResponse;
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
    content = reader.ReadToEnd();
}

//use content to determine form related information
//...

This section of code tells us a few things…

  • Did a server respond to our request?
  • Were we redirected to a different URL?
  • Which level of security was used – http or https
  • If the server doesn’t respond was it really because nothing was there?
  • Does the content contain anything that looks like an Outlook Web Access page?
  • Are we sure that this address will accept our login attempts?

Yikes! Unfortunately those are all real problems that need to be solved in the code — and anything unsuccessful needs to be reported back to the user (or repaired on its own). I’ll skip over the first three since they are fairly easy to determine.

Exception With A Responding Server?

I’ve found that with the HttpWebRequest sometimes you get an exception even if the server is found because the certificate at the site isn’t valid. It throws you off quite a bit especially if you’re expecting a response and your code simply crashes.

As it turns out it isn’t hard to handle invalid certificates.

//Ignore bad certificates
// ** Use at your own risk **
ServicePointManager.ServerCertificateValidationCallback = (obj, cert, chain, ssl) => {
    return true;
};

In my case I’m not too worried if the server’s certificate is valid – I just want to know if it is responding to my requests. By adding in this line of code I can ignore anything invalid and move forward.

Just What Is This Page Anyways?

There are a few arguments you need to use when posting back to an Outlook Web Access login page. We wouldn’t want to accidentally create a login page if someone entered ‘google.com’ instead. By using a couple Regular Expressions we can check to see if the form looks like an Outlook Web Access page.

Here are some of the fields you can check for…

  • An input named username
  • An input named password
  • An hidden input named destination
  • An form action to something containing owaauth.dll

There are more fields you can use but these tend to be a fairly sufficient indicator if we’re looking at an Outlook Web Access form.

Testing The Login

At this point we’re fairly confident that the server we are looking at is an OWA login page but there is one more test we can try. In the final test we perform a fake login to the page to see if we get a password failed error response.

//test the target of the form that was found
HttpWebRequest request = WebRequest.Create(formTarget) as HttpWebRequest;

//create the standard postback information
string post = string.Format(
"username={0}&password={0}&forcedownlevel=0&trusted=0&flags=0&destination={1}&isUtf8=1",
    DateTime.Now.Ticks,
    HttpUtility.UrlEncode(this.Destination)
    );

//prepare the request
request.MaximumAutomaticRedirections = 10;
request.UserAgent = USER_AGENT;
request.Method = "POST";
request.Timeout = 15000;

//and add the content
using (StreamWriter writer = new StreamWriter(request.GetRequestStream())) {
    writer.Write(post);
}

//get the login attempt result
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
response = request.GetResponse() as HttpWebResponse;

//check if a reason code was included
return Regex.IsMatch(response.ResponseUri.Query, @"(&|\?)?reason=\d", RegexOptions.IgnoreCase);

It is possible that we just happened to come across a random server that returns a response code but given all the other tests we can be fairly confident in the address we’re testing.

As a final option we present the user with a test login box that they can try to do a personal verification that the address works.

Written by hugoware

November 2, 2009 at 9:59 pm