├── nodejs ├── .babelrc ├── bin.prod.js ├── .npmignore ├── bin.dev.js ├── config │ └── mocha.js ├── README.md ├── test │ ├── parseTable.js │ └── fixture │ │ └── domTable.js ├── src │ ├── utils │ │ ├── loadData.js │ │ └── parseTable.js │ └── index.js └── package.json ├── .gitignore ├── resources ├── mvprb.png ├── mvpy.png ├── node.icon.png ├── ruby.icon.png ├── node-preview.gif ├── python.icon.png └── readme.logo.png ├── python ├── README.md └── mvg.py ├── ruby ├── README.md └── mvg.rb ├── LICENSE └── README.md /nodejs/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "stage": 0 3 | } 4 | -------------------------------------------------------------------------------- /nodejs/bin.prod.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | require('./lib'); 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | nodejs/node_modules 2 | nodejs/lib 3 | nodejs/npm-debug.log 4 | -------------------------------------------------------------------------------- /nodejs/.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | test/ 3 | config/ 4 | .babelrc 5 | bin.dev.js 6 | -------------------------------------------------------------------------------- /nodejs/bin.dev.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | require('babel/register'); 3 | require('./src'); 4 | -------------------------------------------------------------------------------- /resources/mvprb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/mvprb.png -------------------------------------------------------------------------------- /resources/mvpy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/mvpy.png -------------------------------------------------------------------------------- /resources/node.icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/node.icon.png -------------------------------------------------------------------------------- /resources/ruby.icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/ruby.icon.png -------------------------------------------------------------------------------- /resources/node-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/node-preview.gif -------------------------------------------------------------------------------- /resources/python.icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/python.icon.png -------------------------------------------------------------------------------- /resources/readme.logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/entwicklerstube/mvg-cli/HEAD/resources/readme.logo.png -------------------------------------------------------------------------------- /nodejs/config/mocha.js: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import sinon from 'sinon'; 3 | import sinonChai from 'sinon-chai'; 4 | 5 | chai.use(sinonChai); 6 | 7 | global.chai = chai; 8 | global.expect = chai.expect; 9 | global.sinon = sinon; 10 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # MVG CLI - Python 2 | Dependencies: 3 | 4 | pip install beautifulsoup4 5 | pip install colored 6 | pip install requests 7 | 8 | Usage: 9 | 10 | Edit the line "station = u'Unterföhring'" with your Station. 11 | eg: 12 | 13 | station = u'Sendlinger Tor' 14 | 15 | and then do 16 | 17 | python mvg.py 18 | 19 | 20 |

21 | 22 |

