media, music, movies, hardware, home, synology comments edit

UPDATE 7/8/2015 - All current documentation for my media center and home network is at illigmediacenter.readthedocs.io.

Way back in 2008 I put up an overview of my media server solution based on the various requirements I had at the time - what I wanted out of it, what I wasn’t so interested in.

I’ve tried to keep that up to date somewhat, but I figured it was time to provide a nice, clean update with everything I’ve got set up thus far and a little info on where I’m planning on taking it. Some of my requirements have changed, some of the ideas about what I want out of it have changed.

Requirements

  • Access to my DVD collection: I want to be able to get to all of the movies and TV shows in my collection. I am not terribly concerned with keeping the menus or extra features, but I do want the full audio track and video without noticeably reduced fidelity.
  • Family acceptance factor: I want my wife and daughter to be able to navigate through the system and find what they want to watch with minimal effort.
  • Access to my pictures: I want to be able to see my family photos from a place outside my office where the computers generally sit.
  • Access to my music: I want to be able to listen to my music collection from any room in the house.
  • As compatible as possible: When choosing formats, software, communication protocols, etc., I want it to be compatible with as many devices I own as possible. I have an Android phone, an iPod classic, an iPad, Windows machines, a PS4, an Xbox 360, a Kindle Fire, and a Google Chromecast.

Hardware

My hardware footprint has changed a bit since I started, but I’m in a pretty comfortable spot with my current setup and I think it has a good way forward.

  • Synology DS1010+: I use the Synology DS1010+ for my movie storage and as the Plex server (more on Plex in the software section). The 1010+ is an earlier version of the Synology DS1513+ and is amazingly flexible and extensible.
  • HP EX475 MediaSmart Server: This little machine was my first home server and was originally going to be my full end-to-end solution. Right now it serves as picture and audio storage as well as the audio server.
  • Playstation 3: My main TV has an Xbox 360, a PS3, and a small home theater PC attached to it… but I primarily use the PS3 for the front end for all of this stuff. The Xbox 360 may become the primary item once the Plex app is released for it. The PC was primary for a while but it’s pretty underpowered and cumbersome to turn on, put to sleep, etc.
  • Google Chromecast: Upstairs I have the Chromecast and an Xbox 360 on it. The Chromecast does pretty well as the movie front end. I sort of switch between this and the 360, but I find I spend more time with the Chromecast when it comes to media.

Software

I use a fairly sizable combination of software to manage my media collection, organize the files, and convert things into compatible formats.

  • Picasa: I use Picasa to manage my photos. I mostly like it, though I’ve had some challenges as I have moved it from machine to machine over the years in keeping all of the photo album metadata and the ties to the albums synchronized online. Even with these challenges, it is the one tool I’ve seen with the best balance of flexibility and ease of use. My photos are stored on a network mounted drive on the HP MediaSmart home server.
  • Asset UPnP: Asset UPnP is the most flexible audio DLNA server I’ve found. You can configure the junk out of it to make sure it transcodes audio into the most compatible formats for devices, and you can even get your iTunes playlists in there. I run Asset UPnP on the HP MediaSmart server.
  • Plex: I switched from XBMC/Kodi to Plex for serving video, and I’ve also got Plex serving up my photos. The beauty of Plex is that it has a client on darn near every platform; it has a beautiful front end menu system; and it’s really flexible so you can have it, say, transcode different videos into formats the clients require (if you’re using the Plex client). Plex is a DLNA server, so if you have a client like the Playstation 3 that can play videos over DLNA, you don’t even need a special client. Plex can allow you to stream content outside your local network so I can get to my movies from anywhere, like my own personal Netflix. Plex is running on the Synology DS1010+ for the server; and I have the Plex client on my iPad, Surface RT, home theater PC, Android phones, and Kindle Fire.
  • Handbrake: Handbrake is great for taking DVD rips and converting to MP4 format. (See below for why I am using MP4.) I blogged my settings for what I use when converting movies.
  • DVDFab HD Decrypter: I’ve been using DVDFab for ripping DVDs to VIDEO_TS images in the past. It works really well for that. These rips easily feed into Handbrake for getting MP4s.
  • MakeMKV: Recently I’ve been doing some rips from DVD using MakeMKV. I’ve found sometimes there are odd lip sync issues when ripping with DVDFab that don’t show up with MakeMKV. (And vice versa - sometimes ripping with MakeMKV shows some odd sync issues that you don’t see with DVDFab.) When I get to ripping Blu-ray discs, MakeMKV will probably be my go-to.
  • DVD Profiler: I use this for tracking my movie collection. I like the interface and the well-curated metadata it provides. I also like the free online collection interface - it helps a lot while I’m at the store browsing for new stuff to make sure I don’t get any duplicates. Also helpful for insurance purposes.
  • Music Collector: I use this for tracking my music collection. The feature set is nice, though the metadata isn’t quite as clean. Again, big help when looking at new stuff to make sure I don’t get duplicates as well as for insurance purposes.
  • CrashPlan: I back up my music and photo collection using CrashPlan. I don’t have my movies backed up because I figured I can always re-rip from the original media… but with CrashPlan it’s unlimited data, so I could back it up if I wanted. CrashPlan runs on my MediaSmart home server right now; if I moved everything to Plex, I might switch CrashPlan to run on the DS1010+ instead.

