Better Pipe Organ Database


How Better Pipe Organ Database Works

The website that you are visiting is an alternative front-end to the Pipe Organ Database. You may be wondering how this website works and why I decided to create this. The question of why is explained in About Better Pipe Organ Database. As for the technical details, see below.

As you will find, this website uses the same database as the Pipe Organ Database. This website just parses the information and displays it slightly differently.

All of the following information was found by me by reverse-engineering the behavior of Pipe Organ Database by inspecting scripts that are run by the web browser and network connections and requests made by the browser while using the Pipe Organ Database.

API

With the refactoring of the Pipe Organ Database, the user's web browser downloads javascript files that run locally to generate pages. The web browser communicates with the Pipe Organ Database via api.pipeorgandatabase.org and receives information in JSON format, which is easy parsable by the computer.

$ curl https://api.pipeorgandatabase.com/instruments/12467
{
    "id": 12467,
    "room": null,
    "opusPrefix": null,
    "opus": 2547,
    "opusSuffix": null,
    "yearPrefix": null,
    "year": 1972,
    "yearSuffix": null,
    "originalOpusPrefix": null,
    "originalOpus": null,
    "originalOpusSuffix": null,
    "originalYearPrefix": null,
    "originalYear": null,
    "originalYearSuffix": null,
    "conventionYears": null,
    . . .

Typicaly when an API is made available, there is a documentation that the programmer can use to understand what all of the variables mean. However, for the Pipe Organ Database there was no such documentation. For Better Pipe Organ Database, the API was reverse-engineered, looking through many entries in the database to see how the variables are used. Some aspects presented challenges, such as "opusPrefix" and "opusSuffix".

The Pipe Organ Database website uses javascript to make requests to the API from the web browser. On the other hand, Better Pipe Organ Database uses PHP to make calls to the API from the web daemon to generate the page and send it to the web browser as a completely static HTML document. My thoughts on server-generated vs. javascript websites can be found in the about page for this website.

Stoplists

One area which presents particular challenges is the area of stoplists. In the API response for an organ, the stoplist is not included; instead, an ID number pointing to the stoplist is found.

$ curl https://api.pipeorgandatabase.com/instruments/12467
{
    . . .
    "stoplists": [
        {
            "id": 21867,
            "type": 1,
            "source": "Source not recorded",
            "filename": "bW6C7w_NJWestfield.FirstCongrtnl.1970Austin.stoplist01.txt",
            "description": "Stoplist from the dedication program, courtesy of Frederick Swann",
    . . .

$ curl https://api.pipeorgandatabase.org/uploads/stoplists/bW6C7w_NJWestfield.FirstCongrtnl.1970Austin.stoplist01.txt
       Westfield, New Jersey
       First Congregational Church

       Austin   Op. 2547   1970   2/31
       _________________________________________________________________

       GREAT                SWELL                        PEDAL
   16' Quintaten     61    8' Rohrflöte      61      16' Contre Basse 32
   . . .

Pipe Organ Database handles stoplists using inline frames, in which an embedded HTML document is used so that the browser gets the stoplist in a separate HTTP request (the previous user interface did this in the same way). For Better Pipe Organ Database, I decided to not use inline frames.

When reading the API response, if the BPOD daemon finds a type 1 stoplist (text), it makes a second request to the address of the file ("filename" above). After downloading this file, the daemon pastes the stoplist directly into the HTML document itself (instead of an inline frame) in a pre-formatted block.

On the other hand, a type-0 stoplist (JSON) presents a different set of difficulties, as the stoplist is stored in JSON format and must be generated, rather than simply displaying a text document. Further complicating things is the stoplist is stored in a rather obtuse way, which makes it difficult even to understand.

$ curl https://api.pipeorgandatabase.org/instruments/50004
    . . .
    "stoplists": [
        {
            "id": 40,
            "type": 0,
            "source": "From the builder's website",
            "filename": null,
            . . .

$ curl https://api.pipeorgandatabase.org/stoplists/40
{
    "id": 40,
    "type": 0,
    "source": "From the builder's website",
    "filename": null,
    . . .
    "stops": [
        {
            "id": 1007,
            "name": "Violone",
            "altName": null,
            "from": null,
            "to": null,
            "division": "GREAT",
            "extendedFrom": null,
            "length": "16",
            "pipes": null,
            "numRanks": null,
            "windPressure": null,
            "isReed": 0,
            "isUnisonOff": 0,
            "isPrepared": 0,
            "isDigital": 0,
            "notes": "",
            "order": 0,
            "createdAt": "2024-01-17T18:27:48.000Z",
            "updatedAt": "2024-01-17T18:27:48.000Z",
            "stoplistId": 40,
            "builderId": null
        },
        {
            "id": 1008,
            "name": "Principal",
            "altName": null,
            "from": null,
            "to": null,
            "division": "GREAT",
            . . .
        {
            "id": 1035,
            "name": "Bourdon",
            "altName": null,
            "from": null,
            "to": null,
            "division": "SWELL",
            . . .

All of the stops of the entire organ are grouped in one "directory" in the JSON file, with one attribute "division" saying where the stop is located.

BPOD displays type-0 stoplists in a way that is inspired by http://www.orgbase.nl, in which each division is written on one line with the stops written one after another. First, the BPOD daemon iterates through all the stops, placing them into an array based on the "division". Afterwards, it iterates through each division, printing out the stops.

The type-0 stoplists are perhaps the hardest part of the Pipe Organ Database to reverse-engineer. Even more specifics are not yet known to me. Some notes for the stops include bounding parentheses, others do not. The way that couplers are represented seems to differ from one type-0 stoplist to the next. Similarly, the way that mixtures are represented presents challenges; many times it seems that the number of ranks is written in roman numerals in the "length" and in arabic numerals in "numRanks"; other times, the "length" is the length of the longest pipe. Many pieces of information from type-0 stoplists are not accounted for in the way that stoplists are currently displayed on BPOD, such as the number of pipes per stop.

Images

Images are embedded in the HTML document. BPOD directly links to the image on Pipe Organ Database instead of downloading it and sending it from the BPOD daemon.

$ curl https://api.pipeorgandatabase.org/instruments/12467
    . . .
    "images": [
        . . .
        {
            "id": 20197,
            "type": 8,
            "name": "Church exterior",
            "filename": "Puw01Q_aa393e6c40db4b73a63ae2170eed63eb_west_082121.jpg",
            "thumbFilename": "Puw01Q_thumb_Puw01Q_aa393e6c40db4b73a63ae2170eed63eb_west_082121.jpg",
            "fullThumbFilename": "Puw01Q_fullthumb_Puw01Q_aa393e6c40db4b73a63ae2170eed63eb_west_082121.jpg",
            "isPanoramic": false,
            . . .

$ curl https://api.pipeorgandatabase.org/uploads/images/Puw01Q_aa393e6c40db4b73a63ae2170eed63eb_west_082121.jpg
[image]

-William Rehwinkel, December, 2024.