23 | -------------------------------------------------------------------------------- /ruby/README.md: -------------------------------------------------------------------------------- 1 | # MVG CLI - Ruby 2 | Dependencies: 3 | ``` 4 | gem install mechanize 5 | gem install colorize 6 | ``` 7 | 8 | Run it: 9 | ``` 10 | ruby mvg.rb Marienplatz 11 | ruby mvg.rb "Sendlinger Tor" 12 | ``` 13 | 14 | Alternatively you can install mvg directly from the rubygems.org website 15 | ``` 16 | gem install mvg 17 | ``` 18 | now you can type 19 | ``` 20 | mvg Marienplatz 21 | ``` 22 | in your terminal. 23 | 24 | Have fun :) 25 | 26 | 27 | -------------------------------------------------------------------------------- /nodejs/README.md: -------------------------------------------------------------------------------- 1 | # MVG CLI - NodeJS 2 | ### Install 3 | ``` 4 | npm install mvg-cli -g 5 | ``` 6 | 7 | ### Usage 8 | ``` 9 | Usage: mvg [station] 10 | 11 | station Name of an registered stop-station in the MVV network (not required) 12 | ``` 13 | 14 | ### Develop 15 | ``` 16 | # Clone the repository and move to the "nodejs" folder, then... 17 | 18 | Commands: npm run [command] 19 | 20 | develop starts the command-line script 21 | test start all tests in the test-folder 22 | test-watch watch all tests in the test-folder 23 | compile compile the es6 code to es5 and move to the lib folder 24 | ``` 25 | 26 | ### Contribute / Report issues 27 | Visit our [Github-Repository](https://github.com/entwicklerstube/mvg-cli), you can create pull-requests, join discussions and report bugs. 28 | 29 | ### Data source 30 | For this tool we crawl the official [MVG-Live](http://www.mvg-live.de/MvgLive/MvgLive.jsp) Page. 31 | 32 | ### Preview 33 | ![](resources/node-preview.gif) 34 | -------------------------------------------------------------------------------- /nodejs/test/parseTable.js: -------------------------------------------------------------------------------- 1 | import DOM from './fixture/domTable'; 2 | import ParseTable from '../src/utils/parseTable'; 3 | 4 | describe('Table To Array', () => { 5 | it('returns the entries of the passed table (count tr`s)', () => { 6 | expect(ParseTable(DOM).length).to.equal(9); 7 | }); 8 | 9 | it('returns the amount of the trips-data', () => { 10 | expect(ParseTable(DOM).trips).to.equal(7); 11 | }); 12 | 13 | it('returns the station of interest', () => { 14 | expect(ParseTable(DOM).station).to.equal('Goetheplatz'); 15 | }); 16 | 17 | it('returns the server-time', () => { 18 | expect(ParseTable(DOM).serverTime).to.equal('11:30'); 19 | }); 20 | 21 | it('returns an array with the subway-data', () => { 22 | expect(ParseTable(DOM).departures[0]).to.deep.equal({ 23 | route: 'U6', 24 | station: 'Garching-Forschungszentrum', 25 | arrivingIn: "0" 26 | }); 27 | }); 28 | 29 | it('returns a repaired station-title', () => { 30 | expect(ParseTable(DOM).cleanStationTitle('\n Garching-Forschungszentrum\n  \n')).to.equal('Garching-Forschungszentrum') 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Entwicklerstube 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /nodejs/src/utils/loadData.js: -------------------------------------------------------------------------------- 1 | import request from 'request'; 2 | import cheerio from 'cheerio'; 3 | import iconv from 'iconv-lite'; 4 | import ParseTable from './parseTable'; 5 | 6 | export default function create(config, callback) { 7 | class LoadData { 8 | startStation = config.station 9 | 10 | constructor() { 11 | const RequestURI = [ 12 | `https://`, // protocol 13 | `www.mvg-live.de`, // url 14 | `/ims/dfiStaticAuswahl.svc`, // endpoint 15 | `?haltestelle=${this.startStation}`, // station of interesst 16 | `&ubahn=checked`, // look for subway 17 | `&bus=checked`, // look for bus 18 | `&tram=checked`, // look for tram 19 | `&sbahn=checked` // look for sbahn 20 | ].join(''); 21 | 22 | request({ 23 | uri: RequestURI, 24 | encoding: null 25 | }, (err, res, body) => { 26 | if(err && res.statusCode !== 200) callback('Error: Had problems to connect to mvg-page', null); 27 | const DOM = iconv.decode(new Buffer(body), "ISO-8859-1"); 28 | callback(null, ParseTable(DOM)); 29 | }); 30 | } 31 | } 32 | 33 | return new LoadData(); 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MVG - Command Line Interface 4 | Checkout the MVG-traffic data by querying the arriving/deperature data from you Terminal. 5 | 6 | | Language | Install | Usage | Links 7 | | -------------------------- | ------------------------------------------------------- | ---------------- | -------------------------- 8 | | | `npm install mvg-cli -g` | `mvg [station]` | [Preview](#node-preview), [Docs](nodejs/README.md) 9 | | | `git clone git@github.com:entwicklerstube/mvg-cli.git` | `python mvg.py` | [Preview](#python-preview), [Docs](python/README.md) 10 | | | `gem install mvg` | `mvg [station]` | [Preview](#ruby-preview), [Docs](ruby/README.md) 11 | 12 | ## Contribute 13 | If you want the CLI in your programing language, just write it down and make a pull requests. 14 | Wishes and suggestions are welcome :) 15 | 16 | ## Previews 17 | ### Node Preview 18 | ![](resources/node-preview.gif) 19 | ### Python Preview 20 | ![](resources/mvpy.png) 21 | ### Ruby Preview 22 | ![](resources/mvprb.png) 23 | -------------------------------------------------------------------------------- /nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mvg-cli", 3 | "version": "1.1.0", 4 | "description": "Command Line Interface for the Muenchner Vekehrsgesellschaft", 5 | "main": "index.js", 6 | "repository": "entwicklerstube/mvg-cli", 7 | "scripts": { 8 | "test": "mocha test/* --require ./config/mocha.js --compilers js:babel/register", 9 | "test-watch": "mocha test/* --require ./config/mocha.js --compilers js:babel/register --watch", 10 | "babel-node": "babel-node --stage 0", 11 | "develop": "nodemon --exec npm run babel-node -- src/index", 12 | "pack": "webpack --config config/webpack.js", 13 | "compile": "babel -d lib/ src/", 14 | "develop": "node bin.dev.js", 15 | "prepublish": "npm run compile" 16 | }, 17 | "bin": { 18 | "mvg": "bin.prod.js" 19 | }, 20 | "author": "Michael J. Zoidl (http://michaelzoidl.com)", 21 | "license": "MIT", 22 | "devDependencies": { 23 | "babel": "^5.6.14", 24 | "babel-core": "^5.6.15", 25 | "chai": "^3.0.0", 26 | "json-loader": "^0.5.3", 27 | "mocha": "^2.2.5", 28 | "rimraf": "^2.4.1", 29 | "sinon": "^1.15.4", 30 | "sinon-chai": "^2.8.0" 31 | }, 32 | "dependencies": { 33 | "chalk": "^1.1.1", 34 | "cheerio": "^0.19.0", 35 | "log-update": "^1.0.2", 36 | "moment": "^2.10.6", 37 | "readline-sync": "^1.2.21", 38 | "request": "^2.65.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nodejs/src/utils/parseTable.js: -------------------------------------------------------------------------------- 1 | import cheerio from 'cheerio'; 2 | 3 | export default function create(DOM) { 4 | class ParseTable { 5 | $ = undefined 6 | length = 0 7 | trips = 0 8 | station = 'unknown' 9 | serverTime = '00:00' 10 | departures = [] 11 | 12 | constructor() { 13 | this.$ = cheerio.load(DOM); 14 | // let tramLines = ['20','17','12','18','16','19','15','25','21','22','28','27']; 15 | 16 | this.length = this.$('tr').length; 17 | this.trips = this.$('.rowOdd, .rowEven').length; 18 | this.station = this.$('.headerStationColumn').text(); 19 | this.serverTime = this.$('.serverTimeColumn').text(); 20 | this.departures = this.findByType('ubahn'); 21 | } 22 | 23 | findByType(type) { 24 | let lines = []; 25 | const availableTypes = ['ubahn', 'bus', 'sbahn', 'tram']; 26 | if(availableTypes.indexOf(type) < 0) throw `error: ${type} is not available as mvg type`; 27 | 28 | const that = this; 29 | 30 | this.$('.rowOdd, .rowEven').each(function() { 31 | lines.push({ 32 | route: that.$(this).find('.lineColumn').text(), 33 | station: that.cleanStationTitle(that.$(this).find('.stationColumn').text()), 34 | arrivingIn: that.$(this).find('.inMinColumn').text() 35 | }); 36 | }); 37 | 38 | return lines; 39 | } 40 | 41 | cleanStationTitle(title) { 42 | return title.replace(/^\s+|\s+$/g, ''); 43 | } 44 | } 45 | 46 | return new ParseTable(); 47 | } 48 | -------------------------------------------------------------------------------- /nodejs/src/index.js: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import moment from 'moment'; 3 | import readlineSync from 'readline-sync'; 4 | import logUpdate from 'log-update'; 5 | import LoadData from './utils/loadData'; 6 | 7 | // Clear CLI 8 | process.stdout.write("\u001b[2J\u001b[0;0H"); 9 | // Print a header 10 | console.log( 11 | chalk.black.bgYellow(' MVG ') 12 | ); 13 | 14 | let startStation = undefined; 15 | 16 | if(process.argv && process.argv[2]) { 17 | startStation = process.argv[2]; 18 | } else { 19 | startStation = readlineSync.question('From what station do you want to start? : ') 20 | } 21 | 22 | console.log( 23 | chalk.yellow(`Show all trips from ${chalk.yellow.underline(startStation)}`) 24 | ); 25 | 26 | let LiveData = []; 27 | let LastRefresh = +new Date() 28 | 29 | const updateData = () => { 30 | LoadData({ 31 | station: startStation 32 | }, (err, data) => { 33 | if(err) throw `Error: ${err}`; 34 | LiveData = data; 35 | LastRefresh = +new Date(); 36 | }); 37 | } 38 | String.prototype.paddingLeft = function (paddingValue) {return String(paddingValue + this).slice(-paddingValue.length);}; 39 | 40 | updateData(); 41 | 42 | setInterval(() => { 43 | updateData(); 44 | }, 5000); 45 | 46 | let tmpl = ''; 47 | setInterval(() => { 48 | if(LiveData.length > 0) { 49 | let deps = []; 50 | 51 | // console.log(LiveData.departures); 52 | 53 | LiveData.departures.map((dep) => { 54 | deps.push(` ${chalk.white.bgRed(dep.route.paddingLeft(" ")+" ")} in ${dep.arrivingIn.paddingLeft(" ")} minutes to ${dep.station}\n`); 55 | }); 56 | 57 | 58 | tmpl = ` 59 | ${chalk.black.bgWhite(`From ${LiveData.station}`)} Last refresh: ${moment(LastRefresh).format('HH:mm:ss')} 60 | - - - - - - - - - - - - - - - - - - - - - - - - - - - 61 | ${deps.join('')} - - - - - - - - - - - - - - - - - - - - - - - - - - - 62 | `; 63 | } else { 64 | tmpl = ` 65 | Loading... 66 | `; 67 | } 68 | logUpdate(tmpl); 69 | },100); 70 | -------------------------------------------------------------------------------- /nodejs/test/fixture/domTable.js: -------------------------------------------------------------------------------- 1 | // Example how the `request` feedback looks like from mvg-live page 2 | export default ` 3 | 4 | Goetheplatz 5 | 11:30 6 | 7 | 8 | U6 9 | 10 | Garching-Forschungszentrum 11 |   12 | 13 | 0 14 | 15 | 16 | 58 17 | 18 | Silberhornstraße 19 |   20 | 21 | 10 22 | 23 | 24 | 58 25 | 26 | Hauptbahnhof 27 |   28 | 29 | 10 30 | 31 | 32 | U6 33 | 34 | Klinikum Großhadern 35 |   36 | 37 | 14 38 | 39 | 40 | U3 41 | 42 | Fürstenried West 43 |   44 | 45 | 14 46 | 47 | 48 | U6 49 | 50 | Garching-Forschungszentrum 51 |   52 | 53 | 20 54 | 55 | 56 | U3 57 | 58 | Moosach 59 |   60 | 61 | 21 62 | 63 | 64 | 65 | 66 | Fahrten aktualisieren 67 | 68 | 69 | `; 70 | -------------------------------------------------------------------------------- /ruby/mvg.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'mechanize' 3 | require 'colorize' 4 | 5 | @station_url = ARGV[0] 6 | 7 | class Ride 8 | def initialize(line, destination, minutes) 9 | @line=line 10 | @destination=destination 11 | @minutes=minutes 12 | end 13 | 14 | def display_info 15 | puts @line + ' - in ' + @minutes + ' minutes - to ' + @destination.red 16 | end 17 | end 18 | 19 | def getRides 20 | agent = Mechanize.new 21 | agent.get('http://www.mvg-live.de/ims/dfiStaticAuswahl.svc') do |page| 22 | 23 | form = page.forms.first 24 | form['haltestelle'] = @station_url 25 | result = form.submit 26 | 27 | ubahn_ary = [] 28 | sbahn_ary = [] 29 | bus_ary = [] 30 | 31 | res_table = result.search('table.departureTable') 32 | 33 | res_table.search('tr').each do |entry| 34 | 35 | line = entry.search('.lineColumn').text 36 | station = entry.search('.stationColumn').text.gsub(/\r?\n?\t/, '') 37 | minutes = entry.search('.inMinColumn').text 38 | 39 | if line != '' && station != '' && minutes != '' 40 | if line[0] == 'U' 41 | single_ride = Ride.new(line, station, minutes) 42 | ubahn_ary.push(single_ride) 43 | elsif line[0] == 'S' 44 | single_ride = Ride.new(line, station, minutes) 45 | sbahn_ary.push(single_ride) 46 | else 47 | single_ride = Ride.new(line, station, minutes) 48 | bus_ary.push(single_ride) 49 | end 50 | end 51 | end 52 | 53 | puts 'U-Bahn'.colorize(:color => :white, :background => :blue) 54 | if(ubahn_ary.length == 0) 55 | puts "Keine Einträge gefunden".colorize(:color => :white, :background => :red) 56 | else 57 | ubahn_ary.each do |entry| 58 | puts entry.display_info 59 | end 60 | end 61 | puts '----------------------------------' 62 | puts 'S-Bahn'.colorize(:color => :white, :background => :yellow) 63 | if(ubahn_ary.length == 0) 64 | puts "Keine Einträge gefunden".colorize(:color => :white, :background => :red) 65 | else 66 | sbahn_ary.each do |entry| 67 | puts entry.display_info 68 | end 69 | end 70 | puts '----------------------------------' 71 | puts 'Bus'.colorize(:color => :white, :background => :green) 72 | if(ubahn_ary.length == 0) 73 | puts "Keine Einträge gefunden".colorize(:color => :white, :background => :red) 74 | else 75 | bus_ary.each do |entry| 76 | puts entry.display_info 77 | end 78 | end 79 | end 80 | end 81 | 82 | while true do 83 | getRides 84 | sleep 10 85 | end 86 | 87 | -------------------------------------------------------------------------------- /python/mvg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding: UTF-8 -*- 3 | import requests 4 | from bs4 import BeautifulSoup 5 | import time 6 | import os 7 | from colored import fg, bg, attr 8 | import sys, getopt 9 | import signal 10 | import imp 11 | 12 | if sys.version_info.major == 2: 13 | from urllib import quote as urllib_quote 14 | imp.reload(sys) 15 | sys.setdefaultencoding('utf8') 16 | 17 | strip = lambda x: x.encode('latin-1').strip() 18 | 19 | def _build_line(line, time, place): 20 | return "{} - in {} minutes - to {}".format(line.decode('latin-1'), 21 | time.decode('latin-1'), 22 | place.decode('latin-1')) 23 | else: 24 | from urllib.parse import quote as urllib_quote 25 | 26 | strip = lambda x: x.strip() 27 | 28 | def _build_line(line, time, place): 29 | return "{} - in {} minutes - to {}".format(line, time, place) 30 | 31 | 32 | color = True 33 | 34 | def fgc(p): 35 | global color 36 | if color: 37 | return fg(p) 38 | else: 39 | return '' 40 | 41 | def bgc(p): 42 | global color 43 | if color: 44 | return bg(p) 45 | else: 46 | return '' 47 | 48 | def attrc(p): 49 | global color 50 | if color: 51 | return attr(p) 52 | else: 53 | return '' 54 | 55 | def signal_handler(signal, frame): 56 | print(attrc('reset')) 57 | sys.exit(0) 58 | signal.signal(signal.SIGINT, signal_handler) 59 | 60 | def encode_request_string(station): 61 | station_url = station.encode("latin-1") 62 | station_url = urllib_quote(station_url) 63 | return station_url.lower() 64 | 65 | 66 | def _print_line(lines, line_name): 67 | print(('{}{} {} {}'.format(fgc('white'), 68 | bgc('yellow'), 69 | line_name, 70 | attrc('reset')))) 71 | if not lines: 72 | print(('{} No {} from this station {}'.format(fgc('yellow'), 73 | line_name, 74 | attrc('reset')))) 75 | else: 76 | try: 77 | for idx, x in enumerate(lines): 78 | if idx == 0: 79 | print(('{}{} {} {}'.format(fgc('white'), 80 | bgc('red'), 81 | x, 82 | attrc('reset')))) 83 | else: 84 | print(' ' + x) 85 | except: 86 | import ipdb; ipdb.set_trace() 87 | 88 | def printStations(station, hide): 89 | ubahn=[] 90 | sbahn=[] 91 | tram=[] 92 | bus=[] 93 | 94 | station_url = encode_request_string(station) 95 | 96 | base_url = "http://www.mvg-live.de/ims/dfiStaticAuswahl.svc?haltestelle=" 97 | r = requests.get(base_url + station_url + "&ubahn=checked&bus=checked&tram=checked&sbahn=checked") 98 | site = BeautifulSoup(r.text, "html.parser") 99 | 100 | table_line = [truc.text 101 | for truc in site.find_all('td', {"class":"lineColumn"})] 102 | 103 | table_place = [truc.find(text=True, recursive=False) 104 | for truc in site.find_all('td', {"class":"stationColumn"})] 105 | 106 | table_time = [truc.text 107 | for truc in site.find_all('td', {"class":"inMinColumn"}) 108 | if truc.text] 109 | 110 | table_line = [strip(truc) for truc in table_line] 111 | table_place = [strip(truc) for truc in table_place] 112 | table_time = [strip(truc) for truc in table_time] 113 | 114 | print(('{}{} From {} {}'.format(fgc('black'), bgc('white'), 115 | station, attrc('reset')))) 116 | 117 | for i in range(1, len(table_line)): 118 | line = _build_line(table_line[i], table_time[i], table_place[i]) 119 | if table_line[i][0] == "U": 120 | ubahn.append(line) 121 | elif table_line[i][0] == "S": 122 | sbahn.append(line) 123 | elif int(table_line[i]) < 50: 124 | tram.append(line) 125 | else: 126 | bus.append(line) 127 | 128 | if not hide: 129 | _print_line(ubahn, 'Ubahn') 130 | print('\n') 131 | _print_line(sbahn, 'Sbahn') 132 | print('\n') 133 | _print_line(tram, 'Tram') 134 | print('\n') 135 | _print_line(bus, 'Bus') 136 | 137 | 138 | def printHelp(): 139 | print('mvg.py -s ') 140 | print(' -t : refresh every 10 sec') 141 | print(' -x : hide empty lists') 142 | print(' -c : no color') 143 | print(' -h : this help') 144 | 145 | def main(argv): 146 | global color 147 | station = '' 148 | loop = False 149 | hide = False 150 | 151 | try: 152 | opts, args = getopt.getopt(argv,"htxcs:", ['station=']) 153 | except getopt.GetoptError: 154 | printHelp() 155 | sys.exit(2) 156 | for opt, arg in opts: 157 | if opt == '-h': 158 | printHelp() 159 | sys.exit() 160 | elif opt in ("-t"): 161 | loop = True 162 | elif opt in ("-x"): 163 | hide = True 164 | elif opt in ("-c"): 165 | color = False 166 | elif opt in ("-s", "--station"): 167 | station = arg 168 | 169 | if station == '': 170 | print('station is missing') 171 | printHelp() 172 | sys.exit(3) 173 | 174 | if loop: 175 | while True: 176 | os.system('clear') 177 | printStations(station, hide) 178 | time.sleep(10) 179 | else: 180 | printStations(station, hide) 181 | 182 | if __name__ == "__main__": 183 | main(sys.argv[1:]) 184 | --------------------------------------------------------------------------------