Monthly Archives: November 2006

The Inland Empire CFUG is back!

Charlie Griefer is getting the band back together so to speak. He’s starting up the Inland Empire ColdFusion Users Group (website forthcoming) out in Redlands. I’m glad to see the IE getting UG love again. SoCal in general, for that matter. It seems the OC CFUG doesn’t exist, the umbarella SCCFUG is gone, I think LA might still be going, can’t recall. It’s cool that Charlie is getting it going again.

While I’m no longer in CA, I signed up on the Google Group, you should to! And in January you should be in Redlands for his first meeting.

You go Charlie! Good luck!

Last entry in BlogFusion, and hello BF 2 BCFC migration tool

Well as I mentioned a few days ago. I’m moving from BlogFusion to Ray’s BlogCFC. BlogFusion has a lot of nice features that it looks like I’m gonna have to build in BlogCFC, however that building of Pods, will be much easier than modding BlogFusion has been.

I spent a good part (most of it) working on this migration tool. It’s based on Sean’s tool for migrating from BlogCFC to Word Press. I was gonna write a SQL script with cursors and all kinds of SQL’y jiggy’ness, but then was inspired by Sean’s app. So I figured I’d give a little something back. So I hearby announce that you can now download the BlogFusion 2 BlogCFC Migration Tool starting today.

It’s rough for sure. I’m sure it doesn’t do everything for everybody. But it doe get the heavy lifting done, moving from blogfusion to blogCFC.

I’ll be tweaking it shortly since right now it moves over data from blogfusion that isn’t supported in blogCFC; links, other blogs (blogs I read), personal data (ie, I’m reading X), hot topics (I never knew what these were even in BF). So right now, you get the data migrated but there’s no interface for manipulating the data. Soon though :)

Here’s the nitty gritty instructions. instructions.txt (included) goes deeper.

  1. install blogCFC
  2. unzip the BF2BCFC migration tool
  3. modify the config.ini file to match your setup.
  4. run the included SQL script (this adds tables to blogCFC for the blogfusion data i mentioned above)
  5. modify index.cfm as needed to suit your needs (it should work out of the box, unless your BF install is pretty customized)
  6. run index.cfm

That’s it. You’re done. I HIGHLY recommend you run this in dev once or twice, to make sure it works as you expect before moving it to prod… Just in case.

I’ll be eating my own dog food in prod sometime this week. but I’ve run this in dev a few times now, so far so good. johnwilker.com v2 looks… well it looks just like blogcfc.com

BlogFusion -> BlogCFC

Well I DL’ed the latest rev of Ray’s BlogCFC this week, I’ll probably start figuring out how to migrate from BlogFusion to BlogCFC (So not looking forward to this.)

The Reason… This.
I can’t fault Jake for selling the project off, as side projects go BlogFusion seemed like a big one. What I do fault is the new owners choice to kill the product.

There was a post indicating that the source would no longer be free, it’s now gone. In cruising around, trying to figure out the current status of blogfusion I found this page. Click the link for "BUY THE CODE" it’s very informative :-|

I can only surmise from the lack of updates on the blog itself, and the lack of information

"For information on pricing, please drop an email to the new project leader, Dave."

on the site regarding pricing or Downloads, or anything that Dave and company have scuttled BlogFusion, or at least have decided it’s not worth any serious effort to keep alive.

I initially thought I’d just modify the existing 4.x code, as I have that right since I paid Jake for it, but then thought to myself, why keep using this product that seems to be dead? Why keep propping it up, when no new features are on the horizon? Ray updates blogCFC it’s open too, and more people seem to be expanding it. no offense to Jake, and I wouldn’t want to even try, but the 4.x code is a bit hairy in places.

I was really hoping 5 would solve all my worries, but that doesn’t seem to be in the cards. So in the next few weeks (I hope) I’ll be moving all three blogs (this, this, and this) to BlogCFC

Flex Logging Framework

So I’ve recent;y been tasked with building up an interface for the Flex logging framework… Which surprisingly wasn’t that hard. I learn by example, so the Flex language reference was completely useless. The provided example is completely whack IMO. extending a button to log? yeah that’s helpful in real world needs.

I’ve been working on refining it with the Esria chaps, but thought I’d share my simple little example.

So Flex has a whole logging framework inside it, which is great, and pretty darn easy to implement. I wrote this little example to help me test my understanding of it, as well as test different approaches. You can view the output, here. Not very flashy I know, but…

I created my own webservice debug target by extending the lineformatted target.

Let’s see the code.

This is my simple little MXML witha  button on it.

<mx:Script>
    <![CDATA[
        import mx.logging.LogEvent;
        import mx.logging.LogEventLevel;
        import as_files.logManager;
       
        public function logTester():void
        {
            var testTarget:String = "WebService";
            var testCategory:String = "John";
            var testEvent:LogEvent = new LogEvent();
             //We create a log event to hold our level and message.
            testEvent.level = LogEventLevel.INFO;
            testEvent.message = "ACK";
           
             //create an instance of my log manager (see code below) and call it's logger function
            var writeLog:logManager = new logManager();
            writeLog.Logger(testEvent, testCategory, testTarget);
           
        }
       
    ]]>
</mx:Script>

<mx:Panel label="test">
    <mx:Button label="click me" click="logTester()"/>
</mx:Panel>   

This is the logmanager class.

