GIT: Download a Patch of a Commit from GitHub

by Oliver 15. November 2017 09:00

We are building our branch portal software discoverize on top of the mature Orchard CMS and incorporate important changes from the Orchard sources into our own software. Today, I wanted to add the CacheManagerExtensions class to discoverize to take advantage of some optimizations to the cache population strategy. The first commit contained changes to no less than 27 files. Manual work: go away! So I thought to myself: I'll just get the patch for this commit and apply it to my working directory :-) Well, guess what? There's no magic patch button on the commit page anywhere. Google and this blog post to the rescue… Download a Commit as a Patch It turns out to be as easy as adding .patch to the end of the commit url – and you get a beatiful text screen that you can save to a .patch file. Applying as much of a patch as possible Use git apply --reject abc.patch to apply all of the patch that can be applied to your current working directory – for the rest of the differences in the commit, reject files (.rej) will be created to not loose track of them. And that's all. Happy patching!

How to Retrieve Your Google Search Console Data via API

by Oliver 8. September 2017 00:04

To set up API access to a site's Search Console, we first need to set up and configure a project in the Google Developer Console. Afterwards, we will connect that project to the Search Console to retrieve data from there using our own application. In the Google Developer Console Set up a project in your Google Developer Console (or reuse an existing project). Go to the Service Accounts page and click [+] CREATE SERVICE ACCOUNT:Check "Furnish a new private key" to retrieve a JSON file with credentials that can be used from your application to impersonate that account. Save the file that is being offered as a download. Its name has the form <ProjectId>-<Hash>.json, e.g. discoverize-b134aef29b12.json. This file is confedential – anyone with access to it can do what your Service Account is allowed to! So treat it respectively. Go to the project dashboard and click [+] ENABLE APIS AND SERVICES: Click on the Google Search Console API link and on the next page click ENABLE. That's what had to be done in the Google Developer Console. Now we'll turn to the Google Search Console aka Webmaster Tools. In the Google Search Console Make sure you have a property set up in the Search Console for the target site. Let's assume you're targeting https://glamping.info. The protocol is of importance: http://glamping.info and https://glamping.info will be two different properties. In the settings drop-down menu, go to Users and Property Owners: Click ADD A NEW USER (do not Manage Property Owners):Add the email address of the Service Account you've created in Google Developer Console and give it Full permission.Note: do NOT add the Service Account as a Property Owner before adding it as a user, otherwise API access using it will NOT work. This is a bug – see this stackoverflow answer for more details. When you click Add, you'll see the new user on the Users and Property Owners page: Now, you're all set up to access your site's Search Console using the Google API. Happy coding!

Iframe Content Does Not Load When Iframe URL Matches URL of Parent Document – in IE and FF

by Oliver 29. September 2016 20:00

It's been a few years already, that on Camping.Info we decided to load the detail page (aka product page) of a campsite into an iframe that lies on top of the search page. This decision has three reasons that still hold true today: Opening the new content on top of the search page – which hosts a Google Map – we avoid additional map views (which would count against our quota or cost money when above the quota) because when the user closes the detail page, we simply remove the iframe from the page. Returning to the search page is faster for the user because all we have to do is remove the iframe from the page. Avoiding another page load for re-displaying the search page with the current filters to the user lessens server load, especially during high season, which actually might save us from running an extra server. Recently, we've finally come around to leveraging the HTML5 history API to adapt the URL of the currently visible page, aka the search page, to that of the campsite's detail page URL that a user chooses to open. It can't be that hard to do, right? During development, Chrome is my browser of choice for testing because my Firefox installation is locked down to avoid infections. In Chrome, the following worked like a charm: Open the Camping.Info search page, i.e. https://www.camping.info/campingplaetze. Click on any link that points to a campsite's detail page, e.g. https://www.camping.info/kroatien/istrien/camping-polari-84 Manipulate the browser history to imitate navigation to that URL. Add an iframe to the search page with that same URL and load the page into that iframe – which lies on top of the page now for the user to interact with. Be done with it. Unfortunately, testing the same approach in Firefox and Internet Explorer it turned out that both FF and IE would not load the page from the given URL into the iframe. Firefox and Internet Explorerbehave differently from Chrome At first, the behavior of Firefox and IE irritated and confused me. Only after some reflection on the scenario, it dawned to me that both browsers simply want to avoid an endless loop of loading a page with an iframe that loads the same page again, which contains an iframe that loads the same page again… So, Firefox and IE choose to not load the iframe contents at all. This is a fair decision, if you think about it for a minute. But what does Chrome do? Does it really allow you to crash it by loading a page with an iframe that loads the same page again? Well, no. Chrome simply decides to break out of the endless loop after the first iteration, instead of before it. Here's what a small test page looks like in all three browsers: The Obvious Fix Since loading a page into an iframe from a URL that is identical to the iframe's parent's URL won't work, we really have only one choice: load it from a different URL! In our case, an easy fix to achieve that is by appending a trailing slash to the URL we pass to the iframe, e.g. https://www.camping.info/kroatien/istrien/camping-polari-84/. This works because we have a URL redirect rule in place that will redirect such a request to https://www.camping.info/kroatien/istrien/camping-polari-84 which will then be loaded into the iframe successfully. Our browser's developer tools then tell us that the src attribute of the iframe does not change during that redirect so we've successfully tricked all browsers into loading the desired page into our iframe, while at the same time we can display the campsite's real detail page URL to the user. Happy coding!

