Gnome 3 Background/Wallpaper Changer

There are a few programs in Linux that will change your user background for you randomly – and they are all well and good, but most of them lack the ability to customize maybe the hours certain folders will be included.  With the wave of people that are beginning to embrace Linux that are not all that tech-savvy, this post may be useful to you and help you discover ‘hidden’ abilities within Linux – or just a copy-paste solution. For those that are tech-savvy, this may help you find errors you may have encountered in your own scripts since you moved to Gnome 3, as there were a few changes, or it may just help you enable your script to work with Cron.

This entry is both a tutorial, as well as a complete solution for wallpaper/background changing within Gnome 3.

First, let’s start with directory structure – as it is the basis of what images will be chosen. Under your normal user account, create a directory where you want to store the images used for the wallpaper.  Be this  ~/.wallpaper or a non-hidden folder at ~/Pictures/WP or something similar.  Really, it doesn’t matter where you put it.  Inside that directory, you’ll create the directories that will be used for differentiation.  For example, you might have pictures of you and your friends in one folder, scenic pictures in another, and maybe ‘dark’ pictures in a third or something. So create the directories that will be used to separate the different kinds of pictures that you have – in this tutorial we will use two, one called day the other called night.

Now, for the script that will go in the main directory that you set up:

Now, to explain the script, line 1 is setting what type of script this is, which is a bash script. Line 2 saves the old IFS (Internal Field Separator) so that we can reset it after our use of it., line 3-4 sets the new IFS as a newline character.  Line 5 gets the directory name of the script – removing the need to hard-code the location where the wallpapers are. Line 6 gets the script’s filename, so that if the command was for help, we can properly show how to use the script.  Lines 7-8 will change the directory to the script’s directory and save it in a variable for our use later.

Lines 9-26 are purely to catch -help parameter and display how to use this script.  It can be removed with no ill side-effects other than removing the -help option.

Now, the fun part, line 27 detects if there was a parameter, with line 28 doing the lifting of finding all *.jpg and *.png files within the directory inputted. If there was no parameter, it will find all the valid image files within the script’s directory and all sub-directories.   The result of either is set to the pics array, which is why we set IFS to be a newline, separating each file found.  On line 32, we reset the IFS to its previous value.

Bash doesn’t have a way to find a random value between a min and a max built-in, so lines 33-36 handles that. 34 sets num to be the size of the array, 35 chooses a random number between 0 and 32767.  To knock that random number in to the range we need, we take the modulus if it by the max in line 36.  We use that number on line 37 to select one picture from our array.

Now, with Gnome 3 using a cron to change the background, we need to find the DBUS_SESSION_BUS_ADDRESS and set it so that gsettings has a clue of what to do.  So, we export the variable from the current user’s home directory on line 41.

Line 43 is the command used in Gnome 3 to change the background picture and set it to what was found on line 37.  Our final step it to output the selected picture’s filename in case we want to keep track of it.

So, now that you have a script that will change the background for you, you want it to run automatically.  To do this, run the command  crontab -e .  If you find you can’t edit your crontab, read this for some help.

We are going to set it up so that the day folder is used every 10 minutes from 9am until 4:59pm, (following the typical ‘9-5’ work day.) and we will use the night folder from 5pm until 8:59am. To do this, we need the full location of the script, so if you put it in ~/.wallpaper (as we will assume you did) your crontab will look like the following:

Replace <username> with your username.  And, that’s it!  You now have a Gnome 3 wallpaper changer with just a few lines of script and a properly set up crontab, no need to have an application constantly running to change it for you taking up extra memory.

A Little About Passwords

You often hear about how one organization or another has had their database compromised, they publicly apologize to everyone, and suggest that everyone changes their passwords to all sites that may have used the same password as theirs.  When this happens, it always makes me wonder how securely they held my password, which I consider sensitive information.  The general public, especially the non-technical portion of computer users lack education about passwords, and what makes them secure.  I hope to help remedy some of that in this blog.

First, let’s see what makes a good password.  As you can see from this Educational Institution’s Password FAQ, they suggest using special characters and numbers mixed in with letters – and then try cramming that in to 8 characters to use for your password.  Go ahead, read on for how to choose a good password. Or, you can read on Microsoft’s How-To for strong passwords.  The common theme among all of these is to take a phrase that you can remember, and then use the first letter of each word while adding some numbers in there to mix things up.  Did you know, a modern computer can brute-force a 10 character password rather quickly?  There are commercial applications which can test up to 2.6 billion passwords a second.  With that type of computing power, cracking a 10 digit password can be done in one day.  How secure are those first letter phrases now?  The answer is: not very.

