Notice: Array to string conversion in system/classes/rewriterule.php line 112 http://ryezone.net/luce-line-trail" title="Luce Line Trail">Luce Line Trail

So today I am off exploring the Luce Line Regional Trail. This is part curiosity and part research as I want to see how much of this trail is paved and what condition it is in before we decide to use it for a team ride in preparation for the MS 150.

The route for those who are not familiar with this trail: Click Here

I will update this post later with my reflections on the route.

Reflections on the route:

The Luce Line Regional Trail is a spectacular ride. The wooded scenery keeps the trail relatively cool, even on an 80 degree day. The trail is paved from Theodore Wirth Parkway to Vicksenburg Lane in Plymouth, and crushed limestone all the way to Watertown. The crushed limestone is going to eat about 5 mph from your cruising speed, so bring plenty of water. One other slight disadvantage of the crushed limestone is that after a decent rainfall, some parts of the trail still have standing water on the trail. I would suggest waiting a couple days after a rainfall to let the trail dry out.

That being said, it was the reason I elected to stop in Lyndale rather than continue on to Watertown. While in Lyndale, I stopped at the Ox Yoke Inn and had their Luce Line Lucy burger. This little piece of heaven consists of a half pound patty, grilled to order, smothered in bleu cheese and topped with bacon and your choice of fried or raw onions. It will run you about $13 with fries and a bottomless glass of fresh squeezed lemonade. If you have the time, I highly recommend stopping to enjoy this tasty part of the trail.

Notice: Array to string conversion in system/classes/rewriterule.php line 112 http://ryezone.net/using-the-sql-xml-bulk-loader-to-load-xml-tables-into-sql-server-2008-express-r2" title="Using the SQL XML Bulk Loader to load XML tables into SQL Server 2008 Express R2">Using the SQL XML Bulk Loader to load XML tables into SQL Server 2008 Express R2

As part of my job, I have to load data from various data sources into SQL Server. I recently had to load data from a well defined XML export into a SQL Server 2008 Express R2 instance. This is made a little more difficult than usual as the Express version of SQL Server does not include SSIS. It can be accomplished, but you need a few things installed first.

To accomplish this task, the following tools were used:

Once you have the tools installed, copy and paste the xml below into a text editor and save it as C:\Booklist.xml

<?xml version="1.0" ?>
<Library>
	<Books>
		<Title>Mr. Magoo's Big Adventure</Title>
		<Author>Mr. Magoo</Author>
		<Volume>1</Volume>
		<PublishDate>2002-05-30T09:30:10-06:00</PublishDate>
	</Books>
	<Books>
		<Title>The FooBar Chronicles</Title>
		<Author>The Bug Master</Author>
		<Volume>1</Volume>
		<PublishDate>2010-05-30T09:30:10-06:00</PublishDate>
	</Books>
	<Books>
		<Title>Adventures in SQL Land</Title>
		<Author>Commander Data</Author>
		<Volume>1</Volume>
		<PublishDate>2009-05-30T09:30:10-06:00</PublishDate>
	</Books>
</Library>

Now that we have an XML file to import, we need a table to import it to. Copy and paste the following query into your SQL Server Management Studio window and execute it.

CREATE TABLE Booklist (
	 Title varchar(25)
	,Author varchar(14)
	,Volume int
	,PublicationDate DateTime
)

Once we have somewhere to put the data, we need to tell SQLXML how to put it there. Copy and paste the following XSD into a text editor and save it to C:\Booklist.xsd

<?xml version="1.0" standalone="no" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:element name="Books" sql:relation="Booklist" type="Books_type">
     <xsd:complexType name="Books_type">
           <xsd:element name="Title" sql:field="Title" type="xsd:string"/>
	   <xsd:element name="Author" sql:field="Author" type="xsd:string"/>
	   <xsd:element name="Volume" sql:field="Volume" type="xsd:integer"/>
           <xsd:element name="PublishDate" sql:field="PublicationDate" type="xsd:dateTime" sql:datatype="dateTime"/> 
     </xsd:complexType>
  </xsd:element>
</xsd:schema>

The sql:relation attribute in the Books element defines which table the data will be loaded into. The value of this attribute must match the table name in SQL Server. The sql:field attribute in the Title, Author, Volume, and PublishDate elements defines which column in the SQL Server table the data will be placed into. Note that it is not necessary to have the sql:relation and sql:field attributes be the same as the name attribute of the element. This allows you to map the data to a completely different structure than the original XML file. Also note, that the PublishDate element has an additional attribute sql:datatype. The sql:datatype tells the XML Bulk Loader what SQL Server datatype it should use when converting the incoming data.