Trimming Whitespace From Text Inputs In ASP.NET WebForms – The Easy Way

by Oliver 22. September 2016 01:02

When I validate forms, I usually don't want the user to allow to enter only whitespace in any of the text fields that I deem required. With a handful of them, checking for that condition can be annoying. Let me introduce you to… TrimTextBox! To centralize the concern to trim padding whitespace from text inputs, I simply derived from the built-in TextBox class and overrode a single property – Text: With this simple piece of code my backend validation logic can now focus on the business rules, e.g. a minimum length of one character, without having to worry about leading, trailing, or only whitespace in any input field. Don't Repeat Yourself – Keep it DRY Whenever I encounter a piece of code that repeats more than once, I try and refactor that code away to make it reusable and sometimes even to completely hide a certain aspect of it from the current context so that when reading a block of code I can decide whether I want to dive deeper into the nitty gritty details or just get an overview of the workflow I'm looking at. This saves my brain some precious resources ;-) I wonder what other use cases you can come up with where a specialized control can make your developer life simpler :-) Happy coding (subclassing)!

How to Convert an XSLX File to CSV with UTF-8 Encoding Using LibreOffice / OpenOffice

by Oliver 13. November 2015 21:54

Thanks to this stackoverflow answer I stumbled upon the comment by Aryeh Leib Taurog who shared his solution and a link to the OpenOffice documentation on the available options for the CSV filter. Here's how to convert the file input.xlsx to the UTF-8 encoded file input.csv in the current directory, with semicolons as field delimiter: soffice.exe --convert-to "csv:Text - txt - csv (StarCalc):59,,76,1" input.xlsx On my Windows system the soffice.exe is located under C:\Program Files\LibreOffice 5\program. Hre's the explanation of the cryptic filter arguments: csv – the extension of the output file Text - txt - csv (StarCalc) – the (ancient) name of the filter (kept for compatibility) 59,,76,1 – these are four arguments: the first parameter is the delimiter in the output file – 59 is the ASCII code for ';' the second parameter is the text delimiter – it's missing because I don't want to wrap text in quotes the third parameter is the file encoding – 76 is the internal OpenOffice code for UTF-8 (from the table on the documentation page) the fourth parameter defines the line number with which to start the export – here, we start with line 1 Thank you, open source community, and happy converting! PS: For non-windows users, Gnumeric with its command line tool ssconvert might be a good choice for this job, as well.

Visual Studio 2013 Update 4 Crashes On Startup – It Might Be GitExtensions' Fault

by Oliver 23. February 2015 22:49

