It's been a while since I've blogged, because of a short term overload of things to do, putting in full time at a client's, and also taking a business class at the CC. Yes, business. It was a little bit of a shock to my anarcho-socialist mind to learn that most of the ideas we hold aren't different from the ideas taught in biz school... it's the "masses" who are uninformed about it... and it's only the anarcho-socialistic types who think something is wrong with the way things are. The biz class attitude is to just get yourself on top of the pyramid, and hope to avoid a revolution. I suspect biz school is also a leading vehicle for teaching the finer points of shady business practices and political corruption, but I can't be sure of this.
What I was hoping for were lessons on accounting and standard business practices, negotiation, and laws. Being an intro class, though, none of that was being taught. So, I'll have to just take some specific classes for those things. What was taught: money, organization, government, marketing. It's just basic capitalism, and as enlightening as sitting through an intro to Marx, Weber, or Gramsci. The book was okay, but was biased in favor of business, and also had some factual errors. The factual errors kind of killed it for me.
This is a Perl version of the VB FileMirror class shown earlier on this site. The class helps you write scripts to (semi) safely mirror or move a file system from one directory to another. It does this by building the correct destination paths, making destination directories, and deleting files only after they appear to have been copied over.
Docs are in FileMirror.txt, attached.
DriveGMover.pl is a script that uses the class.
This is a first draft of some classes to manipulate .htaccess and htdigest files. I'm putting it up because there aren't many classes to do this, and seemingly none for htdigest files. (I just learned about the PEAR::Config classes. Neat.)
HTAuthFile is a superclass with a common writer. HTAccessFile is a very incomplete way to manipulate Apache .htaccess files. It is basically incorrect, because it doesn't support those <Scoping things> in Apache config files, and it doesn't take into account the order of directives, and it doesn't deal with using the same directive mulitiple times, but it will do for writing simple files to enable directory passwords. It's at times like this, I wish Apache used XML for the config format... but, this is the only time I've really had that feeling.
This is a class that will help you find files on the disk, without hitting the disk too much. It's a simplified unix "slocate" library. The first time you use it, it creates an index of all the files on the drive. (Subsequent uses update the file when a day passes.) The index is loaded into memory, and searched with regular expressions.
On an AMD Sempron 2000, the first search on 200,000+ files takes around 11 minutes. The second search takes around 2 seconds, and subsequent searches during a single run take around 1 second each. The first run builds the database, and the subsequent searches use it.
I thought there'd be a whole system to deal with the bad files, by now, but my attention shifted to understanding ESRI datasets. Spot checks on the copied data indicated that there were a fair number of datasets used, and they weren't copied over. The topic seems to be involved, and there's a lot to read.
Datasets are basically databases. They're referenced indirectly, via a driver of some kind, and the driver, rather than the app, manages the data files. I suspect there's going to be a serious problem with these, because I was unable to navigate to a missing dataset via the UI. I'd click on the "Set Datasource" button, and a dialog would pop up, but clicking around the interface never seemed to bring up any data.
Chances are, data sources need to be mounted at the workstation before I can navigate to them.
This blog entry doesn't discuss any code, because I ended up doing very little work on the software. I was busy running it, and the app tends to take over the UI, making programing difficult. For the most part, it functioned as expected, but a couple things changed in how I actually used it.
I added a text box to restrict scanning for MXD files to a subdirectory. This new feature allowed me to set the source root and destination root directories, and then type the subdirectory to be processed. The text box could also be left blank.
I used this feature a lot.
The main feature I stopped using was the scheduler. The software was so slow that it failed to use the network 100%. The point of having the program pause at night was to let backups happen faster, to avoid competing for the network.... but since the job appeared to be CPU-bound, I had was a big disincentive to be a good network citizen. The most efficient thing to do was let the app run all the time, even if it impacted the network -- every time the app was "nice" to the network, the length of time to complete it's task would grow by that amount plus the additional CPU time it took to complete the task.
It was looking pretty grim for the file copier. The main problems were twofold:
First, the app sometimes crashed on bad data. The Windows crash-reporting dialog box came up, and all work stopped until it was dismissed.
Second, after dismissing the dialog box, the app looped furiously, failing to process the remaining files, but marked them as completed (that's a little design bug there). The problem was that the COM server was returning an exception, and it was being trapped and effectively ignored. I say "effectively" because a special call to kill the app, via WMI, didn't clear the problem -- the underlying COM server didn't get stopped and unloaded.
The error could be cleared if I paused the batch job, and restarted it. That caused the thread that communicated with the COM server to abort, thus (probably) releasing the COM server. If only this could be automated.
I'm finally running that program I've been writing. For the most part, it was "bug free" inasmuch as the different parts ran their test cases correctly, and it runs fine on a small subset of data. Of course, it's not like I ever really learned the system completely, so there are a lot of situations that I'm not handling (or even aware of). Moreover, because the users probably don't use all the features of the software, it's not likely that a complete solution is necessary. No project is debugged "enough" until it operates on real data, in a real situation. Fortunately, my first iterations were done in Perl and VBA, in a scripting environment, on real data, so my experiences debugging those determined the overall structure of the code -- that is, the code deals with messy situations.
It's going to be a lesson about recursion. It's strictly beginner level.
The following code is a hack to alter a Drupal layout to use two columns. It does this without going into the Drupal code. Instead, it alters the layout of the content, using "float" and "width" to turn a one-column layout into two.
Doing this is pretty easy. First, you get a reference to the content area, then use that to get an array of DIVs within that area. All DIVs are returned. Each DIV is inspected to see if its class is "node". If so, the layout is altered.
Here are three Mac-style busy indicators, or spinners, running at three speeds.
This article discusses debugging a function by rewriting the code.
I'm not sure what I did wrong here, but, my first version of this function didn't work. The function returns true if the current time is withing two time spans. This code was written in a rush, without really thinking about how to do it, because it seemed pretty straightforward. The code, however, was a mess (and embarassing).
Private Function itIsTimeToWork() As Boolean ' Get the two start and end times, and determine if we're within ' the intervals. Dim now, start1, start2, end1, end2 As DateTime now = DateTime.Now start1 = DateTime.Parse(My.Settings.StartWorkAt1) end1 = DateTime.Parse(My.Settings.EndWorkAt1) If end1 < start1 Then
I had this weird problem with implementing a folder-based plugin architecture. Each plugin had a config file, and at the top was this:
$menu = new ApMenu( $acl, 'INFO', 'Your Info' ); $menu->addUrl( $acl, 'Help/FAQ', '', 'Information about the Slaptech server.' ); $menu->addUrl( $acl, 'My Account', '', 'Your financial situation with Slaptech.' ); $menu->addUrl( $acl, 'Disk and Data Usage', '', 'A summary of stats.' ); $menu->addUrl( $acl, 'phpinfo()', '', 'A page with phpinfo() called.' );
The problem was, to implement security in menus, the user security had to be established before the menu was created. This made the entire menu system a pain in the butt. I just had a "revelation" that I could do away with some of my problems by specifying menus as XML instead:
For some reason or other, I didn't get an email response from the client on this gig*, and the week was hectic, so instead, I just worked on making the UI a little nicer. VB has a lot of controls, including a background threader, some standard dialogs, and a serial port. This is giving me a real "Rip Van Winkle" feeling, having been over in Unixville for a while.
(* It was lost in my huge email pile. My bad. No matters... the program got a nice facelift.)
I downloaded a bunch of code examples, and started looking through them. The second volume had some interesting programs. One thing hasn't changed about VB - you have to type a lot of code to get a little done. At least that's still true if you're writing algorithmic code... and clearly, C#'s job is to write that algorithmic code.
I had some personal errands to run and didn't end up doing enough programming work. It was mostly digesting the material on the Sams site, which has a surprising number of very good sample chapters out. I had forgotten about Sams, and for a while, didn't think they were very good, but their editorial quality is very high now. O'Reilly and Apress had better watch out.