Riley Dutton2012-04-10T07:25:11-07:00http://riley.dutton.us/Riley Duttonriley@dutton.usAn easy way to change the settings of an S3 Bucket’s files (in Ruby)2011-05-20T00:00:00-07:00http://riley.dutton.us/2011/05/20/an-easy-way-to-change-settings-of-s3-bucket-in-ruby<h1>An easy way to change the settings of an S3 Bucket’s files (in Ruby)</h1>
<p class="meta">May 20, 2011</p>
<p>I recently needed to go back and change the settings of the files in an S3 bucket. I wanted to set the permissions to “pubic read” and also set a cache control header so that the images would be cached in browsers approparitely. After a bit of Googling, I wasn’t able to find anything particularly simple and straightforward. It’s really a pretty easy task, though. The one “gotcha” is that S3 will only return up to 1,000 keys for a given bucket at a time, so you have to be sure to loop through until you get them all. Here’s what I came up with:</p>
<script src="https://gist.github.com/982938.js?file=setheaders.rb"></script>
Collapsable/Expandable Table View Rows in Titanium Mobile2011-04-28T00:00:00-07:00http://riley.dutton.us/2011/04/28/collapsable-expandable-table-view-rows-in-titanium-mobile<h1>Collapsable/Expandable Table View Rows in Titanium Mobile</h1>
<p class="meta">April 28, 2011</p>
<p>I recently needed to be able to have a quick and easy way to create collapsable/expandable TableView Rows in Titanium Mobile. Here’s what I came up with:</p>
<script src="https://gist.github.com/946647.js?file=collabsablerows.js"></script>
jQuery Templates vs jQote 2 - A Followup2010-10-12T00:00:00-07:00http://riley.dutton.us/2010/10/12/jquery-templates-vs-jqote-2-a-followup<h1>jQuery Templates vs jQote 2 - A Followup</h1>
<p class="meta">October 12, 2010</p>
<h2>Introduction</h2>
<p>My <a href="/2010/10/10/jquery-templates-vs-jqote-2.html">original post</a> regarding a speed comparison between jQote2 and the new jQuery Templates plugin has generated more interest than I originally expected. In fact, several members of the jQuery Templates team have written to me either with questions or with suggestions about how to improve the benchmark to make it a more “apples to apples” comparison. To understand why the first benchmark wasn’t necessarily as fair as I had originally assumed, we have to dig a little deeper into the way the two plugins work.</p>
<p>The original jQote plugin worked very similarly to the way that I was apparently using the jQuery Templates plugin (and it was much slower than jQote 2). Both jQote 1 and the <code>.tmpl()</code> function of the jQuery Templates plugin apparently process the template and then create an unparented DOM fragment that is ready for insertion into the page. The jQote2 plugin, on the other hand, simply generates a string from the template. The overhead associated with creating the DOM fragment is apparently very high, and explained a great deal of the slow down in the jQuery Templates plugin benchmark.</p>
<p>Boris Rivers-Moore, the principal developer on the jQuery Templates plugin, was kind enough to write me an email explaining this, and offered a suggestion on how to improve the benchmark. Apparently, there is a different way of going about using the plugin, with the following method: <code>template_object($, payload).join("");</code></p>
<p>This way of doing things works the same as the jQote2 plugin, generating a string from the template, rather than the unparented DOM object. It is also much faster.</p>
<p>He also pointed out that the jQuery Templates plugin automatically HTML encodes during the variable insertion, and offered a different set of tags for the template that would remove this functionality, again providing a better comparison for a benchmark.</p>
<h2>Benchmarks</h2>
<p>Here is an updated benchmark, using this new method and with the template tag changes (time to render in milliseconds; lower bars are better):</p>
<p><img src="http://riley.dutton.us/images/benchmark5.png" /></p>
<p>Average time for jQote2 was 11ms, for jQuery Templates 25ms. As you can see, the jQuery Templates plugin is now much, much more competitive in terms of speed compared to the jQote plugin.</p>
<p>However, this got me thinking; the benchmark could really be considered rather synthetic at this point, because although it does measure the time to go from template + payload to HTML string, it doesn’t actually take into account doing anything with the resulting string. So, I added on some additional functionality to the benchmark, where the resulting string is appended to the DOM object (in this case, a <code><div></code> tag hidden by CSS). Something along these lines:</p>
<pre><code>$("#div").append(template_object($, payload).join("")); //jQuery Templates
$("#div").append($.jqote(template_object, payload)); //jQote2
</code></pre>
<p>Here are the results of this adjustment:</p>
<p><img src="http://riley.dutton.us/images/benchmark3.png" /></p>
<p>Average time for jQote2 was 66ms, for jQuery Templating, 76ms. As you can see, some time is added on by adding the string to the DOM, but not much, and again the plugins are very close in speed. This, however, led to one further thought: if adding the string to the DOM is so cheap, then why bother with using <code>.tmpl()</code> and creating the unparented DOM fragment?</p>
<p>As a comparison, I again modified the benchmark, this time to use the <code>.tmpl()</code> call from the jQuery Templates plugin, instead of the function which creates a string. Keep in mind that this is the “officially documented” way of using the plugin, and the way that all of the new tutorials being created out there seem to be using. The code was something like this (similar to what was used in the original benchmark): <code>$.tmpl(template_object, payload).appendTo("#div");</code></p>
<p>And here were the results:</p>
<p><img src="http://riley.dutton.us/images/benchmark4.png" /></p>
<p>Average time was 480ms. Over 6 times slower. From a very speedy 76ms, to a page-halting 480ms.</p>
<p>I understand that having an unparented DOM object can have its advantages. For example, it allows you to chain together a series of statements, and work with the resulting object directly in jQuery if you need to do further processing. However, the vast majority of tutorials, and even the official documentation on the jQuery site, is simply taking this unparented DOM object and appending it to some other object on the page (as does the benchmark). It’s apparent from these results (as near as I can tell, anyway), that it would be much, much faster to simply create the string, and then append that string to the DOM (which I assume is why jQote2 switched to this as its primary modus operandi, instead of the DOM fragment functionality of jQote 1).</p>
<h2>Conclusions</h2>
<p>When doing a better, apples-to-apples comparison, it does become clear that the jQuery Templates plugin certainly can hold its own ground against the existing field of jQuery templating plugins, including jQote2. However, the majority of material that I have read about the new plugin (including the official documentation) uses a method which is apparently many times slower than it needs to be. I looked through the official jQuery documentation for any mention of the faster “string” method of using the plugin, and I was unable to find any. It is possible that I missed it, but I hope that these findings will encourage the jQuery Templates team to better publicize the faster method. Again, while the .tmpl() function may be useful if chaining or further processing is required, if your only goal is to get the resulting template into the DOM, the string method is much, much faster.</p>
<p>On the other hand, I should point out that each benchmark here is doing 1,000 template executions, so perhaps this is an unfair comparison of using the .tmpl() function. One could argue that if you needed to loop through 1,000 items, you would do so inside the template, and depending on how the .tmpl() function handles internal loops (I honestly have not looked), it might cut down significantly on the overhead, since it would only be presumably building one fragment instead of 1,000. But, to be on the safe side, it seems that if you just want to process the template and then insert the the result as a whole without any further processing, the string method seems to be the best bet.</p>
<p>Boris also took the time to point out a few other features that jQuery Templates has that I was unaware of:</p>
<blockquote><p>The jQuery Templates does include a number of other features in addition to encoding which may not be part of the other template engines. One is using with() so that you can say rather than as in jQote. Also, we test for whether fields are defined, so that we can accept ‘jagged’ arrays, where a field may be defined on some items and not on others. And we test for whether foo (in or ${foo} ) is of type function, and if so, we call the function. And so on. These features impact the perf [sic] slightly.</p></blockquote>
<p>Thanks to Boris Rivers-Moore and Marcus Tucker for taking the time to read my original post and respond. Keep up the good work!</p>
jQuery Templates vs jQote 22010-10-10T00:00:00-07:00http://riley.dutton.us/2010/10/10/jquery-templates-vs-jqote-2<h1>jQuery Templates vs jQote 2</h1>
<p class="meta">October 10, 2010</p>
<p>The jQuery team recently released an “official” jQuery plugin called Templates to address the increasing need for client-side templating when working with web applications. I have been using this technique for quite some time in my own projects through a different jQuery plugin called jQote2. Of course, the first thought that came to my mind was, “should I switch?”. For me, at least, the two primary concerns are feature set and speed.</p>
<p><em>Feature Set</em></p>
<p>The feature sets of the two plugins are pretty similar at first glance. Both offer you the basic ability to use Javascript variables inside of an HTML template stored in a <code>script</code> tag. The syntax is a little different ( <code>${varname}</code> vs <code><%=varname%></code>), but honestly that’s a pretty minor difference, and it’s really going to become second nature depending on which plugin you end up using. It does meant that I would have to re-write my existing templates to make the switch, though.</p>
<p>Both plugins offer the ability to pre-compile templates at page load so that there is minimal overhead associated with using a template over and over again on a single page. This compiling feature is also very important for those of us who work with Adobe AIR, as without the ability to compile, AIR’s <code>eval()</code> after onload restriction makes templating impossible.</p>
<p>So, as far as feature sets go, at least in my eyes it’s pretty much a tie, with a slight edge to jQote for my own purposes since there’s no point in converting all my existing templates to a new syntax if I don’t gain any new features.</p>
<p><em>Speed</em></p>
<p>The official jQote site has an interesting grouping of benchmarks published, and the author of the plugin was kind enough to post this benchmark page on Github. However, I noticed it had not been updated to include the newly-released official templating plugin, and instead includes a much older version of the plugin. I downloaded and modified the benchmark to include the latest version of the Templates plugin found on Github.</p>
<p>The benchmark works by pre-compiling two templates (a simple template with a few variable insertions, and a more complicated template featuring a for loop) for all the tested plugins (it includes a number of other plugins besides just jQote and the official Templates plugin, which I have also included for consistency’s sake). It then passes two payloads to each templating system 1,000 times for a single benchmark, and this benchmark is repeated 25 times. It should be noted that by precompiling the templates, the actual compilation time is not taken into account in these benchmarks — this is strictly a test of the processing time it takes to process a payload into a pre-compiled template.</p>
<p>I ran the benchmark on Chrome 6.0.472.63 on Mac OS X Snow Leopard 10.6.3. Here are the results (average time to render, in milliseconds; lower bars are better):</p>
<p><img src="http://riley.dutton.us/images/benchmark1.jpg" /></p>
<p>For reference, jQote2 had an average time of 11ms, maximum time of 15 ms. The official jQuery Templates plugin had an average time of 510ms, with a maximum time of 560ms.</p>
<p>The official plugin is off the charts. It is incredibly slow. For reference, here is the benchmark as it originally appears on the jQote site…here “jQuery Templating” refers to a very old version of the jQuery Templates plugin (which at the top reads “for demonstration purposes only”):</p>
<p><img src="http://riley.dutton.us/images/benchmark2.jpg" /></p>
<p>So at some point in the development of the plugin, things got incredibly slow. Just to be sure, I re-ran these benchmarks on Safari and Firefox (both on Mac), and found similar results (the overall time of all the plugins actually increased since the Javascript engines in those browsers are currently slower than the one in Chrome on Mac, but the relative results were the same).</p>
<p><em>Conclusions</em></p>
<p>Of course, the new official Templates plugin for jQuery is still beta software, and I expect as they continue to develop it, the speed increases will come. However, as of right now, I will most definitely be sticking with jQote2 for all current and future websites, until the software has more time to mature. It is good to know, though, that the feature sets are very similar, as is the syntax, so that if a time comes in the future that the Templates plugin surpasses jQote in speed, it won’t be too terribly difficult to switch.</p>
<p><em>Small Rant</em></p>
<p>I am left to wonder, however, why the jQuery team decided to create their own templating code from scratch when there were already so many other jQuery templating plugins out there, including one such as jQote which already does everything they want their plugin to do, and faster to boot. Why reinvent the wheel? I am sure that since it is the official implementation, the Templates plugin will get a lot of use, have many tutorials incorporate it, be used in other plugins, etc. Which just drives home the point further that the jQuery community as a whole might have been better served by using a better, more mature implementation of this feature, rather than starting from scratch.</p>
Getting MSSQL to Work with PHP on Ubuntu 10.0.42010-09-27T00:00:00-07:00http://riley.dutton.us/2010/09/27/getting-mssql-working-with-php-on-ubuntu<h1>Getting MSSQL to Work with PHP on Ubuntu 10.0.4</h1>
<p class="meta">September 27, 2010</p>
<p>After about 2 hours of Googling, I finally found this gem showing you how to get the MSSQL module installed on Ubuntu for PHP. Take my advice, DON’T go the ODBC route — it’s frought with peril.</p>
<p>The only thing that seems to have changed between that post and 10.0.4 is that <code>sudo apt-get source php5</code> put the php5 source in my home directory (<code>~</code>) instead of the a system directory. I also had to install <code>php5-dev</code> in order to get access to <code>phpize</code>. Everything else was a breeze!</p>
<p>Just in case it should ever go away, here’s the exact steps I took to install on Ubuntu 10.0.4:</p>
<div class="highlight"><pre><code class="bash">sudo apt-get install php5-dev
sudo apt-get <span class="nb">source </span>php5
<span class="nb">cd</span> ~/php5-5.3.2/ext/mssql
sudo phpize
sudo ./configure
sudo make
sudo make install
</code></pre>
</div>
<p><em>Viola!</em></p>
iPhone FaceTime - Why It Just Might Work2010-06-07T00:00:00-07:00http://riley.dutton.us/2010/06/07/iphone-facetime-why-it-just-might-work<h1>iPhone FaceTime - Why It Just Might Work</h1>
<p class="meta">June 7, 2010</p>
<p>In case you don't already know, Apple announced the newest iPhone today at their annual Wordwide Developer Conference (WWDC). I'm not going to delve into all the great new features here (there are plenty of other places to go for the full run-down), but one of the features that seems to be consistently generating a lot of chat on Reddit is the new video chat (a.k.a. FaceTime) feature.</p>
<p>Comments are mostly centering around two things: 1) that it's a shame it only works on WiFi, and 2) that this has already "been around, especially in Asia and Europe, for 5+ years". I'm not going to really address point one, because I think we all know that AT&T and their ridiculously bad coverage are to blame for it, and there's nothing Apple can probably do about it at this point. But let's discuss point two, shall we?</p>
<p>I find it interesting that folks constantly bring up the "so-and-so already did it" argument with Apple. Apple is very rarely the first folks to the party when it comes to new technology. Take their iconic MP3 player, the iPod. They didn't invent music players. They didn't even invent the hard drive MP3 player (in fact, I had one years before the iPod came out from a little company called Creative). But they took what was there, and they polished it, and they approached it from a new direction. They made the MP3 player more than just a "geeky gadget" — they made it cool. And they also had the incredible foresight to realize that their new cool gadget would really benefit from a marketplace for music; this has been, arguably, one of the best decisions Apple ever made, even paving the way for the iPhone's App Store, and now the iBooks book store.</p>
<p>I think that the main problem here is the disconnect between the general public and the tech-savvy elite. For a long, long time, the tech-savvy of the world (and I count myself among this group) were used to setting the stage for new technology based in large part on technical specification. It didn't matter to us if the computer looked good, or if the application had a marketing campaign — we just made logical choices based on the specs. Which had a faster processor, which had more memory, which handled more filetypes, which had the features that we wanted, even which was open-source. But Apple changes that game completely around. They have the amazing ability to use marketing and design to sell the general public on things that have been around forever, but have remained in the hands of those elite. My mother (who loves her iPhone) isn't interested in the processor, or the memory, or even the resolution of the display; she loves to be able to get her email wherever she is. It's the first phone she's ever had that she can actually send text messages. Not that her previous phones lacked the capability! Rather, the iPhone is the first phone that has made it effortless.</p>
<p>And I think with video calling, that mainstream appeal is more important than ever. In fact, it's almost downright ridiculous that there are actually folks on Reddit who don't see that. The fact that your Nokia from 3 years ago has a video chat feature is completely and utterly meaningless if you have no one else to call besides your one other geek friend who was capable of understanding how that phone worked in the first place. Apple has the sheer numbers to make this work. In the next year or two, they will ship millions and millions of units (iPhone 4, as well as the inevitable new versions of the iPod Touch and iPad) capable of making video calls. And it's as simple to use as pressing a button when you're already on a call. I also fully expect an announcement at some point with a new version of iChat that supports video calls between PCs and mobile devices that are Face Time capable.</p>
<p>And it's more than just a numbers game. If you've watched the <a href="http://www.apple.com/iphone/design/">Apple iPhone 4 announcement video</a>, you're keenly aware that they've already begun selling the general public on why they need video chat in their lives. What do you mean you're on a business trip and you can't see your baby daughter's face? What do you mean grandma and grandpa can't keep up with the family? The Apple marketing machine has already ramped up, and within a year folks everywhere will wonder how they ever lived without this fundamental piece of their lives -- or they'll be putting it at the top of their list for Christmas.</p>
<p>In short, Apple may not be pioneers of technology specifications, which may not impress geeks making phone choices based largely on processing speed and open-source tech, but they are the kings of polish and mainstream. If anyone can pull off video calling, it's them.</p>
Database Backup on CentOS Using Dropbox2010-06-05T00:00:00-07:00http://riley.dutton.us/2010/06/05/database-backup-on-centos-using-dropbox<h1>Database Backup on CentOS Using Dropbox</h1>
<p class="meta">June 5, 2010</p>
<p>One of the most important considerations when running any web server is the ability to backup important data. One of the most important pieces of data on any server is, of course, the database. I currently use Linode as my web host of choice — they’re fast, reliable, and affordable. However, one place where their service is slightly lacking is the inability to perform automated backups (<em>editor's note: they have since rolled out an automated backup offering</em>). Most of the files for a given website are already backed up as we create and maintain the site, but one key area where a whole host of data could be lost without a proper backup solution is the database. Having already used Dropbox for some time now to enable our team to collaborate effectively, and knowing that they have a command-line Linux client available, using it for our backup solution is an obvious answer. The process itself wasn’t too terribly difficult, but it did require quite a bit of searching through various partially-complete articles, so I have compiled them all into a quick and easy step-by-step guide that should work for those of you out there using a “headless” VPS (such as Linode) with CentOS installed.</p>
<h2>What You’ll Need</h2>
<ul>
<li>At least one Dropbox account. I’ll leave it to you to figure out how to sign up for one, but you must have an active free or paid account to complete this process. Note that with a free account you will only be able to maintain up to 2 GB worth of backups. (Note: We actually use several — a free account for the server, which shares a folder with our team’s paid accounts.)</li>
<li>Command-line and root access to a CentOS web server.</li>
<li>About 30 minutes.</li>
</ul>
<h2>Step 1: Install Dropbox on the CentOS Server</h2>
<p>The first step is to install Dropbox onto the CentOS server itself. This part of the process is largely based off of a handy guide I found by Justin Kelly, so thanks to him for providing that very useful information. SSH into your CentOS server, and in your home directory (or some other temporary place) run the following commands, which will download Dropbox and begin the process of installing it:</p>
<pre><code>wget -O dropbox.tar.gz http://www.getdropbox.com/download?plat=lnx.x86
tar zxof dropbox.tar.gz
wget http://dl.getdropbox.com/u/6995/dbmakefakelib.py
python dbmakefakelib.py
</code></pre>
<p>At this point, you may receive an error about not having GCC installed. If that’s the case, you can install it but running:</p>
<pre><code>sudo yum install gcc
</code></pre>
<p>And then running the Python command again:</p>
<pre><code>python dbmakefakelib.py
</code></pre>
<p>After that command has executed successfully, you should see a pause followed by the message:</p>
<pre><code>dropboxd ran for 15 seconds without quitting - success?
</code></pre>
<p>You can simply <code>Control+C</code> out of that running script. At this point we have successfully run Dropbox, but it does not know what account to connect to. To get that part working, we will have to manually link the HostID of our CentOS server to our Dropbox account. To do so, we will use SQLite to open a small database.</p>
<pre><code>cd .dropbox
sqlite3 dropbox.db
</code></pre>
<p>Once at the SQLite prompt enter:</p>
<pre><code>sqlite> .dump config
</code></pre>
<p>A small amount of data will print out. The part we are interested in is:</p>
<pre><code>INSERT INTO "config" VALUES(3, 'host_id', 'XXXXXXXXXXXXXXXXXXXX
</code></pre>
<p>Take whatever is in <code>XXXXXXXX</code> for you (your <code>host_id</code> value), open up this site: Base64 Decode Script, and get the decoded version of your <code>host_id</code>. NOTE: You only want the characters after the first captial “V”, on the first line (ignore the “pl” and “.”). Once you have this value, open the following URL in your browser (NOTE: You should either be logged out of Dropbox or logged in as the user you want to link the computer to): <code>https://www.getdropbox.com/cli_link?host_id=YOUR-DECODED-HOST-ID</code> After you do that, you should see a message that says “Computer was linked to your account successfully”. Now that we’re linked up, let’s complete the final steps on our server. We need to make a directory for Dropbox to live in. At your server’s command line, enter:</p>
<pre><code>sqlite> .exit
cd ~
mkdir ~/Dropbox
</code></pre>
<p>To start Dropbox, enter:</p>
<pre><code>~/.dropbox-dist/dropboxd &
</code></pre>
<p>When that’s working, we’ll want to install Dropbox as a server. To do so:</p>
<pre><code>sudo vi /etc/init.d/dropbox
</code></pre>
<p>And paste the following into that file:</p>
<pre><code># chkconfig: 345 85 15
# description: Startup script for dropbox daemon
#
# processname: dropboxd
# pidfile: /var/run/dropbox.pid
#
# Source function library.
. /etc/rc.d/init.d/functions
DROPBOX_USERS="user1 user2"
prog=dropboxd
lockfile=${LOCKFILE-/var/lock/subsys/dropbox}
RETVAL=0
start() {
echo -n $"Starting $prog"
for dbuser in $DROPBOX_USERS; do
daemon --user $dbuser /bin/sh -c "/home/$dbuser/.dropbox-dist/dropboxd &"
done
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch ${lockfile}
return $RETVAL
}
stop() {
echo -n $"Stopping $prog"
for dbuser in $DROPBOX_USERS; do
killproc /home/$dbuser/.dropbox-dist/dropboxd
done
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $prog {start|stop|restart}"
RETVAL=3
esac
exit $RETVAL
</code></pre>
<p>Make sure to replace <code>user1</code> and <code>user2</code> with the users that you want Dropbox to run as (we just created a user called ‘backup’ that runs all the backup scripts on the server.) And finally:</p>
<pre><code>sudo chmod +x /etc/init.d/dropbox
sudo /sbin/chkconfig --add dropbox
sudo chmod 755 /etc/init.d/dropbox
</code></pre>
<p>So, at this point, you should have a working Dropbox installation on your CentOS server. Test it out by creating a couple of text files in the folder — they should show up in the web interface. You can also create a Shared Folder as your backup folder and any files created during backup will be copied to other Dropbox users who are sharing that folder.</p>
<h2>Step 2: Create a MySQL Backup Script</h2>
<p>Now that we have Dropbox running and syncing files, all we really need to do is copy the files that we want backed up into the Dropbox folder (or Shared Folder, depending on your setup). To do so, we’ll create a basic CRON script that automatically dumps our MySQL database every day, and puts that dump file into the Dropbox folder. Go to your user’s home directory, and create a new file:</p>
<pre><code>vi daily.backup.cron
</code></pre>
<p>And paste the following code into the newly-created file:</p>
<pre><code>#!/bin/bash
mysqldump --opt --host=localhost --user=DBUSER --password=DBPASSWORD --all-databases > /path/to/Dropbox/dailyBackup.sql
</code></pre>
<p>Be sure to replace <code>DBUSER</code> and <code>DBPASSWORD</code> with the username and password of a database user with access to all of your databases, and replace <code>/path/to/</code> with the path to your Dropbox folder (the one we created earlier). Set the script as executable, and test it out:</p>
<pre><code>chmod +x daily.backup.cron
./daily.backup.cron
</code></pre>
<p>You should get a database dump saved to your Dropbox folder, which is then synced to Dropbox’s servers and any other folks you are sharing the folder with! Finally, create a crontab entry so that this script will be executed automatically ever day at 2:00 AM:</p>
<pre><code>crontab -e
0 2 * * * ./path/to/daily.backup.cron
</code></pre>
<p><code>ESC</code>, <code>:wq</code>, <code>ENTER</code> to save your changes and install the new crontab. And that’s it! Automated daily MySQL backups using Dropbox on CentOS. Whew! A couple of things to note before you head off into the sunset:</p>
<ul>
<li>If you have a large number of databases, doing <code>-—all-databases</code> in your mysqldump command may not be the best idea. Consider doing a series of separate crontabs for each database.</li>
<li>Be sure to run this script at an off-peak time of day for your site — it will take a considerable amount of your system’s resources to dump your databases, and then Dropbox will use quite a few sending it off to their servers.</li>
<li>DON’T link the Dropbox account for the server to one that is constantly receiving files (especially large ones), otherwise you’ll be using a lot of inbound bandwidth getting files that the server doesn’t really need — you want this to be mostly a one-way connection.</li>
<li>Keep in mind that when Dropbox syncs the backup, it will use your server’s bandwidth to do so. If you’re syncing a 300-MB file every day, that can get expensive!</li>
</ul>
<p>Hope that it works out well for you!</p>