Lately, I've been having a hard time with my Visual Studio installation because one day it just out of nowhere started crashing during startup. Starting VS with the /SafeMode flag avoided the crash but wasn't of much help to do major work since all my R# syntax highlighting and refactoring tools are not available in safe mode. First Try: Reset All Your Settings The first time I encountered the problem I found this answer on stackoverflow.com  helpful which suggests to: Reset all your Visual Studio settings by calling devenv /resetsettings from a command line prompt or after hitting the Windows key. Delete the folders %LocalAppData%\Microsoft\VisualStudio and %LocalAppData%\Microsoft\VSCommon Second Try: Uninstall GitExtensions Today, VS started crashing again and I was just happy with resetting all of my fine-tuned settings AGAIN. Luckily, a google search brought up this thread on the NCrunch forum and since I use NCrunch for test execution I went to have a look Here's what Simon had to say there: I'm thinking the problem was a GIT plugin installed by GitExtensions - I've read other reports about it causing problems, so I've removed it and things seem stable so far. To verify whether this was true in my case I just went ahead and uninstalled GitExtensions via the Control Panel – and Visual Studio would happily start again! What a relief. But I Still Want To Use GitExtensions… After uninstalling, go get the installer again (did you know there's a standalone version without msysgit and kdiff?) and during install unselect all the Visual Studio plugins like this: UPDATE: Keep Even GitExtensions' VS Plugin! A commenter to my answer to the VS crash problem on stackoverflow suggested that unchecking the option "Show current branch in Visual Studio" in GitExtensions under Tools –> Settings –> Appearance fixed the VS crashes for him: I used this hint to reactivate the GitExtensions VS plugin on my machine as well, because I use some of its features quite often. Now, you should be good to go! I'll try to get back to work now while my VS is running… Happy coding!

Setting up freeSSHd to Connect to its SFTP Server Using SSH Public Key Authentication

by Oliver 14. January 2015 22:59

