≡ Menu

Nothing to See Here… Move Along

In my 30-plus years playing and working with computers, I’ve seen some strange things. This may be the first time I’ve actually seen an automated application installer ask me, as part of its “automatic” installation process, to manually copy files from one folder it just created, to another folder it just created.

Kony Studio installer dialog box

Wonders never cease.

The most widely known way (which is also often described as the best way) to learn Ruby on Rails is the Rails Tutorial by Michael Hartl. Its third edition, which covers Rails 4, has been available as both a digital book and video screencasts for several months on Hartl’s Rails Tutorial website, but was just released in print form yesterday. I received mine from Amazon today, and was pleased to find my review (of the Second Edition, though it certainly holds true for the Third even more so!) printed just before the title page.

Quick Fixes on SSIS with Oracle Data Sources

I’m currently in the process of building out an ODS (Operational Data Store) that will integrate data from multiple systems and make that data available for reporting using Spotfire and other BI tools.

Both the ODS DBMS and the first system that will be used as a source for the data in the ODS run on Oracle Database. I am using Visual Studio Ultimate 2013 64-bit to build an SSIS package to flow the data from the source into the ODS.

In debugging the SSIS package, I’ve run into a few things that make troubleshooting much easier. The first thing to know is that the Oracle Database is a 32-bit system. The first thing that must be done after loading the SSIS package into Visual Studio is making sure that the Run64BitRuntime setting is set to False in the project’s Properties box. (This can be found in the PROJECT menu.)

Since the data sources for the ODS are Oracle, the SQL queries used to pull data must conform to Oracle syntax. To prevent things like SSIS automatically adding semicolons to the queries (and preventing me from adding them myself), I set the BypassPrepare property to True. This should allow the query to run the same way in SSIS as it does in SQL Developer. (If this is set to False, SSIS will parse the query rather than passing it to Oracle.) This setting made writing queries much easier, as I could test them in SQL Developer and paste them into SSIS without having to rewrite them to conform to SSIS.

Completing the Core iOS 7 Code School Course Using XCode 6.x

One of the classes that must be completed on the iOS Path for Code School is Core iOS 7. When this course was published, version 7 was the most recent iOS release and the IDE used was XCode 5 from Apple.

This course may be done using XCode 6.x, and most of the exercises will run on the iOS 8/8.1 Simulator that comes with this version of XCode. However, due to some changes between iOS 7 and iOS 8, some of the exercises will successfully compile and run, but the associated tests will fail.

The solution to this problem is that the iOS 7.1 Simulator must be added to XCode 6.x. This is done through XCode Preferences on the Downloads tab. If you are using a MacBook Pro or MacBook Air, make sure that it is plugged in before attempting to download anything through the XCode Preferences interface. If you are running on battery, the download never starts and no error message or warning is given.

Also, before selecting Test in your application, make sure that the active scheme is a device running iOS 7.1. The iPhone 6 and 6 Plus options only run on iOS 8, so choosing “iPhone 5s (7.1)” should work fine.

Errors Related to the Use of CFAJAX Tags in ColdFusion

This is a quick change that is easily missed when adding AJAX functionality to an old ColdFusion site with CFAJAX tags. In my case, I was adding this functionality to a site that had originally been developed about ten years ago. This site runs on a Windows server with IIS.

After getting the site upgraded and working properly in the dev and test environments, I discovered that several errors were happening in prod that never happened in test or dev. The most common of these errors was “Coldfusion is undefined”.

Of all things, the Virtual Directory to CFIDE had never been created. As is so common, major problems can be caused by tiny bugs in code, or in this case, in the Web server configuration itself.

Create a Virtual Directory in the root of the website and name it CFIDE. It should, in most cases, point to C:\inetpub\wwwroot\CFIDE. Once this is done, the CFAJAX errors should be no more!

UPDATE via Gavin Pickin (@gpickin):

Using PHP to Scrape the Report Card from a Code School Profile – Part 2

Earlier this week, I described how to use PHP to scrape the report card from a Code School profile. Now, it must be displayed. I chose to display mine in the sidebar of my blog. To do this, jQuery and CSS will be your friends. It’s pretty simple, and this isn’t the only way to do it. However, in this implementation, it is important that the name of the querystring parameter used in the PHP script (in this case, “nick”) matches the one in the jQuery function call below. Likewise, the id attribute of the div element must also match the one in the jQuery statement.