Password policies came around the same time as computers and information systems that required you to.. log in.  Most of these password policies (and how passwords are stored) have not changed much since then.  Most recommend around 6-10 characters, mixing cases, adding symbols, etc.  Most software that accepts passwords are not any better at helping protect you, as they like to follow the same guidelines, and then put an upper maximum on the number of characters your password can have.  Why on earth limit a user to so few characters?  I encourage you to look at your bank’s website, and then look at their password policies.  For example, we have Wells Fargo, which tells you your password has to be between 8 and 12 characters.  Go ahead, read the policy.  Now think about this, if it takes one day to crack a 10 character password, how much longer when the maximum length of your password is 12 characters?

So, what really makes a good password?  Length.  And then more length.  Sure, it helps if you can remember a slightly obfuscated version of it as well, add some symbols or punctuation to it here and there.  But primarily, start with a sentence, “I love my black, dog, skip!”.  That is a 27 character long password, and it will take years to crack. (maybe not now, since it’s used as an example in a password blog, however, you get the point.)  The problem with it, is that most places that have passwords won’t let you use something quite that long.  Websites and applications really, really, need to catch up with computing power in their policies.  Let passwords thrive!

Now, for the programmers, have you ever registered for a website and in their introduction email, they send you your password?!  What. The. Hell.  That has happened a few times to me, or I find out the hard way when I forget my password and click the link, and then they send me my original password.  Those are sites that I immediately delete my account on.  If the purpose of a password is to authenticate a user, that password should not even be available to the website owner/programmer/etc.  That password should forever be hidden.  Most programmer’s do think of this consideration (which, when I come across a site that can email me my password, is why it absolutely baffles me as to why they are so stupid.)  Ask a PHP programmer for advice on how to create an authentication scheme.  A vast majority will have kept up well enough to tell you that “don’t use md5 to hash it, use SHA”.  Which, okay, might be a start.  However, these hashing algorithms are meant to be fast.  They are meant to be used with encryption schemes, and so they need to be fast so they don’t slow down the encryption of a large file.  They are also useful for verifying that data is correct.  Give it a large file, and it will give you a semi-unique string of 32 characters to verify the data with.

So, what is a programmer to do?  You need to create a log in for your site, you want your users to be safe when using your site, and you want to avoid attacks via a Rainbow Table.  To avoid rainbow tables, the simple solution is adding salt to the password before hashing it.  The next thing you need to take in to consideration is computational speed.  The slower an algorithm is at generating a hash the better.  So, how do you use these hashes to store a password in your database, in a way that it can be re-created and get the same exact result?  Well, for that, we get to look at stretching the hash.  We do the hash multiple (thousands) of times, and then store that result.  We also want salt that is unique to each user – that way if two users have the same password, they don’t look the same when stored, so cracking one password won’t mean cracking both.

Here is how to generate a ‘secure’ hash of a password in PHP.  The reason it is ‘secure’ is due to its slow speed at generating a hash, it also uses a static salt, and a salt that is unique to each password.  To get a salt that is unique to each user, I personally use something like the registration time of the user on the website as the dynamic salt, and then all my websites have a salt that is unique to each of them – so even if a user is on both with the same password, it will never look like it according to the hashes.  Here’s a look at a function that makes this happen.

The $pepper  variable is what is unique to each user.  This function will take about ~1-2 seconds to generate a hash, and it is suppose to take that long.  The different variations of combing the previous hash, salt, and pepper add to the complexity of generating the hash, though, knowing how it combines them, and when, makes it less effective to adding to the complexity, though, changing it a little for each application will help serve to further obfuscate the password.  Because it takes so long to generate the hash for one password, even if the salt and pepper are known to the attacker, it takes down the number of attempts from 2.6 billion per second, to 1 every two seconds.  It becomes impractical to even attempt compromising a user’s password, as the same 10 digit password would now takes 5.2 billion times longer to brute-force.

PHP Event Hooking

There comes a time during every programmers career where they need to figure out how to hook on to events.  Today, I will show how to create a simple event register for display.  We’ll start with the ‘display’ class.