A while ago I've set up an SFTP server using the freeware freeSSHd which is relatively easy to get up and running. Initially, I created a user/password pair to log into the server. Using SSH Last week, we decided to switch to public/private SSH keys for authentication instead of the user/password pair. Among other things, this allows us to script access to our server while at the same time we can avoid keeping a clear text password in one of our scripts. Here's how we've set it up. Configuring freeSSHd for use with SSH I'll run you through the necessary steps: Open an instance of freeSSHd and go to the Users tab. Add or Change a login to use Public Key (SSH only) authorization and enable SFTP access: Navigate to the Authentication tab. There you'll find the path to the folder in which to deposit your public keys. If you plan to have more than a few, consider using a subfolder of the default one: Open the public key folder in Windows Explorer and create a new empty text file there by the name of the login you've set up in step 1. Make sure the file name is exactly the same as the name of the user and don't add any file extension to it. This is where we'll be pasting a new SSH public key to in a moment: Now we will generate an SSH key pair. Locate puttygen.exe on your PC. You can grab it from the PuTTY download page, but it also comes bundled with GitExtensions, or WinSCP, if you use one of these: [Side note: I use Everything to find such files. It's a great search tool that delivers instant results.] Start puttygen.exe and generate a pair of SSH keys by clicking Generate ❶: Next, copy the public key from the grey text box ❷ and paste it into the empty file you've created in step 3. In my case, this file is called "oliver". You can now save the private key ❸ to a file of your choice, optionally protected by a passphrase, to use it to connect to freeSSHd via SSH using your preferred tool. I've successfully used WinSCP for testing, as I've experienced several problems using PuTTY's psftp.exe command line tool. Roundup Setting up public key authentication in freeSSHd can be tricky. While researching the solution I've stumbled over this blog post addressing the same problem. Its author refers to this setup guide from IBM (pdf) as the source of help so it might be helpful to others out there, as well. I hope that my step-by-step guide has also helped you. Happy connecting!

Turn Off / Remove Ads in Skype's Chat Window On a Windows OS

by Oliver 19. August 2014 21:37

I've got quite annoyed by seeing the same ad in my Skype chat window and today I simply had enough of it. Going to Google lead me to this Youtube video which shows how to block ads in Skype by denying access to https://apps.skype.com/ in Internet Explorer. Here's a screen shot, just follow the steps below and you're done: Open Internet Options Switch to the Security tab Select Restricted Sites Click the Sites button Type https://apps.skype.com/ into the text box Click Add Click Close Click OK For those changes to take effect in Skype you need to leave your chat window e.g. by clicking on your profile in the upper left corner. Now, when you open a chat window no ads will show. There are other ways to stop Skype from showing ads, and here's a really thorough post on that topic. Happy Skype'ing!

Optimize Images for Your Website

by Oliver 17. June 2013 13:59

This is just a short post to draw your attention to a sweet tool I've just discovered: PNGGauntlet. It runs on Windows using the .NET 4 framework and is as easy to use as you could possibly wish. Also: it's completely free to use. Convert Your Existing PNGs For starters, we'll just convert some existing PNGs – can't really do any harm with that. In the Open File dialog, there's an option to filter for only .png files. You can choose many of them at once: If you provide an Output directory, the optimized files will be written to that destination. But: the tool also has the option to overwrite the original files, which is awesome if you use some kind of source control (and thus have a backup) and just want to get the job done. During my first run, using the 8 processing threads my CPU has to offer, … … I got savings from 3% to 27%: PNGGauntlet also tells me, that in total I saved 4,52 KB. If those were all images on your web site, that would be a not so bad improvement, especially when you get it investing about 2 min of your time and no extra expenses! Real Savings Running PNGGauntlet on the sprites that we use for Camping.Info, we were really surprised: out of 172 KB it saved us over 31%, a whole 54 KB! Now that's an improvement that on a slightly slower connection will already be noticeable. We'll definitely check the rest of our images for more savings. Convert Other Image Formats You can also choose to change your images format to PNG if you're in the mood. I tried converting all GIFs in the Orchard CMS Admin theme to PNGs and went from a total of 24 KB for 20 files to less than 17 KB with no loss of quality – an over 30% saving! Just beware that you'll need to change the file references in your project to pick up the new PNGs. Roundup Easy, fast and cheap (as in free) image optimization doesn't have to be magic anymore – today anyone can do it. Check out PNGGauntlet to try for yourself. There's really no excuse not to!

Orchard Harvest: Shapes Session

by Oliver 14. June 2013 18:09

These are session notes, so they might not adhere to the standards of a complete blog post, but there's a bunch of inspiring info that I had to get out of my head… Shapes – Overview What are they dynamic data model can be updated at runtime replaces static(ally typed) view models Creating Shapes Never instantiate Shape directly it won't trigger the related events in code, use an IShapeFactory dependency IShape Create(string shapeType) in Orchard views, use New   - New is just an IShapeFactory cast to dynamic   - New.Product -> IShapeFactory.Create("Product") Rendering Shapes use well-named file templates use shape methods any method in class inheriting from IDependency with the [Shape] attribute future: dynamic shapes to come, e.g. from DB (by Piotr Szmyd) refer to IDisplayHelperFactory and IDisplayHelper for more detailed info Advanced Uses of Shapes If you're just starting with Orchard Shapes, I recommend you to skip this section for now ;-) Creating Strongly Typed Shapes in your ContentDriver, when creating a Shape, you can do: 1: protected override DriverResult Display(EntryPart part, string displayType, dynamic shapeHelper) { 2: return ContentShape("Parts_Common_Body" /* Placement Key */, 3: () => shapeHelper.Parts_Common_Body(Html: someHtml)); 4: } becomes: 1: public class ConcreteType : Shape { 2: public string Html { get; set; } 3: } 4:  5: protected override DriverResult Display(EntryPart part, string displayType, dynamic shapeHelper) { 6: var shape = (ConcreteType) shapeHelper.Parts_Common_Body(typeof(ConcreteType)) 7: shape.Html = someHtml; 8: return ContentShape("Parts_Common_Body" /* Placement Key */, 9: () => shape); 10: } And then in your template, you can actually define your @model to be of type ConcreteType: 1: @model My.Namespace.ConcreteType 2:  3: @Display(Model.Html) Shape Events We have different extension points to hook into the shape rendering process: IShapeDisplayEvent intercept all shape Display events ShapeMetadata intercept a specific shape's Display events IShapeTableProvider configured at discovery time, for a specific type hook into events other than Display Order of invocation of the different event handlers: Displaying ShapeDisplayEvents ShapteTableProvider ShapeMetadata Display Set Metadata.ChildContent Shape is rendered if ChildContent not set (open e.g. for Caching) Wrappers are rendered in order, from Metadata.ChildContent, e.g. Document.cshtml Displayed ShapeDisplayEvents ShapteTableProvider ShapeMetadata Shape Morphing change the Metadata.Type of a Shape before rendering render the same Shape again using a different template see the MenuItem template for an example Shape Relocation The idea here is to add a Shape to a different part of the page than where your current ContentItem is rendering. In your view, just use: 1: @Display(Model.MyTitle) Now, in your placement.info file, write: 1: <Match ContentType="Page" DisplayType="Detail"> 2: <Place Parts_Title="MyTitle:5" /> 3: </Match> This will display your Title shape (possibly) a second time.

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.