<style scoped>
#codeschool {
   text-align: center;
   vertical-align: middle;
}

.badge-img {
   height: 110px;
   weight: 110px;
   display:block;
   margin-left: auto;
   margin-right: auto;
}

.pr-avatar {
   display:block;
   margin-left: auto;
   margin-right: auto;
   margin-bottom: 10px;
}
</style>
<div id="codeschool">
</div>
<br />
<script>
(function($) {
$("#codeschool").load("/codeschool/codeschool.php?nick=DeepInTheCode");
})(jQuery);
</script>

Well, that’s it. If you debug the client-side code on both your page and the Code School profile page, you’ll see that there are path elements in the Code School script that cause the partial opacity on uncompleted paths. This is presumably done with other JavaScripts and CSS on the Code School site. I haven’t tried bringing that functionality here as yet. Perhaps for another time…

Using PHP to Scrape the Report Card from a Code School Profile – Part 1

I have been manually placing my Master badges from Code School onto my blog which, being a WordPress blog, runs on PHP. I don’t have the script running that shows the fraction completed on Paths that I haven’t yet mastered, but I can get the ones that I’ve completed.

The PHP script I’ve built so far is below. Due to some CSS I want to change, I haven’t implemented it yet. But I can say that it does indeed scrape the page. The jQuery required to display it in the sidebar I’ll share once I get the CSS issues worked out. This is very similar to the code I used to get the CodeEval profile, but it’s been refactored and modified for use with the Code School page.

<?php
    function getClass($classname, $htmltext)
    {
        $dom = new DOMDocument;
        $dom->loadHTML($htmltext);
        $xpath = new DOMXPath($dom);
        $results = $xpath->query("//*[@class='" . $classname . "']");
        return $results;
    }
    
    
    function buildContent($results)
    {
        $content = "";
        foreach ($results as $node) {
            $partial_content = innerHTML($node);
            $content = $content . $partial_content;
        }
        return $content;
    }
    
    
    /* this function preserves the inner content of the scraped element. 
    ** http://stackoverflow.com/questions/5349310/how-to-scrape-web-page-data-without-losing-tags
    ** So be sure to go and give that post an uptick too :)
    **/
    function innerHTML(DOMNode $node)
    {
      $doc = new DOMDocument();
      foreach ($node->childNodes as $child) {
        $doc->appendChild($doc->importNode($child, true));
      }
      return $doc->saveHTML();
    }
    
    
    $previous_value = libxml_use_internal_errors(TRUE);
    $profilename = $_GET['nick'];
    $profile_url =  'https://www.codeschool.com/users/' . $profilename . '/';
    $context = stream_context_create(array(
        'https' => array('ignore_errors' => true),
    ));
    $html = file_get_contents($profile_url, false, $context);  

    $class = 'bucket';
    $resultsBucket = getClass($class,$html);
    
    $class = 'mbl tac';
    $resultsMaster = getClass($class,$html);
    
    $class = 'pr-pathStatus';
    $resultsPath = getClass($class,$html);
    
    libxml_clear_errors();
    libxml_use_internal_errors($previous_value);
?>

<a href="<?php echo $profile_url; ?>" target="_blank">
    <div class="wrapper-scores">
        <?php
        $full_content = "";
        
        $full_content = $full_content . buildContent($resultsBucket);
        $full_content = $full_content . buildContent($resultsMaster);
        $full_content = $full_content . buildContent($resultsPath);
        
        /* changing h2 tags to h1 tags and inserting line breaks */
        $full_content = str_replace("<h2","<br /><h1",$full_content);
        $full_content = str_replace("</h2>","</h1><br />",$full_content);
        
        /* disabling the anchor tags on each badge by changing to divs */
        $full_content = str_replace("<a href","<div class",$full_content);
        $full_content = str_replace("</a>","</div>",$full_content);
        
        /* changing text on heading of Path Status */
        $full_content = str_replace("Path Status","Paths In Progress",$full_content);
        
        /* return the html */
        echo $full_content;
        ?>
    </div>
</a>