Tag Archives: lego

PowerShell Brickset Module – Part 3: Working with the Inventory

In part 1 of this series, we looked at how to get started with the Brickset module. In part 2 we examined how to easily download sets of instructions. Now in part 3 I’ll show you how to use the inventory features of Brickset.

When you are logged into the Brickset website you can use the inventory features to help keep track of your collection. For example if you look at a particular set, you can mark the number of copies of that set you own, or if you don’t own it, mark it down as a set that you want:

Also at the top of the page you’ll see a summary of the number of sets owned and wanted. Each is a clickable hyperlink which will provide you with a nice view of what you own or are looking to get hold of.

Included in the PowerShell Brickset module are a set of functions for working with this functionality. First of all Get-BricksetCollectionTotals will give an overview on existing totals:

Get-BricksetSetOwned will give details on owned sets:

Get-BricksetSetWanted will give details on sets wanted:

Of course these are only useful if you have already populated your Brickset Inventory via the website. While it’s a pretty simple experience in the website to do that for individual sets, there could be a lot of clicking to do if you have a large amount of sets to upload. Step forward Set-BricksetSetOwned. In it’s simplest form, to add one set:

Before:

After:

(Note: I don’t think the ‘xxx people own this set’ stat updates instantly whether you update your set ownership via the website or the API)

Let’s say we now want to do a bulk upload of everything we own and we have a data set of our Lego sets contained in Excel. We could take that data and fire it at Set-BricksetSetOwned to do the bulk update. Here’s an example CSV file with a small amount of data to illustrate the process:

and the following code will mark each of those sets as owned, with the number owned as the quantity:

and now our collection is starting to look a bit more respectable:

 

All that’s left for me to do is get a list of all of my owned sets into that CSV file and uploading to Brickset will take just a few seconds 🙂

PowerShell Brickset Module – Part 2: Downloading Instructions

In part 1 of this series, we looked at how to get started with the Brickset module. In part 2 we’ll take a look at how to easily download sets of instructions.

It may be the case that you have lost the set of instructions for a Lego set or perhaps you have got hold of a set secondhand that didn’t have the instructions to accompany it. It’s possible to do that for an individual set via the Lego website, but with this Brickset module you can do it from the comfort of your own PowerShell session, which can be particularly handy if you need to get more than just one set of instructions.

In its simplest form you can do this for a single set :

which gives you back two URLs. The first is for part 1 of the instructions, the second for part 2 – sometimes the larger sets ship with multiple instruction books.

You could of course paste these URLs into your browser to download them, but an easier way would be this:

which will produce this in your default browser, a tab for each pdf:

This is quite handy, but you’ve still probably got to save them away manually into a folder somewhere for future reference.

Let’s take this a step futher. By using the Theme parameter of Get-BricksetSet and a native PowerShell cmdlet Start-BitsTransfer we can download the sets of instructions for an entire  Lego theme into a specified folder:

🙂

 

PowerShell Brickset Module – Part 1: Getting Started

I recently gave my PowerShell Brickset Module a much needed overhaul, so thought it was worth putting a few posts out on how it works and what you can do with it. In part 1 we’ll look at getting started, including download and installation.

Brickset is an extremely useful site for keeping up-to-date with Lego based news and managing your own collection of brick based goodness. In addition to the browser based content, they also offer a SOAP based API.  My PowerShell Brickset Module takes advantage of this API and provides a number of functions for working with different parts of the site. The recent overhaul of the module includes functions for working with the inventory side of things, i.e. the part which requires a login – the previous version was based only around functions which needed an API key.

Brickset Requirements

To take advantage of all of the module functions you will require both a Brickset account and an API key. Fill out the form here  for an API key and they will send you one. Currently they are free.

Installation

The easiest way to install the Brickset module is to use PowerShell v5 and get it from the PowerShell Gallery. To do that is a single command:

otherwise you can get it from Github, instructions in the previous post.

