├── Procfile ├── package.json ├── LICENSE ├── server.js └── README.md /Procfile: -------------------------------------------------------------------------------- 1 | web: node server.js 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "baditicker", 3 | "version": "1.0.2", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "request": "^2.57.0", 13 | "restify": "^3.0.3", 14 | "xml2js": "^0.4.9" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Martin Naumann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var restify = require('restify'), 2 | request = require('request'), 3 | parseXml = require('xml2js').parseString 4 | 5 | function listPools(req, res, next) { 6 | res.header('Access-Control-Allow-Origin', '*') 7 | res.header('Content-Type', 'application/json; charset=utf-8') 8 | request('https://www.stadt-zuerich.ch/stzh/bathdatadownload', function(err, response, data) { 9 | parseXml(data, function(err, poolData) { 10 | var baths = poolData.bathinfos.baths, 11 | pools = {pools: []} 12 | for(var i=0, len = baths.length; i= 0 ? false : true, 21 | openText: bath.openClosedTextPlain[0], 22 | url: bath.urlPage[0] 23 | }) 24 | } 25 | } 26 | res.json(pools) 27 | next() 28 | }) 29 | }) 30 | } 31 | 32 | var server = restify.createServer() 33 | server.get('/', listPools) 34 | server.listen(process.env.PORT || 8080, function() { 35 | console.log('%s listening at %s', server.name, server.url) 36 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # baditicker-api 2 | Using the public pool open data from Stadt Zürich as a JSON-API, CORS-enabled! 3 | 4 | # API 5 | This is a simple, stupid API with a single endpoint: `GET /`. 6 | 7 | Sending a GET request to [https://baditicker.herokuapp.com/](https://baditicker.herokuapp.com/) you'll receive a response like this: 8 | 9 | ```json 10 | { 11 | "pools": [{ 12 | "name": "Flussbad Au-Höngg", 13 | "temperature": 17, 14 | "updatedAt": "Mi, 10.06.2015 11:02", 15 | "open": false, 16 | "openText": "geschlossen", 17 | "url": "http://www.stadt-zuerich.ch/content/ssd/de/index/sport/schwimmen/sommerbaeder/flussbad_au_hoengg.html" 18 | }, 19 | { 20 | "name": "Flussbad Oberer Letten", 21 | "temperature": 18, 22 | "updatedAt": "Mi, 10.06.2015 08:20", 23 | "open": true, 24 | "openText": "geöffnet bis 13:00", 25 | "url": "http://www.stadt-zuerich.ch/content/ssd/de/index/sport/schwimmen/sommerbaeder/flussbad_oberer_letten.html" 26 | }] 27 | } 28 | ``` 29 | 30 | Here's what each field means: 31 | 32 | | Field name | Description | Type | 33 | | --- | --- | --- | 34 | | name | A human-readable name of the pool | String | 35 | | temperature | The water temperature | Float | 36 | | updatedAt | A datetime containing the last update of the record for this pool | DateTime | 37 | | open | Indicates if this pool is currently open or closed | Boolean | 38 | | openText | Gives the raw text from the pool website, including information such as "open until 13:00" | String | 39 | | url | The web address of the official website for the pool | String | 40 | 41 | ## Contributing 42 | 43 | If you find a bug or want to change the data that the API exposes, please open an issue or a pull request. 44 | The codebase follows the [NPM Coding Style Standard](http://npmjs.org/standard). 45 | 46 | ## License 47 | 48 | * The code is MIT licensed. 49 | * The [original data source](https://www.stadt-zuerich.ch/portal/de/index/ogd/daten/wassertemperaturen_freibaeder.html#description1) is licensed under the [CC-0 license](http://creativecommons.org/publicdomain/zero/1.0/) 50 | --------------------------------------------------------------------------------