PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/mat.py

https://github.com/plux/pynik
Python | 250 lines | 212 code | 23 blank | 15 comment | 13 complexity | 8c483a9347a4650cae1008cd950bb122 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. # Plugin created by Merola, heavily based on HGMat
  3. import re
  4. import utility
  5. from commands import Command
  6. from datetime import datetime
  7. def menu(location):
  8. # Set location-specific settings
  9. if location == "[hg]" or location == "hg":
  10. # Ryds Herrgård [hg], Linköping
  11. url = "http://www.hg.se/?restaurang/kommande"
  12. entry_regex = '\<h2\>(.+?dag)en den .+?\<\/h2\>(.+?)(?=(\<h2\>|\<em\>))'
  13. entry_day_index = 0
  14. entry_data_index = 1
  15. dish_regex = '\<p\>(.+?)\<br\>(.+?((\d+?) kr))?'
  16. dish_name_index = 0
  17. dish_price_index = 3
  18. elif location == "villevalla" or location == "vvp":
  19. # VilleValla Pub, Linköping
  20. url = "http://www.villevallapub.se/"
  21. entry_regex = '\<td valign="top" style="padding-right: 2px;"\>\<strong\>(.+?dag)\<\/strong\>\<\/td\>\s*\<td\>(.+?)\<\/td\>'
  22. entry_day_index = 0
  23. entry_data_index = 1
  24. dish_regex = '\A(.+?) ((\d+?) :-)\Z'
  25. dish_name_index = 0
  26. dish_price_index = 2
  27. elif location == "karallen" or location == "kara":
  28. # Restaurang Kårallen, LiU
  29. # Oh well... The Kårallen guys apparently don't know what they are doing.
  30. # For now, let's hope this pattern continues.
  31. url = "http://www.cgnordic.com/sv/Eurest-Sverige/Restauranger/Restaurang-Karallen-Linkopings-universitet/Lunchmeny-"
  32. if (int(datetime.now().strftime("%W"))+1) % 2: # TODO use better week function
  33. url += "v-13/"
  34. else:
  35. url += "v-15/"
  36. header_regex = '\<strong\>(.+?dag).+?\<\/strong\>'
  37. entry_regex = header_regex + '(\<\/p\>)?\<\/td\>\<\/tr\>(.+?)(?=(' + header_regex + '|\<p\>Pris dagens:))'
  38. entry_day_index = 0
  39. entry_data_index = 2
  40. dish_regex = '\<\/td\>\s+\<td\>(\s+\<p( align="[a-z]+")?\>)?([^\<]+?)(\<\/p\>)?\<\/td\>\<\/tr\>()'
  41. dish_name_index = 2
  42. dish_price_index = 4 # Dummy index.
  43. elif location == "blamesen" or location == "galaxen":
  44. # Restaurang Blåmesen, Galaxen, LiU
  45. url = "http://davidg.nu/lunch/blamesen.php?price"
  46. entry_regex = '([A-Za-zåäö]{3,4}dag)(.+?)(?=([A-Za-zåäö]{3,4}dag|$))'
  47. entry_day_index = 0
  48. entry_data_index = 1
  49. dish_regex = ': (.+?) \((\d+) kr\)'
  50. dish_name_index = 0
  51. dish_price_index = 1
  52. elif location == "zenit":
  53. # Restaurang & Café Zenit, LiU
  54. url = "http://www.hors.se/restauranger/restaurant_meny.php3?UID=24"
  55. entry_regex = '\<tr\>\<td valign="top" colspan="3"\>\<b\>(.+?dag)\<\/b\>\<\/td\>\<\/tr>(.+?)(\<tr\>\<td colspan="3"\>\<hr\>\<\/td\>\<\/tr\>|Veckans Bistro)'
  56. entry_day_index = 0
  57. entry_data_index = 1
  58. # This used to be some clever (?) regex to handle special cases that are
  59. # possibly not applicable now.
  60. # \xa4 == ¤
  61. dish_regex = '(\<td valign="top"\>|\<br \/\>\s*)\xa4 (.+?)(\<br \/\>|\<\/td\>)()'
  62. dish_name_index = 1
  63. dish_price_index = 3 # Dummy index.
  64. else:
  65. return [] # Not implemented yet
  66. # Settings are correct, now it's time to actually do something.
  67. # Fetch the web page
  68. response = utility.read_url(url)
  69. if not response:
  70. return []
  71. data = response["data"]
  72. data = utility.unescape(data.replace("\n", ""))
  73. data = data.replace(utility.unescape("&nbsp;"), " ")
  74. #return data
  75. # Build the menu
  76. menu = []
  77. for entry in re.findall(entry_regex, data):
  78. #print entry
  79. day = entry[entry_day_index]
  80. dishes = []
  81. for dish in re.findall(dish_regex, entry[entry_data_index]):
  82. #print dish
  83. dish_name = dish[dish_name_index].strip()
  84. dish_name = re.sub('\s+', ' ', dish_name)
  85. if not dish_name:
  86. pass # Odd input or bad regex
  87. elif dish_name.find(">") != -1:
  88. print "Hmm, I got an odd dish from " + location + ": " + dish_name
  89. elif dish[dish_price_index]:
  90. # Price found, let's add it
  91. dishes.append(dish_name + " (" + dish[dish_price_index] + " kr)")
  92. else:
  93. # No price, exclude it
  94. dishes.append(dish_name)
  95. menu.append((day, dishes))
  96. # Done!
  97. return menu
  98. def food(location, day):
  99. input_day = day
  100. best_match = None
  101. best_matching_chars = 0
  102. for entry in menu(location):
  103. entry_day = entry[0].lower()
  104. loop_len = min(len(input_day), len(entry_day))
  105. matching_chars = 0
  106. for i in range(loop_len):
  107. if input_day[i] == entry_day[i]:
  108. matching_chars += 1
  109. else:
  110. break
  111. if matching_chars > best_matching_chars:
  112. best_match = entry
  113. best_matching_chars = matching_chars
  114. return best_match
  115. def food_str(location, day):
  116. day_menu = food(location, day)
  117. if day_menu:
  118. return "%s: %s" % (day_menu[0], " | ".join(day_menu[1]))
  119. else:
  120. return "Hittade ingen meny för den platsen/dagen... :("
  121. def liu_food_str(day):
  122. karallen_menu = food("karallen", day)
  123. zenit_menu = food("zenit", day)
  124. blamesen_menu = food("blamesen", day)
  125. result = ""
  126. if karallen_menu:
  127. result += "Kårallen: "
  128. stripped_menu = []
  129. for item in karallen_menu[1]:
  130. dish_string = item.split(" med ", 2)[0]
  131. dish_string = dish_string.replace("serveras", "").strip().capitalize()
  132. stripped_menu.append(dish_string)
  133. result += ", ".join(stripped_menu)
  134. if zenit_menu:
  135. if result:
  136. result += " | "
  137. result += "Zenit: "
  138. stripped_menu = []
  139. for item in zenit_menu[1]:
  140. words = item.split(" ")
  141. important_words = []
  142. for word in words:
  143. if word.isupper():
  144. important_words.append(word.replace(",", "").strip())
  145. # TODO str.capitalize does not work correctly with non-english letters!
  146. if important_words:
  147. dish_string = " + ".join(important_words)
  148. dish_string = dish_string.decode("latin-1").encode("utf-8").capitalize()
  149. stripped_menu.append(dish_string)
  150. result += ", ".join(stripped_menu)
  151. if blamesen_menu:
  152. if result:
  153. result += " | "
  154. result += "Blåmesen: "
  155. stripped_menu = []
  156. for item in blamesen_menu[1]:
  157. dish_string = item.split(" m ", 2)[0]
  158. dish_string = re.sub(' \(\d\d kr\)', '', dish_string).strip().capitalize()
  159. stripped_menu.append(dish_string)
  160. result += ", ".join(stripped_menu)
  161. if result:
  162. return result
  163. else:
  164. return "Hittade ingen LiU-mat den dagen :("
  165. class MatCommand(Command):
  166. days = ["Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"]
  167. def __init__(self):
  168. pass
  169. def trig_mat(self, bot, source, target, trigger, argument):
  170. """Hämtar dagens (eller en annan dags) meny från vald restaurangs hemsida."""
  171. # Split arguments
  172. argument = argument.strip()
  173. args = argument.split(' ', 2)
  174. # Determine location and day
  175. if (not argument) or (len(args) > 2):
  176. return "Prova med \".mat plats [dag]\" - de platser jag känner till är: " + \
  177. "HG, VilleValla, Kårallen, Zenit"
  178. # TODO automatically generated list?
  179. elif len(args) == 1:
  180. day = MatCommand.days[datetime.now().isoweekday()-1].lower()
  181. else:
  182. day = args[1].lower()
  183. location = utility.asciilize(args[0]).lower()
  184. # Do stuff
  185. if location == "liu":
  186. return liu_food_str(day)
  187. else:
  188. return food_str(location, day)