Once installed, import the module and check out the available commands:

Brickset Connection

One of the new functions in this release is Connect-Brickset. This replaces Set-BricksetAPIKey and handles the API key, the User login (if supplied) and the Webservice connection. Run Connect-Brickset and both your API key and user login will be available for all connections in the session, stored via the $BricksetConnection variable:

Use Cases

You can still do all of the same things as in the previous release, such as getting the number of Lego sets per theme:

To drill down into detailed information for a range of sets, we could do something like this:

In part 2 we will look at getting hold of instruction PDFs and Part 3 onto some of the new functions that require a login for managing your inventory…..

PowerShell Module for the Brickset API

Brickset.com is one of my favourite sites for finding info about Lego sets and keeping up-to-date with Lego news. I noticed recently that they had an API so I thought I would check it out. I posted a while back on how to do some similar stuff with other websites, but some of the functionality on those websites is no longer available.

This module for Brickset data contains functions for finding information about Lego sets and also makes it possible to download instruction manuals which can be pretty helpful if you have lost one of them or buy a 2nd hand set without the manuals.

1) Installation

Download the module from Github, ensure the files are unblocked and copy it to one of your PowerShell module folder paths. For me that is C:\Users\jmedd\Documents\WindowsPowerShell\Modules .

PSLego01

If you’ve done it successfully then you should be able to see details of the module with Get-Module:

Get-Module Brickset -Listavailable

PSLego02

You can take a look at the commands available by importing the module and then using Get-Command:

Import-Module Brickset

Get-Command -Module Brickset


PSLego03

 

2) Get a Brickset API Key

To use the Brickset API you need to first of all register for an API key. Fill out the form here and they will send you one. Currently they are free.

All of the Get-* functions in the module require you to use the API key; you won’t get very far without one.

3) Set a Global Variable for the API Key

Each of the Get-* functions has an APIKey parameter. However, to make things easier to use I’ve also added the Set-BricksetAPIKey function which will create a global variable for the API key that will be valid for the duration of that PowerShell session. If you don’t supply an API key to the Get-* functions then they will look for the global key having been set.

So the best thing to do is run this function first, with your API key, to set the API key variable:

Set-BricksetAPIKey -APIKey 'ed4w-KQA2-1Ps2' -Confirm:$false

PSLego04

 

4) Getting All Lego Sets by Theme

First example of using one of the Get-* functions is Get-BricksetTheme and Get-BricksetSet. Together they can be used to retrieve a list of Brickset Themes and then the sets in a theme. So let’s take a look at the example:

First of all, use Get-BricksetTheme to retrieve all available Themes from the Brickset site (remember you don’t need to specify the API key if it has already been set:

Get-BricksetTheme | Format-Table Theme,SetCount -AutoSize

PSLego05

Now say we want to retrieve all of the sets for the Indiana Jones theme we can use Get-BricksetSet with the Theme parameter:

Tip: You can use the OrderBy parameter to sort by a particular value. This may be more efficient than piping it through to Sort-Object afterwards:

Note: there is a lot more information available for each set than displayed here. I’ve restricted the output to a few key properties.

Get-BricksetSet -Theme 'Indiana Jones' -OrderBy Pieces | Format-Table Name,Number,Theme,SubTheme,Year,Pieces -AutoSize

PSLego06

5) Getting All Lego Sets by Theme and Year

If you want the search to be more specific then you can specify multiple search criteria. For instance one of the largest ranges is the Star Wars theme. Let’s have a look and see what sets have been released this year so far:

Get-BricksetSet -Theme 'Star Wars' -Year 2015 -OrderBy Pieces | Format-Table Name,Number,Theme,SubTheme,Year,Pieces -AutoSize

PSLego07b

 

6) Get a Specific Set by Set Number

All Lego sets are assigned a number by Lego. Use the SetNumber parameter of Get-BricksetSet to retrieve details of a specific set.

Note: the API requires that you supply the set number in the format {number}-{variant}, e.g. 7199-1. If you see the number on the front of the box as say 7199, typically you will need to use 7199-1 for the first variant of that set. However, be careful as this will not always be the case.

PSLego08

Get-BricksetSet -SetNumber '7199-1'

PSLego09

 

7) Download Lego Set Instructions

The function Get-BricksetSetInstructions will return URLs for links to the set’s instructions on the Lego.com website.

Note: the parameter to use is SetId not SetNumber. SetId is Brickset’s own reference number for the set and not the Lego Set Number we used in the previous example. Use Get-BricksetSet to find this info first. I’ve used PowerShell pipeline parameter binding in the functions so that you can do this easily:

Get-BricksetSet -SetNumber '7199-1' | Get-BricksetSetInstructions

PSLego10

Note: this example returned two pdfs, since it is a large set and had two printed manuals in the box.

If you want to open them straight into your web browser of choice you could do this:

Get-BricksetSet -SetNumber 7199-1 | Get-BricksetSetInstructions | Select-Object -ExpandProperty url | Foreach-Object {Invoke-Expression “cmd.exe /C start $_”}

or if you wanted to say download all of the instructions for a particular theme you could do this using the built-in Windows cmdlet Start-BitsTransfer:

Get-BricksetSet -Theme 'Indiana Jones' | Get-BricksetSetInstructions | Select-Object -ExpandProperty url | ForEach-Object {$file = ($_.split('/'))[-1]; Start-BitsTransfer -Source $_ -Destination "C:\Users\jmedd\Documents\$file"}

 

8) Other Module Functions

There are a few other functions in the module for finding information around Images, Set Reviews and Recently Updated Sets.

I hope you have fun with this module 🙂

 

Downloading Single or Entire Ranges of Lego Set Instructions with PowerShell

Update 20/07/2015:

The details in this post are now superseded by a post I have made using the Brickset API.

———————————————————————————————————————-

I’ve always enjoyed Lego and it’s currently experiencing a resurgence in our house thanks to strategic hinting encouragement that my children would find it fun too. (It seems like I’m not the only one)

What does tend to happen though is that as sets are pulled apart played with we often need to dig out the instructions to put entire sets pieces back together again. Although I carefully file any instructions from sets we purchase, often it’s easier to download them as pdfs from the Lego website and view them on a tablet and sometimes we buy them 2nd hand without instructions so need to download them anyway.

The official Lego website is pretty good for making these available, even for sets which were released a long time ago, but I particularly like BrickInstructions.com since they make it very easy to find links on the official Lego site to the particular instructions you need and also display the instructions on their own site.

As our collection of sets grew I was manually downloading a copy of the instructions for each one to store for quick reference, then I figured why not just download the whole lot for the particular ranges we are interested in, so that I’ve always got any of them. Naturally I was not going to do that manually……

So the following two PowerShell functions will enable you to download either single, multiple or an entire range of Lego set instructions via the links provided by BrickInstructions.com. The download requests are submitted via a single BITS Transfer job so make good use of available bandwidth, handle network interruptions etc…

Note: Some of the code in these functions requires PowerShell v3 

If you already know the Lego set numbers you can use the first function Get-LegoSetInstructions like this:

9488,7655,7656 | Get-LegoSetInstructions -DestinationFolder "C:\Lego\Instructions\Star Wars" -Verbose

Lego1

The files hosted on  the Lego website are named with a generic number code, so I change this with each download to the name and number of the set so that they are easy to find once downloaded:

Lego2