Media Formats and Protocols

  • DLNA: I’ve been a fan from the start of DLNA, but the clients and servers just weren’t quite there when I started out. This seems to be much less problematic nowadays. The PS3 handles DLNA really well and I even have a DLNA client on my Android phone so I can easily stream music. This is super helpful in getting compatibility out there.
  • Videos are MP4: I started out with full DVD rips for video, but as I’ve moved to Plex I’ve switched to MP4. While it can be argued that MKV is a more flexible container, MP4 is far more compatible with my devices. The video codec I use is x264. For audio, I put the first track as a 256kbps AAC track (for compatibility) and make the second track the original AC3 (or whatever) for the home theater benefit. I blogged my settings info.
  • Audio is MP3, AAC, and Apple Lossless: I like MP3 and get them from Amazon on occasion, but I am still not totally convinced that 256kbps MP3 is the way and the light. I still get a little scared that there’ll be some better format at some point and if I bought the MP3 directly I won’t be able to switch readily. I still buy CDs and I rip those into Apple Lossless format. (Asset UPnP will transcode Apple Lossless for devices that need the transcoding; or I can plug the iPod/iPad in and play the lossless directly from there.) And I have a few AAC files, but not too many.

Media Organization

Videos are organized using the Plex recommendations: I have a share on the Synology DS1010+ called “video” and in there I have “Movies,” “TV,” and “Home Movies” folders. I have Plex associating the appropriate data scrapers for each folder.

/videos
    /Home Movies
        /2013
        /2014
            /20140210 Concert 01.mp4
            /20140210 Concert 02.mp4
    /Movies
        /Avatar (2009).mp4
        /Batman Begins (2014).mp4
    /TV
        /Heroes
            /Season 01
                /Heroes.s01e01.mp4
                /Heroes.s01e02.mp4

You can read about the Plex media naming recommendations here:

Audio is kept auto-organized in iTunes: I just checked the box in iTunes to keep media automatically organized and left it at that. The media itself is on a mapped network drive on the HP MediaSmart server and that works reasonably enough, though at times the iTunes UI hangs as it transfers data over the network.

Photos are organized in folders by year and major event: I’ve not found a good auto-organization method that isn’t just “a giant folder that dumps randomly named pictures into folders by year.” I want it a little more organized than that, though it means manual work on my part. If I have a large number of photos corresponding to an event, I put those in a separate folder. For “one-off photos” I keep a separate monthly folder. Files generally have the date and time in YYYYMMDD_HHMMSS format so it’s sortable.

/photos
    /2012
    /2013
    /2014
        /20140101 Random Pictures
            /20140104_142345 Lunch at McMenamins.jpg
            /20140117_093542 Traffic Jam.jpg
        /20140307 Birthday Party
            /20140307_112033.jpg
            /20140307_112219.jpg

Picasa works well with this sort of folder structure and it appears nicely in DLNA clients when they browse the photos by folder via Plex.

Network

My main router is a Netgear WNDR3700v2 and I love it. I’ve been through a few routers and wireless access points in the past but this thing has been solid and flexible enough with the out-of-the-box firmware such that I don’t have to tweak with it to get things working. It just works.

I have wired network downstairs between the office/servers and the main TV/PS3/Xbox 360/HTPC. This works well and is pretty much zero maintenance. I have two D-Link switches (one in the office, one in the TV room) to reach all the devices. (Here’s the updated version of the ones I use.)

