You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.2 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. import argparse
  2. import re
  3. import ctabus
  4. from dateutil.parser import parse as date_parse
  5. import datetime
  6. # for logging
  7. import sys
  8. import os.path as osp
  9. def numb_sort(str):
  10. n = 40
  11. try:
  12. return re.sub(r'\d+',lambda match: match.group(0).rjust(n,'0'),str)
  13. except Exception as E:
  14. print(str)
  15. raise E
  16. def pprint_delta(delta):
  17. delta = str(delta)
  18. days= None
  19. s1 = delta.split(', ')
  20. if len(s1) > 1:
  21. days,time = s1
  22. else:
  23. time = s1[0]
  24. time = time.split('.')[0]
  25. hour,minute,second = map(int,time.split(':'))
  26. time = ''
  27. if hour:
  28. time += f'{hour} hour' + ('s' if hour != 1 else '')
  29. if minute:
  30. if time and not time.endswith(', '):
  31. time += ', '
  32. time += f'{minute} minute' + ('s' if minute != 1 else '')
  33. if second:
  34. if time and not time.endswith(', '):
  35. time += ', '
  36. time += f'{second} second' + ('s' if second != 1 else '')
  37. ret = ''
  38. if days:
  39. ret = days + ', ' if time else ''
  40. ret += time
  41. return ret
  42. def gen_list(objs,data,*displays,key = None,sort = 0,num_pic = True):
  43. k = displays[sort]
  44. display_data = {obj[k]:obj[data] for obj in objs}
  45. srt_keys = sorted(display_data.keys(),key=key)
  46. display = sorted(
  47. [
  48. [obj[d] for d in displays] for obj in objs
  49. ],
  50. key = lambda row: key(row[sort]) if key else row[sort]
  51. )
  52. if num_pic:
  53. display = [[i] + data for i,data in enumerate(display)]
  54. opts = {
  55. 'spacer':' ',
  56. 'seperator':' ',
  57. 'interactive': True,
  58. 'bottom':'=',
  59. 'l_end':'<',
  60. 'r_end':'>',
  61. }
  62. print2d(display,**opts)
  63. if num_pic:
  64. which = None
  65. while not which:
  66. try:
  67. which = input('Which one?: ')
  68. except KeyboardInterrupt:
  69. quit()
  70. try:
  71. which = srt_keys[int(which)]
  72. except ValueError:
  73. which = None
  74. return display_data[which]
  75. else:
  76. ret = None
  77. while not ret:
  78. try:
  79. ret = display_data[input('Which one?: ')]
  80. except KeyError:
  81. pass
  82. return ret
  83. config = '''\
  84. {route} - {end} ({direction})
  85. {nm}, stop {stop_id}
  86. {delta} ({t})\
  87. '''
  88. if __name__ == "__main__":
  89. parser = argparse.ArgumentParser(prog = 'ctabus')
  90. parser.add_argument('arg',nargs = '+',metavar = '(stop-id | cross streets)')
  91. parser.add_argument('-r','--route',default = None)
  92. parser.add_argument('-d','--direction',default = None)
  93. parser.add_argument('-l','--lucky',action='store_true',help = 'picks first result')
  94. args = parser.parse_args()
  95. sys.stderr = open(osp.join(osp.dirname(__file__),'stderr.log'),'w')
  96. args.arg = ' '.join(args.arg)
  97. if not args.arg.isdecimal():
  98. # save on import time slightly
  99. from print2d import print2d
  100. from search import Search,StopSearch
  101. #routes
  102. if not args.route:
  103. data = ctabus.get_routes()['routes']
  104. route = gen_list(data,'rt','rt','rtnm',num_pic = False,key=numb_sort)
  105. else:
  106. route = args.route
  107. data = ctabus.get_directions(route)['directions']
  108. #direction
  109. if not args.direction:
  110. direction = gen_list(data,'dir','dir')
  111. else:
  112. s = Search(args.direction)
  113. direction = sorted((obj['dir'] for obj in data),key = s)[0]
  114. #direction
  115. stops = ctabus.get_stops(route,direction)['stops']
  116. s = StopSearch(args.arg)
  117. if args.lucky:
  118. stop_id = sorted(stops,key=lambda stop: s(stop['stpnm']))[0]['stpid']
  119. else:
  120. stop_id = gen_list(stops,'stpid','stpnm',key = s)
  121. else:
  122. stop_id = args.arg
  123. times = ctabus.get_times(stop_id)['prd']
  124. today = datetime.datetime.today()
  125. for time in sorted(times,key = lambda t: t["prdtm"]):
  126. arrival = date_parse(time['prdtm'])
  127. if arrival > today:
  128. delta = pprint_delta(arrival-today)
  129. t = arrival.strftime('%H:%M:%S')
  130. route = time['rt']
  131. direction = time['rtdir']
  132. end = time['des']
  133. nm = time['stpnm']
  134. print(
  135. config.format(**globals()),end= '\n'*2
  136. )