Lastly, we need a script to connect to the database and call the XML Bulk Loader. Copy and paste the following code into a text editor and save it to C:\ImportBooklist.vbs

set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkLoad")
objBL.ConnectionString = "Provider=SQLOLEDB;Data Source=HostName\InstanceName;Initial Catalog=DatabaseName;IntegratedSecurity=SSPI"
objBL.ErrorLogFile = "C:\error.log"
objBL.Execute "C:\Booklist.xsd", "C:\Booklist.XML"
set objBL = Nothing

Change the HostName to the name of the computer hosting your SQL Server Express instance. Change the InstanceName to the name of the SQL Server Express instance hosting your database. Finally change the DatabaseName to the name of the database that holds the table where you want to put the data. The connection string provided above uses Windows Authentication to connect to the database. If you wanted to use standard SQL Server Authentication, your connection string would be:

objBL.ConnectionString = "Provider=SQLOLEDB;Data Source=HostName\InstanceName;Initial Catalog=DatabaseName;User Id=myUsername;Password=myPassword"

Once you have made your edits, you should be able to double-click your C:\ImportBooklist.vbs file and the data will load into the table specified.

A few of the links that I found helpful:

SQLXML.org
SQLXML.org How To: Insert datetime values that are in xsd:dateTime format

MSDN: Introduction to Annotated XSD Schemas (SQLXML 4.0)
MSDN: How to import XML into SQL Server with the XML Bulk Load component

XML xsd:dateTime not correctly importing with SQLXMLBulkLoad

ConnectionStrings.com: SQL Server 2008 Connnection Strings

Hope this quick example helps someone.

Notice: Array to string conversion in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
Notice: Object of class HabariDateTime could not be converted to int in system/classes/rewriterule.php line 112
http://ryezone.net/death-to-habari-comment-spam" title="Death to Habari Comment spam.">Death to Habari Comment spam.

I love Habari, It has moderated every scum comment spammer that has approached my blog. For some reason they all seem to be fixated on this post. On occasion though, some of them fall through the SPAM filter and the DNS black lists into my Unapproved moderation bin. As much as I want to know about the next poker or porn site, I decided to investigate captcha technology. My search as thus far landed on the Habari Captcha Plugin by Eugene Wee. It didn't work quite right out of the box for me, so here's how I hacked it to work.

First, you need to create an XML for the plugin if Habari tells you the admin screen won't load the plugin without one. Here's the code:

<?xml version="1.0" encoding="utf-8" ?>
<pluggable type="plugin">
  <name>Captcha</name>
  <license url="http://www.opensource.org/licenses/afl-3.0.php">Academic Free License version 3.0</license>
  <author url="http://www.aranel.net">Eugene Wee</author>
  <version>1.0b3</version>
  <url>https://launchpad.net/habari-captcha</url>
  <description><![CDATA[Automatically approve comments that pass CAPTCHA.]]></description>
  <copyright>2008 Eugene Wee <crystalrecursion@gmail.com></copyright>
  <help>
    <value><![CDATA[
      <h3>Introduction</h3>
      <p>
        <ol>
          <li>Unzip the captcha folder to user/plugins.</li>
          <li>Using an editor, appropriately insert this line into your selected theme's
            commentform.php file:<br><br>
            <?php if ( Plugins::is_loaded( 'Captcha' ) ): $theme->show_captcha(); endif; ?>
          </li>
          <li>From your Habari administration panel, activate the CAPTCHA plugin.</li>
          <li>From your Habari administration panel's Configure option, set the reCAPTCHA
            public and private keys. These may be obtained from http://recaptcha.net<br><br>
            If you wish to require the CAPTCHA instead of allowing submitters to leave it
            blank, check the 'CAPTCHA required' checkbox.
          </li>
        </ol>
      </p>      
      <h3>Theme Configuration</h3>
      <p>
        A template (captcha.php) is provided and used by default. To configure this to
        match your theme, copy captcha.php to your selected theme's folder and edit it.<br><br>
        Currently, only the $captcha_script_url variable is made available to the theme.
      </p>
    ]]></value>
  </help>
</pluggable>

Copy and past the code above and save it as captcha.plugin.xml in the captcha plugin folder.