package as_files
{
    import flash.events.Event;
    import mx.logging.Log;
    import mx.logging.LogEvent;   
    import mx.logging.ILogger;
    import mx.logging.targets.TraceTarget;
    import mx.logging.targets.MiniDebugTarget;
    import mx.logging.targets.LineFormattedTarget;
    import mx.logging.ILoggingTarget;
    import as_files.WebServiceTarget;
   
    public class logManager
    {
        //Use this as a model for my functionality.
       
       
        //Handle categories

        public function Logger(L:LogEvent, category:String, target:String):void
        {
            var myTarget:ILoggingTarget;
            //I made a switch so that I could select the target myself based on my need. One line of code could write to a webservice, another might just write to trace.
            switch(target)
                {
                     case ‘Line’:
                        myTarget = new LineFormattedTarget();
                        break;
                     case ‘MiniDebug’:
                         myTarget = new MiniDebugTarget();
                        break;
                     case ‘WebService’:
                         myTarget = new WebServiceTarget(‘http://www.red-omega.com/DummyLoggingWS/webservice.cfc?wsdl’, ‘Listener’);
                        break;
                     //Trace will be default
                     case ‘Trace’:
                         myTarget = new TraceTarget();                        
                        break;
                     default:
                         myTarget = new TraceTarget();
                        break;
                }
               
            var myLogger:ILogger = Log.getLogger(category);           
           
            //You can filter your target on specific categories.
            myTarget.filters = [category];
            myTarget.level = L.level;
            //myTarget.addLogger(myLogger);
           
            //Add my target to teh logging system so when logs like what I am looking for arrive they are directed to the right place.
            Log.addTarget(myTarget);
       
            //handle the log level
            //It seems that the default behaviour is to log the selected level and those below. For my test I didn’t want that so I simply limited it.
            switch(L.level)
            {
                case 0:
                    myLogger.log(L.level, " GENERAL:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    break;
                case 2:
                    if (Log.isDebug()) {
                        myLogger.debug(" EVENT:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    }
                    break;
                case 4:
                    if (Log.isInfo()) {
                        myLogger.info(" INFO:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    }
                    break;
                case 6:
                    if (Log.isWarn()) {
                        myLogger.warn(" WARN:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    }
                    break;
                case 8:
                    if (Log.isError()) {
                        myLogger.error(" ERROR:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    }
                    break;
                case 1000:
                    if (Log.isFatal()) {
                        myLogger.fatal(" FATAL:   " + L.target + ":" + L.type + ". Message is: ‘{0}’", L.message);
                    }
                    break;
            }           
        }
       
        //Handle targets.
       
    }
}

The last little bit of code is my WebServiceTarget. All it does, you’ll see at the bottom is extend the lineformattedTarget and call a webservice with a block of text to be written. Presumably to a log file on a remote sever in siberia.

package as_files
{

import mx.rpc.soap.mxml.WebService;
import mx.core.mx_internal;
import mx.logging.targets.LineFormattedTarget;
import mx.rpc.AbstractOperation;

use namespace mx_internal;

/**
 *  Provides a logger target that outputs to a <code>LocalConnection</code>,
 *  connected to the MiniDebug application.
 */
public class WebServiceTarget extends mx.logging.targets.LineFormattedTarget
{

    //————————————————————————–
    //
    //  Constructor
    //
    //————————————————————————–

    /**
     *  Constructor.
     *
     *  <p>Constructs an instance of a logger target that will send
     *  the log data to the MiniDebug application.</p>
     *
     *  @param connection Specifies where to send the logging information.
     *  This value is the name of the connection specified in the
     *  <code>LocalConnection.connect()</code> method call in the remote SWF,
     *  that can receive calls to a <code>log()</code> method with the
     *  following signature:
     *  <pre>
     *    log(… args:Array)
     *  </pre>
     *  Each value specified in the <code>args</code> Array is a String.
     *
     *  @param method Specifies what method to call on the remote connection.
     */
    public function WebServiceTarget(service:String, method:String)
    {
        super();
        _ws = new WebService();
        _service = service;
        _method = method;
    }

    //————————————————————————–
    //
    //  Variables
    //
    //————————————————————————–

    /**
     *  @private
     */
    private var _ws:WebService;
   
    /**
     *  @private
     *  The name of the method that we should call on the remote connection.
     */
    private var _method:String;

    /**
     *  @private
     *  The name of the connection that we should send to.
     */
    private var _service:String;

    //————————————————————————–
    //
    //  Overridden methods
    //
    //————————————————————————–

    /**
     *  @private
     *  This method outputs the specified message directly to the method
     *  specified (passed to the constructor) for the local connection.
     *
     *  @param message String containing preprocessed log message which may
     *  include time, date, category, etc. based on property settings,
     *  such as <code>includeDate</code>, <code>includeCategory</code>, etc.
     */
    override mx_internal function internalLog(message:String):void
    {
       
        _ws.loadWSDL(_service);
        _ws.useProxy = false;
       
        //_ws.addEventListener("result", wsLoginResult);
        //_ws.addEventListener("fault", wsLoginFault);
              
        var op:AbstractOperation;
        op = _ws[_method];
              
        var args:Object = new Object();
          
        args.LogData = message;
       
              
        op.arguments = args;
        op.send();
        //_lc.send(_connection, _method, message);
    }
}

}

I don’t for a second think that there aren’t better approaches, this is beta .01 of my logging attempts. It works and it shows how the built in logging functionality does what it does.