<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">

    <channel>
    
    <title>SimplyGold</title>
    <link>http://www.nikhedonia.com/notebook/</link>
    <description>Templates, Themes, Tutorials</description>
    <dc:language>en</dc:language>
    <dc:creator>simplygold@nikhedonia.com</dc:creator>
    <dc:rights>Copyright 2011</dc:rights>
    <dc:date>2011-02-12T13:29:00-06:00</dc:date>
    
      
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nikhedonia/notebook" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nikhedonia/notebook" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Logging all exceptions in WCF</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/logging-all-exceptions-in-wcf/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/logging-all-exceptions-in-wcf/#When:13:29:00Z</guid>
      <description><![CDATA[<p>Logging errors is a common requirement in applications, including WCF applications. Having to catch the exception in each service method, logging it, and throwing it again happens to be dull, boring, painful, and ugly. ASP.NET allows you to "catch" errors in <code>Global.asax Application_Error</code>, but what about WCF applications?</p>

<p>As it happens, it's just as easy to hook into exceptions in WCF as well. WCF conveniently provides us with an <code>IErrorHandler</code> which has a<code>ProvideFault</code> method that's called on all exceptions. For example:</p>

<pre><code>public class HttpErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        return false;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        System.Diagnostics.Debug.WriteLine(error.ToString());
    }
}
</code></pre>

