fogbound.net




Fri, 9 Dec 2011

DSL and Red Herrings

— SjG @ 6:33 pm

On Wednesday, December 7th, at 8:15 AM Pacific Standard Time, the Internet died.

That is to say, the DSL at home went down. No packets in, no packets out. Out in my “machine room,” the modem blinked its lights in a baleful hey I’m trying to sync dance. The usual tricks failed: rebooting, power cycling, yelling obscenities. From work, I could tracert down to what looked like one hop from my system, so I figured it was another blade needing a reboot in the local Covad DSLAM.

I called my ISP’s tech support, and, after the requisite delays, got escalated to a Tier 2 guy who walked me through more tests. He could see my modem, he said, when he did the line test, but it wasn’t syncing. I didn’t realize that that was possible, but I guess it’s not too surprising that one could test a circuit for connectivity on the physical level rather than the network level (as I try to remember the TCP/IP 5- or 7-layer reference model). The Tier 2 guy said that, at this point, it looked like interference on the copper lines in my house. To test, he had me plug the DSL modem into another phone jack in another part of the house. Lo and behold, it worked! I took the modem back out to my machine room, and the sync failed.

Problem isolated! I had originally done the phone wiring out to the machine room myself when we moved into the house in 2000, using two of the wires in a spare Cat-5 cable and a crimped-on 6P2C (“RJ-11”) connector. I figured that the easiest place to start would be to replace the connector, so I lopped off the old one, crimped on a new one, and tested. Voila! it worked. Great Moral Victory, etc.

On Friday, December 9th, at 8:15 AM Pacific Standard Time, the Internet died.

WTF? The DSL at home was down again. The modem would keep its I’m a well-adjusted, happily-synced modem lights lit for about ten seconds, then fall into sync-seeking mode again. What was it about 8:15 AM? That was an hour or so after the door to the machine room was opened to the outside (the cat lives in there along with the machines). The door doesn’t impinge on the phone wire at all. Could there be a temperature component to the problem? Hm. The litterbox is right up against the wall where the conduit passes. Was Quackie micturating on the circuit? No evidence to support this theory could be found. What, then? Alas, it looked like I’d have to attack the phone wiring again.

This time, I went out to where the wires enter the house. I opened the access box, and made sure the connectors were properly attached. I cleaned everything up, and went to test. No luck. But now, the modem wouldn’t sync on any jack in the house.

So it was back out to the access box, and removing all of the connections. There were a few phone lines connected that go to unused jacks in the house. Maybe degradation of copper or oxidation in one of those jacks was enough to cause my problem. So I used my connection tester, and mapped all of the lines. I disconnected two unused jacks. I neatly redid the connectors for all of the active phone lines, and put it all back together. I went back in and tested. Hey! I’ve got sync! But when I plugged a computer in to test that I was getting a good connection, the LAN circuit of the modem dropped, and it went back to trying to sync. Crap.

Next, I ran an extension cord out to where the phone lines come into the house. I opened the access box, removed all the connectors, and patched the modem directly into the incoming phone line. Hey! I’ve got sync! But once again when I plugged a computer in to the LAN circuit, the modem dropped the LAN connection and lost sync. At this point, my suspicion was that the modem itself was failing somehow.

OK, time to call tech support again.

This time, I get an agent who listens patiently to my diatribe and all of the problem symptoms without saying anything. When I let him get a word in edgewise, he starts his script at the very beginning. “What kind of modem are you using?”

“It’s a D-Link 2320b”

“And what lights are lit?”

I launch into a long description of the sync/no-sync dance sequence.

“Please tell me exactly what lights are lit and what color they are.”

This, of course, is ridiculous, since the power and status lights have red LEDs and the LAN, USB, and sync lights have green LEDs, but I play along.

“The power light is red? It should be green.”

At this point, I am doing everything I can to avoid sighing with disgust, cursing the idiot, or flinging my phone. He asks me to plug the modem into the power supply from my router (without asking make/model or any other details). I verify for myself that they’re both 12VDC devices, and do as he asks.

“What color is the power light?” he asks me again.

It’s still red, of course. The modem is doing its I’m desperately trying to start up and get synced dance, and it gets momentary sync. Then the power light changed from red to green. And the modem stayed in sync.

Once I had recovered my composure, thanked tech support, and closed the ticket, I checked the modem power supply. It was putting out 7.4VDC (although I didn’t test it under load). It was rated for 12VDC. I was flabbergasted that it lit any LEDs at all when operating at 60% voltage, much less tried to sync.

Grabbing a 12VDC wall-wart from the box of spares, I put everything back together, and the Internet lives again!

For now, anyway…


Fri, 11 Nov 2011

Imaginary Tech Conversation

— SjG @ 3:14 pm

Coder #1: Man, revision control sucks.
Coder #2: What? Are you insane?
Coder #1: Insane? I don’t think so.
Coder #2: How can you say revision control sucks, then?
Coder #1: Well, I’m stuck using SVN.
Coder #2: Subversion isn’t so bad. Especially with the new merge tracking stuff from version 1.5. It’s pretty easy to use.
Coder #1: Yeah, well, I stand by my assertion. It sucks.
Coder #2: Can you be more specific?
Coder #1: Have you tried using SVN in a mixed environment? Say Windows, Linux, and Mac OS?
Coder #2: It’s not going to be line-ending issues. Oh, I see. You’re talking about case-sensitive versus case-insensitive filesystems.
Coder #1: I wish it was that easy. That’s crappy, but you can work around it.
Coder #2: Then?
Coder #1: A riddle for you. When is UTF-8 not UTF-8?
Coder #2: Huh?
Coder #1: When it’s in a filename.
Coder #2: [clicks, reads]
Coder #1: But I guess if you don’t have any Macs or ZFS around, you’re fine.
Coder #2: Holy Linus on a unicycle! Well, I guess it’s back to dated tar files…
Coder #3: Use GIT, you IDIOT!