Now, make sure to read the comments.  Notice line 38, as that is where the magic happens, but also forces conformity among the classes that register.  Each class that registers needs to have a method called ‘getDisplay’, and the return from each of those functions populates the $myDisplay array.  Now, if you are using a template engine (recommended), you can assign the variable $name to it with the return.  But I’m not going in to creating an actual display class that is fully functional, just demonstrating how to allow anonymous event hooking.  Byanonymous, I mean that the display class isn’t away of anything else within the registered objects, just that they have one function to utilize for display.

Now, that the basic display class is created, we’ll create two classes that will register with it.  Now remember, these are very simple classes that will require a reference to the display class.  In an actual application, the display class will be attached to a ‘site’ class or similar, as will these two additional classes, so they would need a reference to the main site and then link it to the display class from there.

And the main code to tie them together:

Notice how Foo and Bar display since they registered with the display class.  So now, you know how to create a class that allows events to be registered and calls the classes that did register.  This can be useful for so many purposes within a dynamic site, display being only one.

I hope that you found this useful, if you have any questions, feel free to add a comment asking.

SSL From a Developer’s Perspective

SSL (Secure Socket Layer) and its new version TLS (Transport Layer Security) are meant to provide secure communication between a client and a server.  I understand how easy it must have been to decide to verify identity with them as well – to show that a site is actually who they say they are.  However, from a developer’s perspective – why on earth do I need to pay so much yearly to prove that…  Well, I am not using it as a payment gateway – I just want to ensure that my user’s information is secure against man-in-the-middle attacks.  I want my users to know that when they submit anything to my site, it will be safe from prying eyes, and kept with me and me alone.  I want my users to have that security.  But now, because of how SSL has developed and how modern browsers treat the certificates – if I have a self-signed certificate my users are told before they see my page that it isn’t trusted.  This is told to my users because I have not paid these large corporations a sum of $200 plus annually to sign my certificate verifying that it is me.  I understand a fee for that service, but why is it worth so much, and why do browsers tell you when a certificate is not signed by these companies?  The security between the communication of the server and client is the same whether or not I paid to have my certificate signed.

As a developer, I do not care whether my identity is is verified.  I want that security for users, but I refuse to pay for it if I am not running a store.  So, that is my rant about the corporate world.  I don’t like people making a ton of money of developers that are trying to protect their users, and then telling those same users that because this developer wanted to secure that communication between them – they are not trusted.  Sorry, I just don’t like how the users get screwed in the situation; because honestly whether data can be intercepted by a third party really does not directly effect me.

Triangles, intersecting lines, how to solve it