<p>We're returning <code>false</code> from <code>HandleError</code> to let WCF know that we haven't actually handled the error, so the dispatcher aborts any session (and the <code>InstanceContext</code> if the <code>InstanceContextMode</code> isn't <code>Single</code>).</p>

<p>Once we're done creating our custom error handler, we need to let WCF know to use it. In <code>web.config</code>, create a <code>&lt;behaviors&gt;.&lt;serviceBehaviors&gt;.&lt;behavior&gt;</code> configuration as follows:</p>

<pre><code>&lt;serviceBehaviors&gt;
    &lt;behavior name="myconfig"&gt;
        &lt;logErrors /&gt;
    &lt;/behavior&gt;
&lt;/serviceBehaviors&gt;
</code></pre>

<p>Then, create the <code>&lt;logErrors&gt;</code> extension:</p>

<pre><code>&lt;extensions&gt;
    &lt;behaviorExtensions&gt;
        &lt;add
            name="logErrors"
            type="Example.ErrorServiceBehavior, Example" /&gt;
    &lt;/behaviorExtensions&gt;
&lt;/extensions&gt;
</code></pre>

<p>Then, you need to your services to use the  <code>myconfig</code> behavior configuration with <code>&lt;service behaviorConfiguration="myconfig" /&gt;</code>.</p>
]]></description>
      <dc:subject>WCF</dc:subject>
      <dc:date>2011-02-12T13:29:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Log ASP.NET Request Durations</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/log-aspnet-request-durations/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/log-aspnet-request-durations/#When:10:00:00Z</guid>
      <description><![CDATA[<p>Suppose you want to log how long each request to your ASP.NET application took. Four months from now, when clients complain about hanging pages, you'll have a ton of data at your disposal to figure out average request times per URL by day, month, whatever.</p>

<p>Fortunately, ASP.NET provides an easy way for us to accomplish this, via a custom <code>IHttpModule</code>.  Essentially, the process goes as follows:</p>

<ol>
<li>Start your timer in <code>HttpApplication.BeginRequest</code>.</li>
<li>Stop your timer in <code>HttpApplication.EndRequest</code> .</li>
<li>Raise an event with the request URL and the duration. </li>
</ol>

<p>The code is amazingly simple, so here it is in its entirety:</p>

<pre><code>public class RequestDurationEventArgs : EventArgs
{
    public string Url { get; private set; }

    public TimeSpan Duration { get; private set; }

    public DateTime RequestedAt { get; private set; }

    public RequestDurationEventArgs(string url, DateTime requestedAt, TimeSpan duration)
    {
        Url = url;
        Duration = duration;
        RequestedAt = requestedAt;
    }
}

public class RequestDurationLoggerModule : IHttpModule
{
    private const string _requestDurationKey = "RequestDurationKey";

    private EventHandler&lt;RequestDurationEventArgs&gt; _requestDurationCalculatedHandler;

    public event EventHandler&lt;RequestDurationEventArgs&gt; RequestDurationCalculated
    {
        add { _requestDurationCalculatedHandler += value; }
        remove { _requestDurationCalculatedHandler -= value; }
    }

    public void Dispose()
    {

    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += (sender, e) =&gt;
        {
            context.Context.Items[_requestDurationKey] = DateTime.UtcNow;
        };

        context.EndRequest += (sender, e) =&gt;
        {
            var end = DateTime.UtcNow;
            var start = (DateTime)context.Context.Items[_requestDurationKey];
            var url = context.Context.Request.RawUrl;

            if (_requestDurationCalculatedHandler != null)
            {
                _requestDurationCalculatedHandler(this, new RequestDurationEventArgs(url, start, end - start));
            }
        };
    }
}
</code></pre>

<p>The only steps remaining are to:</p>

<ol>
<li>Let ASP.NET know about the module. </li>
<li>Hook into the <code>RequestDurationCalculated</code> and process it.</li>
</ol>

<p>Step 1 requires adding the module to <code>&lt;httpModules&gt;</code> in your <code>web.config</code>:</p>

<pre><code>&lt;add name="RequestDurationLogger" type="Utilities.RequestDurationLoggerModule, Utilities" /&gt;            
</code></pre>

<p>Step 2 can be done in a variety of ways. Here's one that uses <code>Global.asax</code>:</p>

<pre><code>protected void RequestDurationLogger_RequestDurationCalculated(object sender, RequestDurationEventArgs e)
{
    System.Diagnostics.Debug.WriteLine(string.Format("{0}: Requested At: {1}:{2}, Took: {3}s", e.Url, e.RequestedAt.ToLocalTime().ToShortDateString(), e.RequestedAt.ToLocalTime().ToShortTimeString(), e.Duration.TotalSeconds));
}
</code></pre>
]]></description>
      <dc:subject>ASP .NET, Miscellaneous</dc:subject>
      <dc:date>2011-02-11T10:00:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Manually Hosting WCF Services in ASP.NET Web Application</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/manually-hosting-wcf-services-in-aspnet-web-application/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/manually-hosting-wcf-services-in-aspnet-web-application/#When:15:40:00Z</guid>
      <description><![CDATA[<h3>What's wrong with using Visual Studio's WCF projects and automatic proxy generation?</h3>

<p>Visual Studio provides you with two handy projects to create WCF services: "WCF Service Application"  and "WCF Service Library," in which Visual Studio automatically setups up the binding and endpoint information when you create a new "WCF Service." Once you publish the WCF app, assuming metadata publishing is enabled, you can use Visual Studio to automatically generate the proxies for your services in your client apps. The client configuration file is also updated with the binding and endpoint information.</p>

<p>This all sounds pretty good. So what's wrong with it?</p>

<ol>
<li>You need to "Update Service Reference" every time you make a change in every project you're referencing the service. There's a not insignificant chance that this operation will fail at any given time, anyway, especially if you're under source control. </li>
<li>The configuration files look insane. Have more than one service in a project? You will see tons of duplicate information. </li>
<li>Having multiple services in a single project is a pain to deploy if you put each service in its own folder. The services have trouble finding the bin folder. <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></li>
<li>Contracts and services are all mushed into the same project. Providing multiple implementations of the same contract is more difficult and less clean. </li>
</ol>

<h3>How to do everything manually?</h3>

<p>You might think self-hosting WCF services is going to be complicated and convoluted, but nothing could be further from the truth. I'll give you the step-by-step in this article. Once you understand the process, you'll be able to do the whole thing in five minutes.</p>

<p>Let's look at an example. Say you're writing the next generation blogging software and want to use WCF services for your back-end. One of your business requirements might be to show all the posts created by a particular author. Here's what you would do:</p>

<h4>Step 1: Create your solution structure</h4>

<p>Create four projects: 
1. Blog: class library. This is where your DTOs will live. 
2. Blog.Contracts: class library. This is where your service interfaces will live. 
3. Blog.Services: class library. This is where your service implementations will live. 
4. Blog.Hosts: (Empty) ASP.NET web application. This is where your hosts will live. This is the project you will publish. 
5. Blog.Proxies: class library. This is where your proxies will live.</p>

<h4>Step 2: Add the appropriate references</h4>

<p>Add the following references to the following projects: 
1. Blog
    * System.Runtime.Serialization
2. Blog.Contracts: 
    * System.ServiceModel
    * Blog
3. Blog.Services: 
    * Blog
    * Blog.Contracts
4. Blog.Hosts: 
    * Blog
    * Blog.Contracts
    * Blog.Services
5. Blog.Proxies: 
    * Blog
    * Blog.Contracts</p>

<h4>Step 3: Create your DTO</h4>

<pre><code>[DataContract]
public class Post
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public string Contents { get; set; }

    [DataMember]
    public string Author { get; set; }
}
</code></pre>

<p>The <code>DataContract</code> and <code>DataMember</code> attributes specify that the type and the properties are serializable.</p>

<h4>Step 4: Create your contract</h4>

<pre><code>[ServiceContract]
public interface IPostService
{
    [OperationContract]
    Post[] GetPostsByAuthor(string author);
}
</code></pre>

<p>Nothing surprising here.</p>

<h4>Step 5: Create your proxy</h4>

<p>public class PostServiceProxy : ClientBase<IPostService>, IPostService
    {
        public Post[] GetPostsByAuthor(string author)
        {
            return Channel.GetPostsByAuthor(author);
        }
    }</p>

<p>Every other service will follow this same exact pattern: your proxy will inherit from <code>ClientBase&lt;IYourContractType&gt;</code> and implement <code>IYourContractType</code>. Each method's body will be the same: <code>return Channel.MethodName(method arguments)</code> for methods that return something and <code>Channel.MethodName(method arguments)</code> for methods that don't.</p>

<p>The benefit of creating your own proxy is that you get compile-time error checking. You can also reference this and the <code>DTO</code> DLL anywhere you're using the service, so you only need to make changes in one place instead of several.</p>

<h4>Step 6: Create your service</h4>

<p>Here's a sample implementation of the service that uses Linq to filter an in-memory post collection:</p>

<pre><code>public class PostService : IPostService
{
    private static readonly List&lt;Post&gt; Cache = new List&lt;Post&gt;();

    public Post[] GetPostsByAuthor(string author)
    {
        return Cache.Where(x =&gt; x.Author == author).ToArray();
    }
}
</code></pre>

<h4>Step 7: Create your host</h4>

<pre><code>&lt;%@ ServiceHost Service="Blog.Services.PostService" %&gt;
</code></pre>

<p>The way to do this is a little tricky. You don't want to add a "WCF Service," because then Visual Studio will create all kinds of useless configuration elements in your web.config, not to mention a code-behind for your service.</p>

<p>Instead, add a new text file to your <code>Blog.Hosts</code> project, but set the extension to be svc. Add the aforementioned line to the top of the file, and you're good to go.</p>

<h4>Step 8: Add a service endpoint to the web.config</h4>

<p>Lastly, you need to setup the endpoint information in web.config in your <code>Blog.Hosts</code> project.</p>

<pre><code>&lt;system.serviceModel&gt;
    &lt;services&gt;
        &lt;service name="Blog.Services.PostService"&gt;
            &lt;endpoint 
</code></pre>

<p>address="" 
binding="wsHttpBinding"
contract="Blog.Contracts.IPostService" />
            </service>
        </services>
    &lt;/system.serviceModel></p>

<p>This is all the configuration you need to create an endpoint using the defaults. If you want to change the defaults, you have to configure the endpoint -- either through code or through web.config -- but that's a topic for an upcoming article. For most services, default configurations should work just fine.</p>

<p>Set your host project as the startup project and the PostService.svc as your startup page. Run the solution, and you should see the service. <sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup></p>

<p>And that's all there is to it. Adding a new service follows the exact same process.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>You can probably fix this with additional coding.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn:2">
<p>The page will tell you that "Metadata publishing for this service is currently disabled" because we haven't set that up. You can do it by configuring <code>behaviors.serviceBehaviors.behavior</code> with <code>&lt;serviceMetadata httpGetEnabled="true" /&gt;</code>. This will enable metadata publishing for all services in the project.&#160;<a href="#fnref:2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></description>
      <dc:subject>C#, WCF</dc:subject>
      <dc:date>2011-02-10T15:40:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Scrollbars in WPF</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/scrollbars-in-wpf/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/scrollbars-in-wpf/#When:19:33:00Z</guid>
      <description><![CDATA[<p>Quick tip: to see scrollbars in WPF -- when the content spills over the window width or height -- add a <code>ScrollViewer</code> to your control.</p>

<pre><code>&lt;ScrollViewer HorizontalScrollBarVisibility="Auto"&gt;
    &lt;StackPanel name="contentPanel"&gt;
    &lt;/StackPanel&gt;
&lt;/ScrollViewer&gt;
</code></pre>

<p>Note the <code>HorizontalScrollBarVisibility</code> property on your <code>ScrollViewer</code>. You have to explicitly set it to <code>Auto</code> (or <code>Visible</code>) to see the horizontal scrollbar.</p>
]]></description>
      <dc:subject>Tips &amp;amp; Tricks</dc:subject>
      <dc:date>2011-01-19T19:33:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Download all PDF documents from webpage</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/download-all-pdf-documents-from-webpage/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/download-all-pdf-documents-from-webpage/#When:19:15:00Z</guid>
      <description><![CDATA[<p>I recently found myself wanting to download multiple pdf documents from a webpage. I started doing this manually, but I got sick of clicking on links and keeping track of which ones I'd already downloaded, so I decided to write a small python script to automate this for me.</p>

<h4>Steps</h4>

<ol>
<li>Download the webpage content using <a href="http://docs.python.org/library/urllib.html">urlopen</a>.</li>
<li>Find all links using <a href="http://docs.python.org/library/htmlparser.html">HTMLParser</a>: you can subclass <code>HTMLParser</code> and override the <code>start_a</code> method, which is called at the start of every link.</li>
<li>Figure out which of these link to PDFs: get the link's extension and make sure it's "pdf."</li>
<li>Ensure each PDF link is a "full path": sometimes, the link href will be of format "/blah.pdf" or "blah.pdf," so we need to take that into account.</li>
<li>Download each PDF via <a href="http://docs.python.org/library/urllib.html">urlretrieve</a>.</li>
</ol>

<h4>The code</h4>

<pre><code>import urllib, htmllib, formatter, os

class LinksExtractor(htmllib.HTMLParser):
    def __init__(self, formatter):
        htmllib.HTMLParser.__init__(self, formatter)
        self.links = []

    def start_a(self, attrs):
        if len(attrs) &gt; 0:
            for attr in attrs:
                if attr[0] == "href":
                    self.links.append(attr[1])

    def get_links(self):
        return self.links

def full_links(url, links):
    full_links = []

    for link in links:
        if link.startswith("http"):
            full_links.append(link)
        elif link.startswith("/"):
            base_url_parts = url.split("/")[0:3]
            base_url = base_url_parts[0] + "//" + base_url_parts[2]
            full_links.append(base_url + link)
        else:
            filename_starts_at = url.rindex("/") + 1
            base_url = url[0:filename_starts_at]
            full_links.append(base_url + link)

    return full_links


def download(url, save_dir):
    urllib.urlretrieve(url, save_dir + os.sep + url.split('/')[-1])

def get_pdfs(url):
    format = formatter.NullFormatter()
    parser = LinksExtractor(format)
    data = urllib.urlopen(url)

    parser.feed(data.read())
    parser.close()

    all_links = parser.get_links()
    pdf_links = []

    for link in all_links:
        extension = link.split(".")[-1]

        if extension == "pdf":
            pdf_links.append(link)

    return pdf_links

def download_pdfs(url, save_dir):
    pdfs = full_links(url, get_pdfs(url))

    for pdf in pdfs:
        download(pdf, save_dir)

url = "url goes here"
save_dir = os.getcwd() 

download_pdfs(url, save_dir)
</code></pre>
]]></description>
      <dc:subject>Python, Tips &amp;amp; Tricks</dc:subject>
      <dc:date>2010-12-18T19:15:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Open Chrome in Incognito Mode by Default in Mac</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/open-chrome-in-incognito-mode-by-default-in-mac/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/open-chrome-in-incognito-mode-by-default-in-mac/#When:00:38:00Z</guid>
      <description><![CDATA[<p>Setting up Chrome to open incognito on Windows is fairly easy: create a shortcut, add the appropriate arguments, and you're on your way. How to do it on Mac wasn't as straightforward to me, however. After a couple of months of annoyance, I blocked some time in the evening yesterday to figure it out.</p>

<p>It turned out to be fairly simple. On Snow Leopard, anyway.</p>

<h4>Step 1: create scrippt</h4>

<p>Open the Apple Script Editor (in Applications/Utilities) and type the following:</p>

<pre><code>do shell script "open -a /Applications/Google\\ Chrome.app --args --incognito"
</code></pre>

<p>You're basically telling shell to open Chrome, with the argument "incognito." Note the two back slashes in front of the space between Google and Chrome. Also note that "args" and "incognito" have <strong>two</strong> dashes in front of them, not one.</p>

<p>If you run the script, it should open up Chrome in incognito mode, assuming you don't have Chrome already open.</p>

<h4>Step 2: save as application</h4>

<p>Go File > Save As, and give the app whatever name you want. "ChromeIncognito," for example. Make sure that the File Format is "Application."</p>

<p>Drag the application onto your dock, maybe change the icon of the script to something more Chrome-looking, and you're done!</p>
]]></description>
      <dc:subject>Miscellaneous</dc:subject>
      <dc:date>2010-12-18T00:38:00-06:00</dc:date>
    </item>
      
    <item>
      <title>SafeDataReader without magic strings</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/safedatareader-without-magic-strings/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/safedatareader-without-magic-strings/#When:02:42:01Z</guid>
      <description><![CDATA[<p>I was reading a book about lambda expressions the other day and had a minor eureka! moment.</p>

<p>Let's look at your typical data population code:</p>

<pre><code>using (var reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        var user = new User
        {
            UserId = reader.GetInt32(0),
            UserName = reader.GetString(1),
            EmailAddress = reader.GetString(2)
        };
    }
}
</code></pre>

<p>If you detest magic constants as much as I do, your code might be a bit better:</p>

<pre><code>UserId = reader.GetInt32(reader.GetOrdinal("UserId"));
</code></pre>

<p>You might have gone further and created a <a href="http://www.lhotka.net/Article.aspx?id=9280bc86-c706-4d2d-8993-8b5bda6bad22">SafeDataReader</a> of some sort that lowers the pain-threshold, so you can write:</p>

<pre><code>UserId = reader.GetInt32("UserId");
</code></pre>

<p>The only problem is that you're exchanging one type of magic for another. "UserId" is definitely better than "0," but not by much. The best way to fix this is to use an ORM, of course, but that's not always possible. I thought .NET's new lambda expressions might come in useful here.</p>

<pre><code>UserId = reader.GetInt32(user =&gt; user.UserId);
</code></pre>

<p>This looked much better than the previous version.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></p>

<p>With my newfound knowledge on expressions, I thought i would give it a try. The main task is figuring out the name from the expression; I googled for a little bit, but then I remembered that <a href="http://github.com/jagregory/fluent-nhibernate">FluentNHibernate</a> had to solve the problem already for their syntax. After digging through their code, I came up with something similar for the parsing:</p>

<pre><code>public class SafeDataReader&lt;T&gt; : SafeDataReader, ISafeDataReader
{
        private string parseName(UnaryExpression expression)
        {
            var malformedExpressionError = "Expression must be of form user =&gt; user.UserId";

            if (!(expression.Operand is MemberExpression))
            {
                throw new ArgumentException(malformedExpressionError, "expression.Operand");        
            }

            return parseName((MemberExpression)expression.Operand);
        }

        private string parseName(MemberExpression expression)
        {
            var member = expression.Member;
            var wrongDeclaringTypeError = "Member must be declared in " + typeof(T);

            if (member.DeclaringType != typeof(T))
            {
                throw new ArgumentException(wrongDeclaringTypeError);
            }

            return member.Name;
        }

        private string parseName(Expression&lt;Func&lt;T, object&gt;&gt; expression)
        {
            if (expression.Body is UnaryExpression)
                return parseName((UnaryExpression) expression.Body);
            if (expression.Body is MemberExpression)
                return parseName((MemberExpression)expression.Body);

            throw new ArgumentException(
                string.Format("Malformed expression: {0}", expression),
                "expression");
        }
}
</code></pre>

<p>(The <code>SafeDataReader</code> (non-generic) class is the same as an <code>IDataReader</code>, but it also implements the associated "get-by-name" methods.)</p>

<p>Your methods look as follows:</p>

<pre><code>public bool GetBoolean(Expression&lt;Func&lt;T, object&gt;&gt; name)
{
    return GetBoolean(parseName(name));
}
</code></pre>

<p>Pretty simple. You can <a href="http://nikhedonia.com/work/SafeDataReader.zip">download all the files here</a></p>

<p>Now you'll be chasing bugs because somebody renamed the property but didn't change the stored procedure .... ;-)</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>You can probably go farther in reducing/removing duplication.&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
]]></description>
      <dc:subject>C#</dc:subject>
      <dc:date>2010-10-20T02:42:01-06:00</dc:date>
    </item>
      
    <item>
      <title>Compiling Rhino ETL from GitHub</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/compiling-rhino-etl-from-github/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/compiling-rhino-etl-from-github/#When:16:25:01Z</guid>
      <description><![CDATA[<p>I wanted to play with Rhino ETL, but there isn't a place for you to download the release DLLs. Instead, you have to compile source code. This isn't the most intuitive thing in the world.</p>

<p>You need:</p>

<ol>
<li><a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx">The PowerShell</a></li>
<li><a href="http://code.google.com/p/msysgit/downloads/list">mysysgit</a></li>
</ol>

<h3>PowerShell</h3>

<p>By default, PowerShell execution policy is set to Restricted (which you can check by running <code>Get-ExecutionPolicy</code>). default.ps1 script requires Unrestricted access:</p>

<pre><code>Set-ExecutionPolicy Unrestricted
</code></pre>

<p>If the script runs without errors, good for you. It didn't for me. It kept dying on "git" for me. We're only using git to get the log for AssemblyInfo.cs (for compiling the solution, anyway). You can move past the error by going to the <code>psake_ext.ps1</code> and commenting out this line (put a <code>#</code> before the line):</p>

<pre><code>$commit = Get-Git-Commit
</code></pre>

<p>The script hopefully runs successfully at this point and create a bunch of directories under the root folder (for example, <code>build</code>).</p>

<p>Don't forget to revert your PowerShell execution policy back to Restricted (<a href="http://technet.microsoft.com/en-us/library/ee176949.aspx">or something a little more secure</a>).</p>
]]></description>
      <dc:subject>Miscellaneous, Tips &amp;amp; Tricks</dc:subject>
      <dc:date>2010-10-18T16:25:01-06:00</dc:date>
    </item>
      
    <item>
      <title>Download all pages of a forum thread</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/download-all-pages-of-a-forum-thread/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/download-all-pages-of-a-forum-thread/#When:19:08:00Z</guid>
      <description><![CDATA[<p>I recently found myself wanting to save a thread that had over 200 pages. Saving each of them manually would have been long and painful, so I decided to create a small script in python that will save each page:</p>

<pre><code>import urllib
url_prefix = "the site url prefix here"
forum = forum number
thread = thread number
pages = range(thread_start_index, thread_end_index, thread_step)
file_prefix = "file prefix here"
page_count = len(pages)
file_suffix = ".html"

for page in pages:
    url = "thread format here" % (url_prefix,forum,thread,page)
    url_handle = urllib.urlopen(url)
    page_index = (page / thread_step) + 1
    file_page = "%dof%d" % (page_index, page_count)
    filename = "%s%s%s" % (file_prefix, file_page, file_suffix)

    file_handle = open(filename, 'w')

    for lines in url_handle.readlines():
        file_handle.write(lines)

    file_handle.close()
    url_handle.close()
</code></pre>
]]></description>
      <dc:subject>Python, Tips &amp;amp; Tricks</dc:subject>
      <dc:date>2010-08-07T19:08:00-06:00</dc:date>
    </item>
      
    <item>
      <title>Django save_model not being called on create</title>
      <link>http://www.nikhedonia.com/ee/index.php/notebook/entry/django-save-model-not-being-called-on-create/</link>
      <guid>http://www.nikhedonia.com/ee/index.php/notebook/django-save-model-not-being-called-on-create/#When:02:55:00Z</guid>
      <description><![CDATA[<p>I just spent an hour trying to figure out why my save_model was not being called on the creation of a model but got called fine during edits. It's not like the save_model code was particularly complicated or anything like that. It was, in fact, about as simple as it got:</p>

<pre><code>def save_model(self,request,model,form,change):
    if not change:
        model.created_by = request.user
    model.save()
</code></pre>

<p>If this doesn't work, <strong>make sure you are developing against the latest Django version.</strong> A <a href="http://code.djangoproject.com/ticket/12696">bug was reported and fixed 5-6 months ago</a>, so you might already have the latest version, but make sure.</p>
]]></description>
      <dc:subject>Python, Tips &amp;amp; Tricks</dc:subject>
      <dc:date>2010-07-14T02:55:00-06:00</dc:date>
    </item>
      
    
    </channel>
</rss>