The router provides simultaneous dual-band 2.4GHz and 5GHz wireless-N through the house which covers almost everywhere except a few corners. I’ve just recently added some Netgear powerline adapters to start getting wired networking upstairs into places where the wireless won’t reach.

The Road Ahead

This setup works pretty well so far. I’m really enjoying the accessibility of my media collection and I find I’m using it even more often than I previously was. So where do I go next?

  • Plex on Xbox 360: The only reason I still have that home theater PC in my living room is that it’s running the Plex app and if I want a nice interface with which to browse my movies, the HTPC is kinda the way to go. Plex has just come out with an app for Xbox One and should shortly be available for Xbox 360. This will remove the last reason I have an HTPC at all.
  • Add a higher-powered Plex server: My Synology DS1010+ does a great job running Plex right now, but it can’t transcode video very well. Specifically, if I have a high-def video and I want to watch it on my phone, the server wants to transcode that to accommodate for bandwidth constraints and whatnot… but the Synology is too underpowered to handle that. I’d like to see about getting a more powerful server running as the actual Plex server - store the data on the Synology, but use a different machine to serve it up, handle transcodingI, and so forth. (That little HTPC in the living room isn’t powerful enough, so I’ll have to figure something else out.)
  • Add wireless coverage upstairs: It’s great that I can hook the Xbox upstairs to wired networking using the powerline adapters but that doesn’t work so well for, say, my phone or the Chromecast. I’d like to add some wireless coverage upstairs (maybe chain another WNDR3700 in?) so I can “roam” in my house. I think even with the powerline stuff in there, it’d be fast enough for my purposes.
  • Integrate music into Plex: I haven’t tried the Plex music facilities and I’m given to understand that not all Plex clients support music streaming. This is much lower priority for me given my current working (and awesome) Asset UPnP installation, but it’d be nice long-term to just have one primary server streaming content rather than having multiple endpoints to get different things.

synology, security comments edit

A few months back Cory Doctorow stopped by the local library and did a great talk on security and copyright issues. Very cool stuff which inspired me to look into how to secure my public/open wifi usage.

I have a Synology DS1010+ with a ton of helpful packages and features on it, so that seemed like the best place to start. It took a while, but I got it. I’m going to show you how.

Truly, Synology has made this super easy. I’m not sure this would have been something I could have done nearly as easily without that device and the amazing Diskstation Manager “OS” they have on it. If you haven’t got one of their NAS devices, just go get one. I’ve loved mine since I got it and it just keeps getting more features with every DSM release they put out.

So, with that, the general steps are:

  • Set up user accounts on your Synology NAS.
  • Make your Synology NAS publicly accessible.
  • Add a proxy server to the NAS.
  • Add VPN support to the NAS.
  • Make sure the firewall and router allow the VPN to connect.
  • Configure your client (e.g., phone) to use the VPN and proxy.

I’ll walk you through each step.

Don’t skim and skip steps. I can’t stress this enough. Getting this up and running requires some virtual “planets to align” as it were, so if you skip something, the process will break down and it is kind of tough to troubleshoot.

You need to set up user accounts for people accessing the VPN. Chances are if you have your NAS set up already, you have these accounts - these are the same accounts you use to grant access to NAS files and other resources. There is a nice detailed walkthrough on the Synology site showing how to do this.

Now you need to set up your Synology NAS so you can access it from outside your home network. This is accomplished through a service called “dynamic DNS” or “DDNS.” But you don’t really need to know too much about that because, built right into the DSM interface, is a program called “EZ-Internet” that will do all the work for you. For the easiest solution, you’ll need to set up a user account with Synology, but that’s free… and if you use their DDNS system (a “synology.me” domain name) then that’s also free. They have a really super tutorial on getting this set up. Focus specifically on the EZ-Internet part of the tutorial - the QuickConnect stuff is neat and good to set up, but it won’t work for VPN usage.

It took me something like (seriously) five minutes to get this part working from start to finish. Some of the steps may seem “scary” if you’ve not set it up before, but Synology has made this really painless and if you don’t know what to do, accept the defaults. They’re good defaults.

When that’s done, you’ll see your DDNS setup in the Synology control panel under “External Access.”

The DDNS settings will show your NAS