Sometimes, I hate how my brain works.  Last night around midnight, I saw this image on a friend’s Facebook wall; and then promptly went to sleep.  This morning, I woke up, and my brain was thinking of those triangles, and wouldn’t let me do much until I set to the task of figuring it out.  Why did this happen?  Well, I counted out the triangles, writing it out in ABC format connecting the points after labeling them in a small photo shop I did (which is bellow).  I ended up with the **SPOILER ALERT answer of 64 **.  And then, I clicked around and saw people coming up with all sorts of numbers (note, this was shared from facebook, none of my friend’s friends got it correct; when I clicked to the ‘Shared from’ thingy, I saw there were over 1000 comments, and none of the last 50 were correct.  So I put down my answer, and then saw so many people after posting saying there are so many more/so many less than that.

The one person that absolutely irked me was the idiot who said there were 7, and everything else had 4 sides.  This person had screwed up in a post I saw earlier that involved the simple order of operations 7 – 10 + 3 * 4….and she said the answer was definitely 3, even after I broke it down and showed why it was 9.  So, she already got on my nerves for being ignorant and arrogant. (When combined, that is my biggest pet peeve.) So, since she claimed that she was right in the instance of this triangle question, I set out to prove it – because that would be the simplest way to show “Hey, here’s how to do it, I hope it helps.” and hopefully edify some people.

So, I typed the triangles in ABC format, and then, since I didn’t want to paste them all in to a comment, especially when my reference image wouldn’t have been available, I put it together with my reference image. Click the left-side image for a full view.  Now, since that was done, I google’d for solving triangles, etc.  I came across something (I can’t remember where it is now, I apologize; I wish I could post the equation there as well)  Anyways, someone saying that no mathematical function exists for a geometric figure that has so many known points of reference?  Really?  Ok, so, now I can’t do anything until I find the mathematical formula to solve this type of problem.

Once you know that the answer is 64, you see that there are 4 lines coming from both A and B that is not connecting the two points, and 43=64. If you remove one line from both A and B, and then count those, you find that there are 27 triangles.  See where this is going? (# of lines)3= # of triangles.  But, that isn’t good enough for me.  What happens if they don’t have the same number of lines?  For example, if you took the outer triangle to be ANB from the test image?  What happens then? Well, you get 15 triangles.  What to the power of 3 is equal to 15?  Well, not an integer – so that general formula doesn’t work for all cases where two points have lines extending from them reaching each others most obtuse angle.  So, I worked out the pattern, and got:

Now, for those that don’t know how summations work, you take f(x) and run it through for different values of x.  For these summations, you would get (1 + 2 + 3 + .. + A)  Remember, that in this formula, the A and B are the number of lines each has that aren’t connected to each other.  So if we go back to the original problem with both having 4 lines each, we get: (1 + 2 + 3 + 4)4 + (1 + 2 + 3 + 4)4 – (4 *4) which is 40 + 40 – 16 = 64.  Sweet!  It works for the main triangle problem.  Now, if we go back to ANB where A is 2 and B is 3, we get (1 + 2)3 + (1 + 2 + 3)2 – (2*3) which is (3)3 + 6(2) – 6 breaking down to 9 + 12 -6 = 15.  Wow… so… it fits all the situations arising from two points throwing lines through space and connecting in triangular fashion!

So, since I couldn’t find a definitive source for this information via my not-so-intensive google search, I present it here!  For those that aren’t good at math, or were just looking for the answer, there you have it.  For those that ask How? to every logical/mathematical problem they are presented with – I hope this helps you understand it, and why it works.  Now, since you have the formula to solve these…

Throw that one around and see how many people say something like 10. 😉

I almost forgot!  Since this is a programming blog, I want to include code, if possible.  So, here is the code to solve this type of problem in PHP.  It can easily be ported to any other language.


MySQL helpers in PHP

Now, as most everyone that programs is accustomed to, it’s the high use of Object Oriented Programming (OOP).  Now, with that, the Liquid Web Framework (though, I am wondering if I should call it Platform? Maybe?  A developers code is separate from the core of the project, and it provides all the useful classes to work with it, so not sure what its technical name should be.)  Anyways, the LW Project is completely OOP is both its design and its implementation, so most code samples and projects that will be presented here will have a containing class -even if a class exists in a PHP module that most installs have.  The reason for this is to try and allow a module to be removed and replaced by another one that serves the same person, but fulfills it in a different manner.  I mention this because that is why these MySQL helper functions came in to play.  I wanted everything I could to pass raw data into the class, and have it form the queries needed to complete.  However, with select statements, that become more difficult, but I did still create a few helper functions that will work nicely in the install script once it’s built.

Now, as I go through these helper functions, keep in mind that like with all good “pre-built” systems that use a database, you want to give those using it the ability to have multiple installs in the same database rather than forcing them to be able to have a new database for each install.  So, the first thing declared with these functions is: define('LW_TP', 'LW_'); That statement will set a constant LW_TP to be LW_, LW_TP stands for “Liquid Web Table Prefix’, but since it will be used often in a database intensive application, I used the acronym. The ‘LW_’ is what the users of this system will change for their specific projects (if they so choose to change it).

The first method that we create will be to sanitize string input:

Notice the call to $this->connection , that is the stored object resulting from creating a new mysqli object.  The method real_escape_string requires a connection to be made, and can escape the string based on the database charset.  That’s it.  That is the entire method for sanitizing user input to prevent SQL Injections. (Though, it should be noted that it must be called individually on each input into the database – but we’ll get to that.)

Once you are connected to a database, the first thing you need to do is add tables – whether you do that manually, or in an install script really makes no difference; though using an install script allows your entire base application to be portable.  This next method will create a SQL statement based on input, and then execute it.

The tableName parameter is pretty obvious, coupled with our earlier define, we get the new table name stored in $tbName that will be used in the SQL statement.  Now, the fun part has to do with $fields , as that is an associative array of the fields that will be in the table.  An example input would be:

See how it is set up?  The name of the table is the key of the array, while the parameters are the value of said array.  On lines 4/5 of the method, we loop through the array, adding to the array we created on line 3.  From there, we make use of the implode function to separate our new array out by comma’s.  After that, we put it all into a SQL statement and then execute it via $this->query() method.  That function can and should be changed for your own integration, but it is a simple method that can be used in a script to automatically add the table prefix and piece it together.

This next function is a little more useful, as it does a couple of things other than making sure the table name has the prefix.  It is for inserting information into your database:

Inputs are pretty much the same as the createTable method, however, the associative array is formed slightly differently, with the key being the name of the field you want to insert in to; the value is…the value you want to insert.  Please note – for auto-incrementing fields, you don’t want to have a key set for that field, ignore it completely in the insert so it can do its thing. Example of the fields variable with a static input, you would want to use the user-input information instead:

Now, this method will create two arrays, one for the names of the fields, and one for the values, on lines 3/4.  On lines 5-8, we loop through the $fields setting our two new arrays appropriately. Notice on line 7, we use the sanitize method that we created previously to escape the user-input and prevent SQL injections.  On lines 9/10, we implode the arrays we created with a comma so that they are in appropriate form.  After that, it’s just putting the pieces together and executing them (Lines 11/12 in the method).

That’s it! The last method I gave is the actual useful one outside of needing to prefix the table name, so have fun.

Handling Fatal Errors in PHP

Yesterday, I went over the ways to use a debug class in order to catch and report exceptions. Today, I will build off that same class we used to catch and show fatal errors as well as keeping the display of the notice stack. We will do this by using the php function register_shutdown_function, and passing the current class instance. This is done in a similar fashion to how we handled exceptions. But, first things first – we need to build the helper functions that we will use while handling the errors.

First, we want a quick way to change the error[‘type’] into text that we can output. For that, we’ll create the method called ‘getErrorType’ which will take a numeric input and return the string equivalent to it.

Notice that it is declared in the private scope. We do this as this class is meant to be the say-all in the debugging process, so no other class/method/code should need to call it from outside of our debug class.

Next, we create a method that will be called on script ‘shutdown’.

Now, that method will call our error handler if ANYTHING has gone wrong in the script before it is killed. Notice the comments stating that it is blanketing everything. If you want to change the handler to only call the stack on a fatal error, check for $e['type'] == 1 , rather than $e != null .

Now that our new helper methods have been created, we’ll go back in to the __construct() method and add a few things. First, we want to stop PHP from displaying errors itself, that’s the purpose of this class, so we’ll add the line ini_set('display_errors', 0); to the top of our constructor, and then we’ll register the shutdown handler that we just created with register_shutdown_function(array($this, "handleShutdown")); Notice the context – it is called every time a script ends, but before objects are dismantled – which is why we check for an error rather than routing it immediately to our error method. So now, our full constructor method looks like:

And now, your debug class can catch and close nicely when a fatal error appears – showing in the same format as we had for exceptions yesterday, but adding the fatal error as the error message instead of the exception thrown.

PHP Exception Handling

No one, including myself, seems like to write “try/catch” into their code. There is one reason why I don’t that stands out – an exception means that something went wrong with something vital enough that it cannot continue. I see a lot of PHP developers complain that they want to be able to ‘handle’ the exception by logging it or displaying it to the screen; however, if an exception occurs, it’s something vital enough that it was thrown to let you know of the error. Something in your code (or user input if you are using that) was wrong, and should be fixed – either in the code, or as a notice for the user.

I am currently working on my LW framework version 4. (It is called Liquid Web, as it has been since 2002, but since there is now a hosting company with that name, I’m not sure if I’ll run in to a trademark issue, as that’s something I never applied for.) With this, I am changing the purpose of LW from being a CMS to being a Framework for developer’s to use. Because of its nature, being dynamic with the classes/modules loaded, I had to make a ‘debug’ class that will record various actions (ie, ‘This class was loaded’, etc.). Now, those notices are stored within a class variable, and if something goes wrong, I want to be able to display the notices/warnings that have accumulated within the class before an error occurred. I also want the error to be displayed, and the application to quit so that as I develop the rest of the features for this framework, I can intuitively debug it depending on what went wrong, and where. After looking for hours on, and reading through all the comments, then some googling on the issue; I came up short for an answer of how to catch exceptions within a class, but not to have it statically called (I want my variables to be available). And so, I got to do some trial and error within my debug class – what i ended up with works like a charm.

First things, first, I have two private variables within the class:

The main variable used is $notices as that is where the “This class was loaded”/etc are stored. The $warnings is there for future implementation if I feel there’s a need to separate the two. To add a notice to the array, the following method handles:

Now, as previously said, there is no implementation to set warnings yet, though one exists to display them (so I have less code to change if I do use them eventually). Those two functions are:

I also have an error method to be given an error message, display all the warnings/notices along with the error, and then die.

Now, that’s all well and dandy, but anytime an exception happens, I want to work with it in the framework, not need to know the variable that is holding the debug object, and to display everything before it dies. I can do some of that with the error method, however, I will need to catch every exception, and then call the [debug variable]->error in every catch, or make a function that will handle it all, but still need to know the variable holding it.

After some trial and error, I ended up with a constructor method that looks like:

Now, obviously, due to how set_exception_handler works, I need a function, but using an array and passing the reference of the current class instance, I get full access to the notices/warnings that have already been stored. So after the constructor, I added the handleException method:

After that, ANY exception thrown within the code is passed to the debug exception handler, and I know what all got loaded before the error, the error is displayed at the top of the page with the file/line/etc.

Now, this entry isn’t meant to extensively cover how to handle exceptions in PHP, but it is meant to show a small demonstration of how to do it within a class structure so you can keep any other debugging information that may have already been passed to help further identify the problem in the code. I know that the debug class is simple, incredibly simple even, but it seems to fit its purpose of a basic logging/error handling class that is loaded into another class – and that is something I couldn’t find how to do in anything I read online. So I hope this may help any other programmers that have this problem.

Matrices and PHP

So, I have been wanting to complete my matrix class since I started it back in 2005 (right before entering the army).  Anyways, yesterday I found my old code, and looking through it saw that it wasn’t documented, but was partially functional. (Some key components were missing to solve linear equations using it.)  Anyways, seeing that, and seeing a lack of Matrix support in PHP other than from PEAR (and I’ve never been a fan of PEAR), I decided to rewrite mine in PHP5.  Behold!  The Power of the Matrix!

You can see the documentation for this class, use an application to solve linear equations with it.  After, I commented it, got it into my SVN, and then uploaded it to  The documentation is quite complete, and there are plenty of examples on its usage within the Class page on that site, including the script used to solve linear equations. So, my fellow programmers/math nerds, I hope this class finds you well, and you can find a lot of practical uses for it within your code.  And, if you do, please, let me know how you used it, and let me know of any errors you might find!

All My Movies v7.1

Normally, I wouldn’t break from the main purpose of this blog to post on something that isn’t technically related.  However, since I have thousands of movies, and never had a good way to organize them, I had been about to give up and create my own program via Python/PHP to get the list of files from the dir, and then to try and do automated lookups/HTML parsing in order to store that info in a format that I can read, easily see where the files are, etc.  Now, I’ve attempted to use AMC (Ant Movie Catalog) a few times, each time winding up disappointed that while it does have a rich feature-set, it doesn’t allow linking to the movie on your hard drive as well as the IMDB page that belongs to the movie.  Also, the data fields are just…fields, lacking interactivity of say linking to actor’s.  So, I went online one more time to see if there were any better solutions.

What I ended up finding was All My Movies, with a free (30 day) trial.  Importing 190+ movies took almost no time at all – though I personally didn’t like the social networking ‘push’ once the database hit 100 movies, I am sure that others might? (Allows you to tell Facebook or twitter that you have 100 movies in your collection now.)  So, adding movies from files and linking them to and pulling information from IMDB was rather quick (especially when compared to every other movie database I have attempted to use, let me get to the awesomeness that is All My Movies version 7.1.

Select by Genre

Choosing a Genre to browse by

First, movies can be listed by the Genre, and then sorted by year or title.  Now for those out there that have thousands of movies and are trying to decide what to watch – well, this is perfect!  Because after you sort the list, select your genre, see the box-cover – you can then play the movie from within the application.Play buttonHow easy is that?  Not only will you have a comprehensive list of all your movies, you have the tools to easy look through them and choose what you want to watch based on any number of attributes.

Another cool feature that might be overlooked is the ability to view random stats about your collection.  How many are on your hard drive, how many are VHS, DVD, etc.  These stats also break down the Genre’s as well as the years and codec’s used for the movies linked by files.

All My Movies Stats View

Small version of stats

Conclusion: Go get All My Movies and test drive it yourself!  If you have a ton of movies and would like some efficient and feature-rich software to help you organize them across multiple drives and folders – this is what you are looking for.  The only ‘con’ that I have found, is that I would like it to ‘watch’ certain (and multiple) folders for new files and request to add them to the particular database that you are working with when you open it.  But hey, this has more than enough to make up for it, and it’s just a matter of remembering to keep it updated and you are good to go.

« Older Entries

    Search the Blog