Now that you have the plugin loaded into the admin interface, if you get some PHP error saying that it can't override the info function, comment out the Info function in the captcha.plugin.php file. Commenting is shown below:

<?php
/**
 * Captcha Class.
 *
 * This plugin allows comments to be automatically approved if they pass the
 * CAPTCHA provided by the given provider. If a reader does not attempt the
 * CAPTCHA when posting a comment, his or her comment is added to the moderation
 * queue, unless the plugin is configured to require the CAPTCHA.
 *
 * Currently, the only CAPTCHA provider supported is reCAPTCHA.
 * See the README file provided for more information, including usage.
 *
 * Version: 1.0b3 (tested on Habari 0.5.1)
 * Copyright 2008 Eugene Wee
 * Licensed under the Academic Free License version 3.0
 */
class Captcha extends Plugin
{
  const RecaptchaIndex = 0;
  private $provider = null;
/*
  function info()
  {
    return array(
      'name' => 'Captcha',
      'url' => 'https://launchpad.net/habari-captcha',
      'author' => 'Eugene Wee',
      'authorurl' => 'http://www.aranel.net',
      'version' => '1.0b3',
      'description' => 'Automatically approve comments that pass CAPTCHA.',
      'license' => 'Academic Free License version 3.0'
    );
  }
*/
  function action_init()
  {
    $this->add_template( 'captcha', dirname(__FILE__) . '/captcha.php' );
  }
  function action_update_check()
  {
    Update::add( 'Captcha', '080310f0-41ce-11dd-ae16-0800200c9a66', $this->info->version );
  }
  function filter_comment_insert_allow( $allow, $comment )
  {
    $this->initProvider();
    $allow = $this->provider->check( $allow, $comment );
    if ( $allow ) {
      $comment->status = Comment::STATUS_APPROVED;
      EventLog::log( _t('Comment by ') . $comment->name . _t(' automatically approved.'),
        'info', 'comment', 'Captcha' );
    }
    else if ( !Options::get( 'captcha__required' ) ) {
      $allow = true;
    }
    else {
      // Copied from FeedbackHandler::act_add_comment()
      Session::add_to_set( 'comment', $comment->name, 'name' );
      Session::add_to_set( 'comment', $comment->email, 'email' );
      Session::add_to_set( 'comment', $comment->url, 'url' );
      Session::add_to_set( 'comment', $comment->content, 'content' );
      Session::error( _t('Your CAPTCHA attempt did not succeed. Please try again or leave the CAPTCHA blank.') );
    }
    return $allow;
  }
  function theme_show_captcha( $theme )
  {
    $this->initProvider();
    $this->provider->show( $theme );
    return $theme->fetch( 'captcha' );
  }
  function filter_plugin_config( $actions, $plugin_id )
  {
    if ( $plugin_id == $this->plugin_id ) {
      $actions[] = _t('Configure');
      $actions[] = _t('Choose Provider');
    }
    return $actions;
  }
  function action_plugin_ui( $plugin_id, $action )
  {
    if ( $plugin_id == $this->plugin_id ) {
      $ui = new FormUI( strtolower( get_class( $this ) ) );
      switch ( $action ) {
      case _t('Configure'):
        $ui->append( 'text', 'public_key', 'captcha__public_key', _t('Public key: ') );
        $ui->append( 'text', 'private_key', 'captcha__private_key', _t('Private key: ') );
        $ui->append( 'checkbox', 'captcha_required', 'captcha__required', _t('CAPTCHA required ') );
        break;
      case _t('Choose Provider'):
        $ui->append( 'select', 'provider', 'captcha__provider', _t('Provider: '),
          array( _t('reCAPTCHA') ) );
        break;
      }
      $ui->append( 'submit', 'save', _t('Save') );
      $ui->out();
    }
  }
  private function initProvider()
  {
    if ( $this->provider == null ) {
      switch ( Options::get( 'captcha__provider' ) )
      {
      case Captcha::RecaptchaIndex:
      default:
        require_once 'recaptchaprovider.php';
        $this->provider = new RecaptchaProvider();
      }
    }
  }
}
?>

Once you have commented that function out, you should be able to activate the plugin in the admin interface. After that, all that's left is to make the required modifications in your commentform.php file and sign up for the ReCAPTCHA service which is free. Hope this helps someone.