function Get-LegoSetInstructions {
<#
 .SYNOPSIS
 Function to download Lego Set Instructions.

 .DESCRIPTION
 Function to download Lego Set Instructions.

 .PARAMETER ID
 Lego set to download instructions for

.PARAMETER Link
 Link to Lego set instructions page

.PARAMETER DestinationFolder
 Folder to save the instructions in

.PARAMETER Force
 Overwrite an existing instructions file if it already exists

.INPUTS
 String

.OUTPUTS
 None.

.EXAMPLE
 PS> Get-LegoSetInstructions -ID 9488 -DestinationFolder "C:\Lego\Instructions"

.EXAMPLE
 PS> 9488,7655,7656 | Get-LegoSetInstructions -DestinationFolder "C:\Lego\Instructions"

.EXAMPLE
 PS> Get-LegoSetInstructions -Link "http://lego.brickinstructions.com/instructions.php?code=10212&amp;set=Imperial Shuttle" -DestinationFolder "C:\Lego\Instructions"

.NOTES
 Version: 1.0 - First draft
 Date: 17/04/2013
 Tag: lego,download,BITS
#>
[CmdletBinding(DefaultParametersetName="ID")]

Param (

 [parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName="ID")]
 [ValidateNotNullOrEmpty()]
 [String[]]$ID,

[parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="Link")]
 [ValidateNotNullOrEmpty()]
 [String[]]$Link,

 [parameter(Mandatory=$true)]
 [ValidateNotNullOrEmpty()]
 [String]$DestinationFolder,

[parameter(Mandatory=$false)]
 [Switch]$Force
 )

 begin {

$ErrorActionPreference = 'Stop'
 Write-Debug $MyInvocation.MyCommand.Name
 $LegoSetObject = @()

# --- Test for the existence of the BITS transfer module
 if (!(Get-Module BitsTransfer -ListAvailable)){

 throw "BITS Transfer module not available. Run from a system with this module"
 }

# --- Test for the existence of the Destination Folder
 if (!(Test-Path $DestinationFolder)){

 throw "Destination Folder $DestinationFolder does not exist"
 }
 }

process {

switch ($PsCmdlet.ParameterSetName)
 {
 "ID" {

 foreach ($Set in $ID){

 # --- Retrieve the web page for the Lego instructions
 $url = Invoke-WebRequest "http://lego.brickinstructions.com/instructions.php?code=$Set"

# --- Find links that contain pdfs. There may be multiple for different print formats on newer modelss
 if ($PDFLink = $url.Links | Where-Object {$_.outerHTML -like '*pdf*'} | Select-Object -First 1){

$Description = $url.ParsedHtml.nameProp
 $Output = Join-Path -Path $DestinationFolder -Childpath ($Description + ".pdf")

$Object = [pscustomobject]@{

 LegoSet = $Set
 Description = $Description
 DownloadLink = $PDFLink.href
 Output = $Output
 }
 $LegoSetObject += $Object

}
 else {
 Write-Warning "No instructions for Lego Set $Set were found"
 }
 }
 }

"Link" {

foreach ($href in $Link){

 # --- Retrieve the web page for the Lego instructions
 $url = Invoke-WebRequest $href

 # --- Pick out the set number from the link
 $href -match ".*?(?<Set>\d+)" | Out-Null
 $Set = $Matches.Set

# --- Find links that contain pdfs. There may be multiple for different print formats on newer modelss
 if ($PDFLink = $url.Links | Where-Object {$_.outerHTML -like '*pdf*'} | Select-Object -First 1){

$Description = $url.ParsedHtml.nameProp
 $Output = Join-Path -Path $DestinationFolder -Childpath ($Description + ".pdf")

$Object = [pscustomobject]@{

 LegoSet = $Set
 Description = $Description
 DownloadLink = $PDFLink.href
 Output = $Output
 }
 $LegoSetObject += $Object
 }
 else {
 Write-Warning "No instructions for Lego Set $Set were found"
 }
 }
 }
 }
 }