Next, install the Proxy Server and VPN Server packages using the DSM Package Station package manager. Installing packages is a point-and-click sort of thing - just select them from the list of available packages and click “Install.” Make sure you set them as “Running” if they don’t automatically start up. Once they’re installed, you’ll see them in the list of installed packages.

Proxy Server and VPN Server packages installed

Let’s configure the proxy server. From the application manager (the top-left corner icon in the DSM admin panel) select the “Proxy Server” application. There isn’t much to this. Just go to the main “Settings” tab and…

  • Put your email address in the “Proxy server manager’s email” box.
  • Make a note of the “Proxy server port” value because you’ll need it later.

You can optionally disable caching on the proxy server if you’re not interested in your Synology doing caching for you. I didn’t want that - I wanted fresh data every time - so I unchecked that box. You can also optionally change the proxy server port but I left it as the default value provided.

Proxy server settings updated

Done with the proxy server! Close that out.

Now let’s configure the VPN server. This is a bit more complex than the proxy server, but not too bad.

Again from the application manager (the top-left corner icon in the DSM admin panel) select the “VPN Server” application.

On the “Overview” pane in the VPN server you you will start out showing no VPNs listed. Once you’ve finished configuring the VPN, you’ll see what I see - the NAS running the VPN and the VPN showing as enabled.

My overview tab after the VPN has been enabled

The VPN Server application offers several different VPN types to choose from. You can read about the differences on this article. I chose to use PPTP for my VPN for compatibility reasons - it was the easiest to get set up and running and I had some challenges trying to get different devices hooked up using the others. I am not specifically recommending you use PPTP, that’s just what I’m using. The steps here show how to set up PPTP but it isn’t too different to set up the other VPN types.

On the PPTP tab, check the “Enable PPTP VPN server” option. That’s pretty much it. That gets it working.

Check the PPTP enabled box

That’s it for the VPN configuration.

To allow people to connect to the VPN on the NAS, we need to set up the firewall on the NAS. In the Synology DSM control panel, go to the “Security” tab on the left, then select “Firewall” at the top. Click the “Create” button to create a new firewall rule.

Start creating a new firewall rule

When prompted, choose the “Select from a list of built-in applications” option on the “Create Firewall Rules” page. This makes it super easy - the DSM already knows which ports to open for the VPN server.

Select from a list of built-in applications

Scroll through the list of applications and check the box next to “VPN Server (PPTP)” to open the firewall ports for the VPN.

Select the VPN from the list of applications

The firewall settings will be applied and you’ll see it in the list of rules.

The last thing to do on the NAS is to set up the router port forwarding configuration. DSM can automatically configure your router right from the NAS to enable the VPN connection to come through.

In the DSM Control Panel, go to the “External Access” tab on the left and choose “Router Configuration” from the top. This is almost identical to the firewall configuration process. Click the “Create” button to add a new rule and you’ll be prompted to choose from a list of existing applications. Do that, and select the VPN server from the list.

Choose "Built-in application" and select the VPN

Once it’s configured, the DSM will issue some commands to your router and the rule will show up in the list.

The router rule in DSM control panel

That’s it for your server configuration! Now you have to connect your clients to it.

The rest of this walkthrough shows how I got my Android 4 phone connected to the VPN. I don’t have walkthroughs for other devices. Sorry.

Go to the main settings screen. From here, you’re going to choose “More settings.”

Choose "More settings"

Scroll down to the VPN settings and click that.

Choose "VPN"

For a PPTP VPN, select “Basic VPN” from the list.

Choose "Basic VPN"

Give your VPN a memorable name and put the DDNS name for your server in the “Server address” box.

Name your VPN and put the DDNS name as the server address

When you connect to the VPN you’ll be asked for a username and password. Use the username and password from your user account on the Synology NAS. (Remember that first step of setting up user accounts? This is why.)

The last configuration step is to set the proxy server. Android 4 has this hidden inside the wifi configuration for each wifi hotspot. For the hotspot you’re connected to, edit the settings and check the “Show advanced options” box. Fill in the proxy details using the local machine name of your NAS (not the DDNS name) and the proxy server port you have configured.

The proxy server configuration in the wifi hotspot

Now connect to the VPN and the wifi hotspot at the same time. Go back through the Settings => More settings => VPN path to find the VPN you configured. Connect to it and if you haven’t previously set up credentials you’ll be prompted. Connect to the wifi hotspot as well so it’s using the proxy server.