Notice: Array to string conversion in system/classes/rewriterule.php line 112 http://ryezone.net/regripper-and-internet-explorer-1" title="RegRipper and Internet Explorer.">RegRipper and Internet Explorer.

I was working on a certification exam and I ran across a situation where I needed to find out what a user had set their home page to in Internet Explorer on a Windows XP machine. Seeing as I don't have a license to AccessData's Registry Viewer, I set out to find a free viewer to find the information I needed.

The home page settings for Internet Explorer are found in the NTUSER.dat file of the user account in question under the HKCU\Software\Microsoft\InternetExplorer\Main registry key. RegRipper does not extract this information fresh out of the box, so I had to write a custom plugin. Rather than start completely from scratch, I based this plugin off the user_run.pl plugin provided with the RegRipper program since it did pretty much what I wanted it to do with relatively few modifications.

The following plugin code is fully functional, and will dump the contents of the HKCU\Software\Microsoft\InternetExplorer\Main registry key to the console or a text file. Thanks to Harlan Carvey for developing such a versatile and extend-able tool. To download RegRipper, go to regripper.net.

#-----------------------------------------------------------
# iexplore.pl
#
# copyright 2010 E. Rye  esten@ryezone.net
#-----------------------------------------------------------
package iexplore;
use strict;

my %config = (hive          => "NTUSER\.DAT",
              osmask        => 22,
              hasShortDescr => 1,
              hasDescr      => 0,
              hasRefs       => 0,
              version       => 20100308);

sub getConfig{return %config}

sub getShortDescr {
	return "Get Main Key contents from HKCU\\Software\\Microsoft\\Internet Explorer";	
}
sub getDescr{}
sub getRefs {}
sub getHive {return $config{hive};}
sub getVersion {return $config{version};}

my $VERSION = getVersion();

sub pluginmain {
	my $class = shift;
	my $hive = shift;
	::logMsg("Launching iexplore v.".$VERSION);
	my $reg = Parse::Win32Registry->new($hive);
	my $root_key = $reg->get_root_key;

	my $key_path = "Software\\Microsoft\\Internet Explorer\\Main";
	my $key;
	if ($key = $root_key->get_subkey($key_path)) {
		::rptMsg($key_path);
		::rptMsg("LastWrite Time ".gmtime($key->get_timestamp())." (UTC)");
		my %vals = getKeyValues($key);
		if (scalar(keys %vals) > 0) {
			foreach my $v (keys %vals) {
				::rptMsg("\t".$v." -> ".$vals{$v});
			}
		}
		else {
			::rptMsg($key_path." has no values.");
		}		
		my @sk = $key->get_list_of_subkeys();
		if (scalar(@sk) > 0) {
			foreach my $s (@sk) {
				::rptMsg("");
				::rptMsg($key_path."\\".$s->get_name());
				::rptMsg("LastWrite Time ".gmtime($s->get_timestamp())." (UTC)");
				my %vals = getKeyValues($s);
				foreach my $v (keys %vals) {
					::rptMsg("\t".$v." -> ".$vals{$v});
				}
			}
		}
		else {
			::rptMsg("");
			::rptMsg($key_path." has no subkeys.");
		}
	}
	else {
		::rptMsg($key_path." not found.");
		::logMsg($key_path." not found.");
	}	
}

sub getKeyValues {
	my $key = shift;
	my %vals;	
	my @vk = $key->get_list_of_values();
	if (scalar(@vk) > 0) {
		foreach my $v (@vk) {
			next if ($v->get_name() eq "" && $v->get_data() eq "");
			$vals{$v->get_name()} = $v->get_data();
		}
	}
	else {	
	}
	return %vals;
}

1;

Notice: Array to string conversion in system/classes/rewriterule.php line 112 http://ryezone.net/an-even-shinier-update" title="An even shinier update">An even shinier update

So playing with the new habari 0.6.2 update has been interesting. This new update has provided me with a feature I really wanted, Private Posts. This new feature allows me to restrict certain posts as viewable to only those who are registered and authenticated with the site. Those of you who are regular visitors, if I have any regular visitors, will have to request a username and password from me to see most of my entries. I will still post some entries as non-private, however they will be few and far between and most likely will be either more technical in nature or non-personal.

That being said, if you would like to request a username and password, send me an email at esten@ryezone.net with the subject Habari-Request. Usernames will be granted on a discretionary basis. Meaning, just because you want to have access, doesn't mean you'll get it.

 1 2 Next →

About

User