end {
 # --- If no Force parameter, then filter the downloads to those that don't already exist
 if (-not ($PSBoundParameters.ContainsKey('Force'))){

$LegoSetObject = $LegoSetObject | Where-Object {-not (Test-Path $_.Output)}
 }

# ---
 $Job = Start-BitsTransfer -Source $LegoSetObject.DownloadLink -Destination $LegoSetObject.Output -Asynchronous

 Write-Verbose "Checking the status of the BITS transfer download job...."

while (($Job.JobState -eq "Transferring") -or ($Job.JobState -eq "Connecting")){

 Write-Verbose "BITS Transfer job is still downloading...."
 Start-Sleep 10}

switch ($Job.JobState){

"Transferred" {Complete-BitsTransfer -BitsJob $Job}
 "Error" {Write-Warning "BITS transfer has failed..." }
 default {Write-Warning "Please investigate download for Lego Set "}
 }
 Write-Verbose "BITS transfer download job has completed...."

Write-Output $LegoSetObject
 }
}

If you don’t know the set number or want an entire range then you can use the Get-LegoSetLink function to generate links to the pages on the BrickInstructions.com website for all of the Lego sets in that range. The list of possible ranges are on the left-hand side of the site.

Lego4

So to get the Harry Potter range:

Get-LegoSetLink -Range "Harry Potter"

Lego3

The Get-LegoSetInstructions function will also take hyperlinks as input, so to get an entire range of instructions downloaded you can do this:

Get-LegoSetLink -Range "Harry Potter" | Get-LegoSetInstructions -DestinationFolder "C:\Lego\Instructions\Harry Potter" -Verbose

Lego5

Lego6

Lego7

function Get-LegoSetLink {
<#
 .SYNOPSIS
 Function to retrieve Lego Set Links from supplied Lego range.

 .DESCRIPTION
 Function to retrieve Lego Set Links from supplied Lego range.

 .PARAMETER Range
 Range of Lego sets to retrieve links for

.INPUTS
 String

.OUTPUTS
 None.

.EXAMPLE
 PS> Get-LegoSetLink -Range "Star Wars"

.NOTES
 Version: 1.0 - First draft
 Date: 18/04/2013
 Tag: lego,link
#>
[CmdletBinding()]

Param (

 [parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [ValidateNotNullOrEmpty()]
 [String]$Range

)

begin {

$ErrorActionPreference = 'Stop'
 Write-Debug $MyInvocation.MyCommand.Name
 $LegoLinkObject = @()
 }

process {

 # --- Retrieve the web page for the Lego instructions
 $EndUrl = ("lego_" + ($Range -replace " ", "_") + ".php").ToLower()
 $url = Invoke-WebRequest "http://lego.brickinstructions.com/$EndUrl"

# --- Find the Lego set links
 if ($LegoSets = $url.links | Where-Object {$_.href -like '*set=*'}){
 foreach ($LegoSet in $LegoSets){

$Object = [pscustomobject]@{

 Description = $LegoSet.innerHTML
 Link = "http://lego.brickinstructions.com/" + $LegoSet.href
 }
 $LegoLinkObject += $Object
 }

# If there are additional pages, e.g. for large ranges, cycle through each page to find all of the sets
 if ($AdditionalPages = $url.links | Where-Object {$_.href -like '*page=*'} | Where-Object {$_.innerhtml -match "\d+"} | Select-Object innerhtml,href -Unique){

foreach ($Page in $AdditionalPages){

$AdditionalPageURL = "http://lego.brickinstructions.com" + $Page.href
 $url = Invoke-WebRequest $AdditionalPageURL

$LegoSets = $url.links | Where-Object {$_.href -like '*set=*'}

foreach ($LegoSet in $LegoSets){

$Object = [pscustomobject]@{

 Description = $LegoSet.innerHTML
 Link = "http://lego.brickinstructions.com/" + $LegoSet.href
 }
 $LegoLinkObject += $Object
 }
 }
 }
 }
 else {

Write-Warning "No sets are available for this range"
 }
 }
 end {
 Write-Output $LegoLinkObject
 }

}

Accio Instructions!

 

4736-harry-potter-minifigure