When you’re connected to both the VPN and the hotspot with the proxy settings, things work! You will see a little “key” at the top of the phone showing you’re connected to a VPN. You can pull up some VPN details from there.

The VPN details will show connection information

And here’s a screen shot of me surfing my blog through my VPN and proxy server, securely from an open wifi hotspot. Note the key at the top!

Secure browsing through VPN and proxy

I’m still working out a few things and may change my setup as time goes on, but this is the easiest DIY VPN/proxy setup I’ve seen.

Stuff I’d like to do next…

  • Switch from PPTP to a different VPN type (or maybe offer more than one VPN type so I can be compatible with devices requiring PPTP but offer better security for devices that can handle it).
  • Figure out if caching helps. I’ve found that some stuff is pretty fast, but other stuff is slow (or doesn’t flow quite right through the proxy). I’m not sure why that is. Maybe additional proxy settings I’m not aware of yet?

And, finally, again - thanks to Cory Doctorow for prodding me into researching this; and thanks to Synology for making it easy. Part of what Doctorow was saying at his visit is that Security is Hard, particularly the implementation of decent security for the lay person. Synology is as close to point-and-click easy setup as I’ve ever seen for this.

If you’re looking for one of these devices, the Synology DS214se is pretty budget-friendly right now, though the Synology DS414j might give you a little room to grow. I have the DS1010+, which is basically the previous model of the Synology DS1513+, which is more spendy but is super extensible. All of the Synology products run the DSM so you really can’t go wrong.

UPDATE 8/14/2015: I’ve moved to an OpenVPN-based VPN (still hosted by my Synology Diskstation) and no longer need the proxy. I’ve added some instructions on how to get that working as well as how to make your Android device auto-connect to it when not on a trusted network.

powershell, teamcity comments edit

We have a nice TeamCity build server at work and we somewhat-recently updated it to use a MySQL database instead of XML for the data storage (like for the VCS roots).

We have a number of service accounts we use for interacting with the version control systems and they periodically need their passwords changed. It used to be that we could modify the XML document search-and-replace style, but now it’s hidden in the database somewhere and is less straightforward to update.

Thankfully, TeamCity offers a REST API you can work with, so I decided to play with PowerShell and the Invoke-RestMethod command to automate the drudgery of going through the something-like-50 VCS roots we have defined and updating the passwords for selected accounts.

Here’s the code for a small one-function module:

<#
.Synopsis
   Updates the password for a user account in TeamCity associated with VCS root entries.
.DESCRIPTION
   Iterates through the VCS roots defined in TeamCity and updates the password associated with the specified user for all VCS roots.
.EXAMPLE
   $credential = Get-Credential
   Update-TeamCityVcsAccount -TeamCityUrl "http://your-teamcity-dash/" -TeamCityCredential $credential -VcsUserName "serviceaccount" -VcsPassword "TheNewPassword"
.NOTES
   This command uses the TeamCity REST API to iterate through the VCS roots and update the password for matching accounts.
#>
function Update-TeamCityVcsAccount
{
    [CmdletBinding()]
    Param
    (
        # The URL to the TeamCity dashboard.
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$false)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [Uri]
        $TeamCityUrl,

        # The credentials of the TeamCity administrator account to make changes.
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$false)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [PSCredential]
        $TeamCityCredential,

        # The username of the VCS user that should be updated.
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$false)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [String]
        $VcsUserName,

        # The new password for the VCS user.
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$false)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [String]
        $VcsPassword
    )

    Begin
    {
        $updated = @()
        $progressActivity = "Updating VCS root passwords for $VcsUserName..."
    }
    Process
    {
        $vcsRootsUri = New-Object -TypeName System.Uri -ArgumentList $TeamCityUrl, "/httpAuth/app/rest/vcs-roots"
        $allRoots = Invoke-RestMethod -Uri $vcsRootsUri -Method Get -Credential $credential
        foreach($href in $allRoots.'vcs-roots'.'vcs-root'.href)
        {
            $rootHref = New-Object -TypeName System.Uri -ArgumentList $TeamCityUrl, $href
            $vcsRoot = Invoke-RestMethod -Uri $rootHref -Method Get -Credential $credential
            $currentVcsUserName = $vcsRoot.'vcs-root'.properties.property | Where-Object { $_.name -eq "user" } | Select-Object -ExpandProperty "value"
            if($currentVcsUserName -ne $VcsUserName)
            {
                continue;
            }

            # secure:svn-password == Subversion Repo
            # secure:tfs-password == TFS Repo
            # Making the assumption all the password fields have this
            # name format...
            $propToChange = $vcsRoot.'vcs-root'.properties.property  | Where-Object { ($_.name -like 'secure:*') -and ($_.name -like '*-password') }  | Select-Object -ExpandProperty "name"
            $propHref = New-Object -TypeName System.Uri -ArgumentList $rootHref, "$href/properties/$propToChange"

            Write-Progress -Activity $progressActivity -Status "VCS root: $href"
            Invoke-RestMethod -Uri $propHref -Method Put -Credential $credential -Body $VcsPassword | Out-Null
            $updated += $propHref;
        }
    }
    End
    {
        Write-Progress -Activity $progressActivity -Completed -Status "VCS roots updated."
        return $updated
    }
}

