Merge branch 'master' into experimental
[pywienerlinien] / scotty
1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3
4 import argparse
5 import sys
6
7 from gotovienna.utils import *
8 from gotovienna.routing import *
9
10 parser = argparse.ArgumentParser(description='Get public transport route for Vienna')
11 parser.add_argument('-ot', metavar='type', type=str, help='origin type: %s' % ' | '.join(POSITION_TYPES), default=None, choices=POSITION_TYPES)
12 parser.add_argument('-dt', metavar='type', type=str, help='destination type: %s' % ' | '.join(POSITION_TYPES), default=None, choices=POSITION_TYPES)
13 parser.add_argument('origin', nargs='?', help='origin station name')
14 parser.add_argument('destination', nargs='?', help='destination station name')
15
16 args = parser.parse_args()
17
18 if not args.origin:
19     args.origin = raw_input('Origin: ')
20
21 if not args.destination:
22     args.destination = raw_input('Destination: ')
23
24 def do_search(args):
25     if isinstance(args.origin, unicode):
26         args.origin = args.origin.encode('utf-8', 'ignore')
27     elif isinstance(args.destination, unicode):
28         args.destination = args.destination.encode('utf-8', 'ignore')
29
30     result = search((args.origin, args.ot),
31             (args.destination, args.dt))
32
33     return sParser(result.read())
34
35 print >>sys.stderr, 'Searching...\n',
36 parser = do_search(args)
37 print >>sys.stderr, 'done.'
38
39 finished = False
40 while not finished:
41
42     html = search((args.origin, args.ot), (args.destination, args.dt)).read()
43     
44     parser = sParser(html)
45     state = parser.check_page()
46
47     if state == PageType.CORRECTION:
48         try:
49             cor = parser.get_correction()
50             origin, origin_place = split_station(args.origin)
51             destination, destination_place = split_station(args.destination)
52             
53             # FIXME refactoring
54             
55             if cor.has_key('origin'):
56                 print
57                 print '* Origin ambiguous:'
58                 l = None
59                 while not l or not l.isdigit() or int(l) > len(cor['origin']):
60                     i = 1
61                     for c in cor['origin']:
62                         print '%d. %s' % (i, c)
63                         i += 1
64                     l = sys.stdin.readline().strip()
65     
66                 origin = cor['origin'][int(l) - 1]
67     
68             if cor.has_key('destination'):
69                 print
70                 print '* Destination ambiguous:'
71                 l = None
72                 while not l or not l.isdigit() or int(l) > len(cor['destination']):
73                     i = 1
74                     for c in cor['destination']:
75                         print '%d. %s' % (i, c)
76                         i += 1
77                     l = sys.stdin.readline().strip()
78     
79                 destination = cor['destination'][int(l) - 1]
80                 
81             if cor.has_key('origin_place'):
82                 print
83                 print '* Origin place ambiguous:'
84                 l = None
85                 while not l or not l.isdigit() or int(l) > len(cor['origin_place']):
86                     i = 1
87                     for c in cor['origin_place']:
88                         print '%d. %s' % (i, c)
89                         i += 1
90                     l = sys.stdin.readline().strip()
91     
92                 origin_place = cor['origin_place'][int(l) - 1]
93     
94             if cor.has_key('destination_place'):
95                 print
96                 print '* Destination place ambiguous:'
97                 l = None
98                 while not l or not l.isdigit() or int(l) > len(cor['destination_place']):
99                     i = 1
100                     for c in cor['destination_place']:
101                         print '%d. %s' % (i, c)
102                         i += 1
103                     l = sys.stdin.readline().strip()
104     
105                 destination_place = cor['destination_place'][int(l) - 1]
106                 
107             args.origin = '%s, %s' % (origin, origin_place)
108             args.destination = '%s, %s' %(destination, destination_place)
109             
110         except ParserError:
111             print 'PANIC at correction page'
112             finished = True
113     
114     elif state == PageType.RESULT:
115         parser = rParser(html)
116         try:
117             overviews = parser.overview
118             details = parser.details
119             l = ''
120             while not l == 'q':
121                 for idx, overview in enumerate(overviews):
122                     timespan = overview['timespan']
123                     if not timespan:
124                         # XXX: Bogus data for e.g. Pilgramgasse->Karlsplatz?!
125                         continue
126                     
127                     str_timespan = timespan[0].strftime('[%y-%d-%m] %H:%M')
128                     str_timespan += '-' + timespan[1].strftime('%H:%M')
129                     timedelta = timespan[1] - timespan[0]
130                     print '%d. %s (%s)' % (idx + 1,
131                             str_timespan,
132                             timedelta)
133                 print 'q. Quit'
134                 l = sys.stdin.readline().strip()
135                 print
136                 print '~' * 80
137     
138                 if l.isdigit() and int(l) <= len(details):
139                     for detail in details[int(l) - 1]:
140                         if detail['timespan'] and detail['station']:
141                             time = '%s - %s' % (detail['timespan'][0].strftime(TIMEFORMAT), detail['timespan'][1].strftime(TIMEFORMAT))
142                             print '[%s] %s\n%s' % (time, ' -> '.join(detail['station']), '\n'.join(detail['info']))
143                         else:
144                             print '\n'.join(detail['info'])
145                         print '-' * 80
146                 print
147         
148             finished = True
149         
150         except ParserError:
151             print 'parsererror'
152     
153     elif state == PageType.UNKNOWN:
154         print 'PANIC unknown result'
155
156 while parser.state == PageType.CORRECTION:
157     origin_corr, destination_corr = parser.get_correction()
158
159     if origin_corr:
160         print
161         print '* Origin ambiguous:'
162         lo = None
163         while not lo or not lo.isdigit() or int(lo) > len(origin_corr):
164             for idx, correction in enumerate(origin_corr):
165                 print '%3d. %s' % (idx+1, correction)
166             lo = sys.stdin.readline().strip()
167
168         args.origin = origin_corr[int(lo) - 1]
169
170     if destination_corr:
171         print
172         print '* Destination ambiguous:'
173         ld = None
174         while not ld or not ld.isdigit() or int(ld) > len(destination_corr):
175             for idx, correction in enumerate(destination_corr):
176                 print '%3d. %s' % (idx+1, correction)
177             ld = sys.stdin.readline().strip()
178
179         args.destination = destination_corr[int(ld) - 1]
180
181     parser = do_search(args)
182
183 if parser.state == PageType.RESULT:
184     parser = parser.get_result()
185     overviews = parser.overview
186     details = parser.details
187     l = ''
188     while not l == 'q':
189         for idx, overview in enumerate(overviews):
190             if not overview['date'] or not overview['time']:
191                 # XXX: Bogus data for e.g. Pilgramgasse->Karlsplatz?!
192                 continue
193
194             print '%d. [%s] %s-%s (%s)' % (idx + 1,
195                     overview['date'],
196                     overview['time'][0],
197                     overview['time'][1],
198                     overview['duration'])
199         print 'q. Quit'
200         l = sys.stdin.readline().strip()
201         print
202         print '~' * 79
203
204         if l.isdigit() and int(l) <= len(details):
205             for detail in details[int(l) - 1]:
206                 if detail['time'] and detail['station']:
207                     time = '%s - %s' % (detail['time'][0].strftime(TIMEFORMAT), detail['time'][1].strftime(TIMEFORMAT))
208                     print '[%s] %s\n%s' % (time, ' -> '.join(detail['station']), '\n'.join(detail['info']))
209                 else:
210                     print '\n'.join(detail['info'])
211                 print '-' * 79
212         print
213 else:
214     print 'Error - unknown page returned.'
215