Fri, 21 Oct 2011

Using PHPExcel with Yii

— SjG @ 2:18 pm

I was running into problems with conflicting autoloaders when I tried to use PHPExcel with the Yii framework. There are instructions out on the web on how to resolve this, but they are only useful if you’re not creating instances of Yii active record models while you’re using PHPExcel. That’s fine if you’re using Yii to create an Excel spreadsheet from already instantiated Yii classes, but my need is to read an Excel spreadsheet and import its data into my database.

It turns out that this is fairly straightforward as well. The trick is in realizing that PHPExcel is registering its autoloader when it’s instantiated, so you don’t need to register it yourself.

public function actionImport()
  {
  $message = '';
  if (!empty($_POST))
     {
    $file = CUploadedFile::getInstanceByName('import');
    $spec = Yii::app()->basePath.'/data/imports/'.$file->name;
    $file->saveAs($spec);
    spl_autoload_unregister(array('YiiBase','autoload'));
    require(Yii::app()->basePath.'/extensions/phpexcel/Classes/PHPExcel.php');
    spl_autoload_register(array('YiiBase', 'autoload'));
    try {
         $inputFileType = PHPExcel_IOFactory::identify($spec); 
         $objReader = PHPExcel_IOFactory::createReader($inputFileType);  
         if ($inputFileType != 'CSV')
            {
            $objReader->setReadDataOnly(true);
            }
        $objPHPExcel = $objReader->load($spec); 
        $objWorksheet = $objPHPExcel->setActiveSheetIndex(0);
        $highestRow = $objWorksheet->getHighestRow();
        for ($row = 1;$row < $highestRow+1; $row++)
             {
             $myObjThing = new MyObject; // Yii AR model
             $myObjThing->someField = $objWorksheet->getCellByColumnAndRow(1, $row)->getValue();
             $myObjThing->otherField = $objWorksheet->getCellByColumnAndRow(5, $row)->getValue();
             $myObjThing->save(false);
             $myObjThing->detachBehaviors(); // PHP < 5.3 memory management
             unset($myObjThing);
             }
        }
    catch (Exception $e)
       {
       $message = 'There was a problem handling your file. Technical details: '.$e->getMessage();
       }
    if (! empty($message))
       {
       Yii::app()->user->setFlash('error',$message);
       }
    }		
  $this->render('import');
  }

Pretend WordPress didn’t hose the formatting on that …


Tue, 18 Oct 2011

Publishing Old Projects

— SjG @ 9:52 pm

I’ve been publishing a bunch of old projects that I may have posted here, or simply left on my hard drive to suffer the slings and arrows of outrageous bit-rot. Most of these are projects that I created for some specific purpose or another, and have either coded to the point where I’m satisfied with them, or abandoned them.

I’m publishing this stuff in the hopes that it’ll be useful to somebody somewhere. In some cases, the code’s primary use may be as an example of how not to accomplish a task. In other cases, they’re projects that are being used in mission-critical operations, and so are reasonably robust.

I’ll be maintaining them on GitHub, if you want to get creative with the definition of “maintaining.”


Sun, 25 Sep 2011

Photoshop scripting with Javascript

— SjG @ 6:41 pm

I’ve played with the Javascript interface to Photoshop for a couple of years. Conceptually, it’s great — a simple, powerful, interpreted language like Javascript, with an API to interface to one of the best image-processing packages available. In practice, it’s not as good as it is in concept, but it’s still pretty good. The API doesn’t include all of Photoshop’s functionality directly, and there are a lot of things you need to execute as fairly obscure event actions. These event actions aren’t documented, but can be determined by activating a plug-in which logs everything that you do using the Photoshop GUI — you can then read through these logs, and copy the actions you need.

Still, there are some real advantages to using this Javascript interface, as opposed to something designed for the purpose like, say, Processing. You can use the Photoshop UI for controlling inputs to your script (set foreground colors, select portions of the image, select specific layers, etc.), and output your manipulations directly into Photoshop layers.

I’ll be posting here shortly a library I’ve created for easily building dialog panels for setting script options. I find that most manipulations I want to do have a set of variables, and I’d rather not tweak the code each time I want to change them.

This library was originally written under Photoshop 10 (aka CS3). Under version 11 (aka CS4), it was less stable. Sometimes it would crash out at odd places complaining that I was referencing properties of undefined objects. Because there have been memory leaks and other issues with the Javascript interpreter, these seemingly random failures were annoying but not too surprising. When it came to version 12 (aka CS5), I was rarely able to run my scripts at all. What made it frustrating was the apparent randomness of the crashes. I could print a variable to the console, and the very next line would crash out with an “undefined object” error when referencing that variable.
To make a long story short, I was able to track down the issue. It turns out that in iterations, declaring variables matters. That is to say:
for (i in someCollection)
{
$.writeln(i['someAttribute']);
}

will cause random crashes, but
for (var i in someCollection)
{
$.writeln(i['someAttribute']);
}

runs beautifully. Now, I “knew” that the var keyword is optional and used for specifying scope, but I never had any idea that there could be an issue within the scope of a simple loop. Obviously, Javascript didn’t know that I intended i to be a variable on each iteration — perhaps it thinks I meant for i to be a 1957 Chevy Belair on some iterations.

In any case, having cracked the code as it were, I have proceeded to enhance and add to my library. After a little more testing, I’ll be posting it here or on GitHub.