Export-ModuleMember -Function Update-TeamCityVcsAccount

Save that as TeamCity.psm1 and then you can do this:

Import-Module .\TeamCity.psm1
$credential = Get-Credential
Update-TeamCityVcsAccount -TeamCityUrl "http://your-teamcity-dash/" -TeamCityCredential $credential -VcsUserName "serviceaccount" -VcsPassword "TheNewPassword"

When you run Get-Credential you’ll be prompted for some credentials. Enter your TeamCity username and password. Fill in the appropriate values for the parameters and you’ll see progress rolling by for the password updates. The return value is the list of VCS root URLs that got updated.

Now that I have a reasonably-working pattern for this, it should be easy enough to use the REST API on TeamCity to automate other common admin tasks we do. Neat!

vs, azure comments edit

I have an MSDN subscription at work which comes with some Azure services like virtual machines. I’m using one of these VMs to explore the VS 14 CTP.

The problem is… port 3389 isn’t open through the firewall at work, so using the default port for Terminal Services doesn’t work for me.

Luckily, you can change the port your VM uses for Terminal Services. Knowing I won’t be hosting a web site here, changing to port 80 makes it easy.

First, open up the VM in the Azure Portal and click the “Settings” button.

Click the Settings button on the VM

Now click the “Endpoints” entry on the list of settings.

Click Endpoints in the settings menu

We want the public port for Terminal Services to be port 80. Click the Terminal Services entry to edit it.

We want TS on port 80

Update the public port to 80 and click the Save button at the top.

Update the public port to 80

Now go back to the main VM dashboard and click the “Connect” button.

Click the Connect button

A small .rdp file will download. If you open it in a text editor it will look like this:

full address:s:yourmachine.cloudapp.net:3389
prompt for credentials:i:1

Change that port at the end to 80.

full address:s:yourmachine.cloudapp.net:80
prompt for credentials:i:1

Save that and double-click the file to start a Terminal Service session. Boom! Done.

autofac, github comments edit

All Autofac documentation has moved to our official documentation site at http://autofac.readthedocs.io/.

Since moving from Google Code to GitHub we’ve had documentation spread all over, some of which was getting pretty stale from not being maintained. We wanted to get control over that and set a good stage going forward, so we consolidated everything to our site on Read the Docs.

Doing this provides a lot of benefit:

  • Documentation is searchable.
  • You can get the docs in multiple formats (online, PDF, epub).
  • Docs are readable on a mobile browser.
  • We can start versioning the documentation.
  • We can update docs in one spot, inside the source tree, and not worry about wikis all spread out getting stale.

As part of this, you will see some changes to our wikis:

  • All of the pages in our GitHub wiki have been removed except for the release notes pages. We’ll only be maintaining release notes in the wiki. If you want docs, you need to go to the doc site. This may break some links in things like StackOverflow answers, but the other choice was to keep a bunch of placeholder redirect pages in place, which would be just painful to maintain. Instead we ripped the bandage off.
  • All of the pages in the Google Code wiki have been cleared out and replaced with some text pointing to the new documentation location. There are a substantially larger number of articles and answers linking to the old wiki and that wiki doesn’t change anymore so putting some pseudo-redirects in there was a simple one-time effort.

Apologies if this causes some issue with broken links.

It’s taken a long time to get here, but we think this will provide a better documentation experience for everyone now and going forward.