Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.73 KB | None | 0 0
  1. import json
  2. import time
  3. import telebot
  4. import datetime
  5. import requests
  6. from bs4 import BeautifulSoup
  7.  
  8. with open('config.json') as conf:
  9. config = json.load(conf)
  10.  
  11. bot = telebot.TeleBot(config['access_token'])
  12. WEEKDAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
  13. WEEKDAYS_RUSSIAN = {'monday': 'понедельник',
  14. 'tuesday': 'вторник',
  15. 'wednesday': 'среду',
  16. 'thursday': 'четверг',
  17. 'friday': 'пятницу',
  18. 'saturday': 'субботу',
  19. 'sunday': 'воскресенье'}
  20. WEEK_PARITY = {0: 'четная неделя', 1: 'нечетная неделя', 3: ''}
  21. EMOJI_NUMBERS = [u'\u0031\u20E3', u'\u0032\u20E3', u'\u0033\u20E3', u'\u0034\u20E3', u'\u0035\u20E3',
  22. u'\u0036\u20E3', u'\u0037\u20E3', u'\u0038\u20E3', u'\u0039\u20E3']
  23. CACHED_SCHEDULE = {}
  24.  
  25.  
  26. def get_week_number():
  27. return datetime.date.today().isocalendar()[1] - 35
  28.  
  29.  
  30. def get_day_number():
  31. return datetime.date.today().weekday() + 1
  32.  
  33.  
  34. def parse_command(message):
  35. try:
  36. day, group = message.text.split()
  37. day = day[1:]
  38. except ValueError:
  39. bot.send_message(message.chat.id, 'You should specify your group number like "/monday K3140"')
  40. return
  41. return day, group
  42.  
  43.  
  44. def get_schedule_page(group, week: str = None):
  45. if week is None or week == '0':
  46. week = ''
  47. else:
  48. week = week + '/'
  49.  
  50. url = f'{config["domain"]}/{group}/{week}raspisanie_zanyatiy_{group}.htm'
  51. response = requests.get(url)
  52. web_page = response.text
  53. return web_page
  54.  
  55.  
  56. def parse_schedule_for_day(web_page, day_number: str):
  57. soup = BeautifulSoup(web_page, "html5lib")
  58.  
  59. # Получаем таблицу с расписанием на понедельник
  60. schedule_table = soup.find("table", attrs={"id": f"{day_number}day"})
  61.  
  62. if schedule_table is None:
  63. return None
  64.  
  65. times_list = schedule_table.find_all("td", attrs={"class": "time"})
  66. times_list = [time.span.text for time in times_list]
  67.  
  68. # Место проведения занятий
  69. locations_list = schedule_table.find_all("td", attrs={"class": "room"})
  70. locations_list = [room.span.text for room in locations_list]
  71.  
  72. # Название дисциплин и имена преподавателей
  73. lessons_list = schedule_table.find_all("td", attrs={"class": "lesson"})
  74. lessons_list = [lesson.text.split('\n\n') for lesson in lessons_list]
  75. lessons_list = [', '.join([
  76. info.replace('\r\n', '(', 1).replace('\r\n', ') ', 1).replace('\t', '').replace('\n', '') for info in lesson_info if info
  77. ]) for lesson_info in lessons_list]
  78.  
  79. return times_list, locations_list, lessons_list
  80.  
  81.  
  82. def get_schedule_info(group: str, day: str, week: str = None):
  83. global CACHED_SCHEDULE
  84. if week is None:
  85. week_key = 0
  86. elif week == '0':
  87. week_key = 0
  88. elif week == '1':
  89. week_key = 1
  90. elif week == '2':
  91. week_key = 2
  92. elif int(week) % 2 == 0:
  93. week_key = 1
  94. else:
  95. week_key = 2
  96.  
  97. if CACHED_SCHEDULE.get(group) is None:
  98. CACHED_SCHEDULE[group] = {}
  99.  
  100. if CACHED_SCHEDULE[group].get(week_key) is None:
  101. CACHED_SCHEDULE[group][week_key] = {}
  102.  
  103. if CACHED_SCHEDULE[group][week_key].get(day) is None:
  104. # print('Loading web-page with schedule...')
  105. web_page = get_schedule_page(group, week)
  106. schedule = parse_schedule_for_day(web_page, day)
  107.  
  108. if schedule is None:
  109. CACHED_SCHEDULE[group][week_key][day] = [[], [], []]
  110. return None
  111. else:
  112. CACHED_SCHEDULE[group][week_key][day] = schedule
  113. return schedule
  114. else:
  115. # print('Loading schedule from cache...')
  116. schedule = CACHED_SCHEDULE[group][week_key][day]
  117. if len(schedule[0]) == 0:
  118. return None
  119. return schedule
  120.  
  121.  
  122. @bot.message_handler(commands=WEEKDAYS)
  123. def get_schedule(message, week_number: str = None, return_reply=False, consider_week_parity=True):
  124. """ Получить расписание на указанный день """
  125. try:
  126. day, week_number, group = message.text.split()
  127. day = day[1:]
  128. except ValueError:
  129. _cmd = parse_command(message)
  130. if _cmd is None:
  131. return
  132. else:
  133. day, group = _cmd
  134.  
  135. weekday_number = str(WEEKDAYS.index(day) + 1)
  136. if consider_week_parity:
  137. schedule = get_schedule_info(group, weekday_number, week_number)
  138. else:
  139. schedule = get_schedule_info(group, weekday_number)
  140.  
  141. if schedule is None:
  142. resp = 'На указанный день пар нет. Можно отдыхать :)'
  143. if return_reply:
  144. return resp
  145. else:
  146. bot.send_message(message.chat.id, resp)
  147. return
  148.  
  149. times_list, locations_list, lessons_list = schedule
  150.  
  151. resp = f'Расписание на {WEEKDAYS_RUSSIAN[day]}:\n'
  152. for i in range(len(times_list)):
  153. resp += f'{EMOJI_NUMBERS[i]} {times_list[i]} | {lessons_list[i]} | {locations_list[i]}\n'
  154.  
  155. if return_reply:
  156. return resp
  157. bot.send_message(message.chat.id, resp)
  158.  
  159.  
  160. @bot.message_handler(commands=['near'])
  161. def get_near_lesson(message):
  162. """ Получить ближайшее занятие """
  163. _cmd = parse_command(message)
  164. if _cmd is None:
  165. return
  166. else:
  167. day, group = _cmd
  168.  
  169. weekday_number = get_day_number()
  170. week_number = get_week_number()
  171.  
  172. found = False
  173. this_day = True
  174. while not found:
  175. schedule = get_schedule_info(group, str(weekday_number), str(weekday_number))
  176. if schedule is not None:
  177. times_list, locations_list, lessons_list = schedule
  178. if this_day:
  179. time_now = time.strptime(time.strftime('%H:%M'), '%H:%M')
  180. for i in range(len(times_list)):
  181. lesson_start_time = time.strptime(times_list[0].split('-')[i], '%H:%M')
  182. if time_now < lesson_start_time:
  183. bot.send_message(message.chat.id, f'Ближайшая пара сегодня, в {times_list[i]}\n'
  184. f'{lessons_list[i]}\n'
  185. f'Корпус: {locations_list[i]}\n')
  186. found = True
  187. break
  188. else:
  189. if len(times_list) != 0:
  190. if weekday_number <= get_day_number():
  191. weekday_number += 7
  192. bot.send_message(message.chat.id, f'Ближайшая пара через {weekday_number - get_day_number()} дня в '
  193. f'{WEEKDAYS_RUSSIAN[WEEKDAYS[weekday_number % 7 - 1]]}, {times_list[0]}\n'
  194. f'{lessons_list[0]}\n'
  195. f'Корпус: {locations_list[0]}\n')
  196. found = True
  197. else:
  198. this_day = False
  199. weekday_number += 1
  200. if weekday_number == 8:
  201. weekday_number = 1
  202. week_number += 1
  203.  
  204.  
  205. @bot.message_handler(commands=['tomorrow'])
  206. def get_tommorow(message):
  207. """ Получить расписание на следующий день """
  208. _cmd = parse_command(message)
  209. if _cmd is None:
  210. return
  211. else:
  212. _, group = _cmd
  213.  
  214. day = get_day_number() + 1
  215. week = get_week_number()
  216. if day == 7:
  217. day = 1
  218. week += 1
  219.  
  220. message.text = f'/{WEEKDAYS[day - 1]} {group}'
  221. get_schedule(message, str(week))
  222.  
  223.  
  224. @bot.message_handler(commands=['all'])
  225. def get_all_schedule(message):
  226. """ Получить расписание на всю неделю для указанной группы """
  227. _cmd = parse_command(message)
  228. if _cmd is None:
  229. return
  230. else:
  231. _, group = _cmd
  232.  
  233. all_response = []
  234. for day in range(1, 8):
  235. resp = ''
  236. message.text = f'/{WEEKDAYS[day - 1]} {group}'
  237. schedule_for_day = get_schedule(message, return_reply=True, consider_week_parity=False)
  238. if 'пар нет' in schedule_for_day:
  239. resp += f'Расписание на {WEEKDAYS_RUSSIAN[WEEKDAYS[day - 1]]}:\n' \
  240. f'Нет пар'
  241. else:
  242. resp += schedule_for_day
  243. all_response.append(resp.strip())
  244.  
  245. bot.send_message(message.chat.id, f'\n{"=" * 30}\n'.join(all_response))
  246.  
  247.  
  248. if __name__ == '__main__':
  249. bot.polling(none_stop=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement