Skip to content

Commit

Permalink
Recent elements (#15)
Browse files Browse the repository at this point in the history
* Added support for recent searched stations

* Added support for all recent elements types (implemented for stations)

* Implemented support for recent trains

* Implemented support for recent itineraries
  • Loading branch information
MarcoBuster authored Dec 28, 2017
1 parent ddc0ea1 commit b3dfe5f
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 17 deletions.
122 changes: 122 additions & 0 deletions src/objects/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import redis

import config
from ..viaggiatreno.viaggiatreno import Utils

r = redis.StrictRedis(host=config.REDIS_HOST, port=config.REDIS_PORT, db=config.REDIS_DB, password=config.REDIS_PASSWORD)

Expand Down Expand Up @@ -96,5 +97,126 @@ def increaseStat(self, stat):
response = r.hincrby(self.rhash, stat)
return response

def _getRecentElements(self, element_type, reverse=False):
"""
Get recent elements
:param element_type: element type
:return: Recent elements in raw format
"""
return sorted(r.smembers(self.rhash + ':recent:' + element_type), reverse=reverse)

def removeRecentElement(self, element_type, index=0, reverse=False):
"""
Remove a recent element
:param element_type: element type
:param index: index of redis result
:param reverse: reverse elements order
:return: None
"""
names = self._getRecentElements(element_type, reverse=reverse)
r.srem(self.rhash + ':recent:' + element_type, names[index])

def addRecentElement(self, element_type, element_hash):
"""
Add a recent searched element
:param element_type: element type
:param element_hash: element hash
:return: None
"""
names = self._getRecentElements(element_type)
index = 0
is_duplicate = False
duplicate_check = None
if element_type == "stations":
duplicate_check = element_hash.split("@")[0]
if element_type == "trains":
duplicate_check = element_hash.split("@")[0]
if element_type == "itineraries":
duplicate_check = element_hash
for name in names:
if duplicate_check in name.decode('utf-8'):
self.removeRecentElement(element_type, index)
del (names[index])
is_duplicate = True
break
index += 1

if len(names) >= 5 and not is_duplicate:
self.removeRecentElement(element_type, 0)

names.reverse()
r.sadd(self.rhash + ':recent:' + element_type,
format((int(names[0].decode('utf-8').split("@")[0], 2) + 1) if names else 0, '016b') + "@" +
element_hash)

@staticmethod
def formatRecentStationHash(station_name, station_id):
return station_name + "@" + station_id

@staticmethod
def formatRecentItineraryHash(station_a, station_b):
return station_a + "@" + station_b

def formatRecentStationsKeyboard(self):
"""
Format recents stations keyboard
:return: list of lists of dict
"""
names = sorted(self._getRecentElements('stations'), reverse=True)

keyboard = []
for name in names:
station_name = name.decode('utf-8').split("@")[1]
station_id = name.decode('utf-8').split("@")[2]
keyboard.append([{"text": "🕒 {name}"
.format(name=station_name.title()),
"callback_data": "station@{station_id}"
.format(station_id=station_id)}])
return keyboard

def formatRecentTrainsKeyboard(self):
"""
Format recent trains keyboard
:return: list of lists of dict
"""
names = sorted(self._getRecentElements('trains'), reverse=True)

keyboard = []
for name in names:
train_name = name.decode('utf-8').split("@")[2]
train_id = name.decode('utf-8').split("@")[1]
keyboard.append([{"text": "🕒 {name}"
.format(name=train_name),
"callback_data": "train@{train_id}"
.format(train_id=train_id)}])
return keyboard

def formatRecentItinerariesKeyboard(self):
"""
Format recent itineraries keyboard
:return: list of lists of dicts
"""
names = sorted(self._getRecentElements('itineraries'), reverse=True)

utils = Utils()
keyboard = []
index = 0
for name in names:
station_a = name.decode('utf-8').split("@")[1]
station_b = name.decode('utf-8').split("@")[2]
if utils.station_from_ID(station_a) == 'UNKNOWN' or utils.station_from_ID(station_b) == 'UNKNOWN':
self.removeRecentElement('itinerary', index=index, reverse=True)
index += 1
continue

keyboard.append([{"text": "🕒 {station_a} ➡️ {station_b}"
.format(station_a=utils.station_from_ID(station_a).title(),
station_b=utils.station_from_ID(station_b).title()),
"callback_data": "itinerary@{station_a}_{station_b}"
.format(station_a=station_a,
station_b=station_b)}])
index += 1
return keyboard

def isActive(self):
return bool(r.hget(self.rhash, "active")) or False
64 changes: 51 additions & 13 deletions src/updates/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def process_callback(bot, cb, u):

elif cb.query == "train_bynum":
u.state("train_bynum")
last_trains = u.formatRecentTrainsKeyboard()
text = (
"<b>🚅 Cerca treno</b> per numero"
"\nInserisci il <b>numero di treno</b> (senza nessuna sigla prima, per esempio <code>9650</code>)"
Expand All @@ -206,16 +207,17 @@ def process_callback(bot, cb, u):
"chat_id": cb.chat.id, "message_id": cb.message.message_id, "text": text,
"parse_mode": "HTML", "reply_markup":
json.dumps(
{"inline_keyboard": [
[{"text": "🛤 Cerca invece per itinerario", "callback_data": "train_byiti"}],
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]
]}
{"inline_keyboard":
last_trains + [[{"text": "🛤 Cerca invece per itinerario", "callback_data": "train_byiti"}],
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]]
}
)
})
cb.notify("1️⃣ Cerca treno per numero")

elif cb.query == "train_byiti":
u.state("train_byiti")
last_itineraries = u.formatRecentItinerariesKeyboard()
text = (
"<b>🛤 Cerca treno</b> per itinerario"
"\nInserisci, come prima cosa, la <b>stazione di partenza</b>"
Expand All @@ -224,16 +226,18 @@ def process_callback(bot, cb, u):
"chat_id": cb.chat.id, "message_id": cb.message.message_id, "text": text,
"parse_mode": "HTML", "reply_markup":
json.dumps(
{"inline_keyboard": [
[{"text": "1️⃣ Cerca invece per numero", "callback_data": "train_bynum"}],
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]
]}
{"inline_keyboard":
last_itineraries +
[[{"text": "1️⃣ Cerca invece per numero", "callback_data": "train_bynum"}],
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]]
}
)
})
cb.notify("🛤 Cerca treno per itinerario")

elif cb.query == "station":
u.state("station")
last_stations = u.formatRecentStationsKeyboard()
text = (
"<b>🚉 Cerca stazione</b>"
"\nInserisci il <b>nome</b> della stazione che vuoi cercare"
Expand All @@ -242,9 +246,9 @@ def process_callback(bot, cb, u):
"chat_id": cb.chat.id, "message_id": cb.message.message_id, "text": text,
"parse_mode": "HTML", "reply_markup":
json.dumps(
{"inline_keyboard": [
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]
]}
{"inline_keyboard":
last_stations + [[{"text": "⬅️ Torna indietro", "callback_data": "home"}]]
}
)
})
cb.notify("🚉 Cerca stazione")
Expand Down Expand Up @@ -274,6 +278,7 @@ def process_callback(bot, cb, u):

if not arguments:
u.increaseStat('stats_trains_bynum')
u.addRecentElement('trains', cb.query.split("@")[1] + "@" + raw['compNumeroTreno'])

text = format.formatTrain(raw)
bot.api.call('editMessageText', {
Expand Down Expand Up @@ -418,6 +423,8 @@ def process_callback(bot, cb, u):

elif not arguments:
u.increaseStat('stats_stations')
u.addRecentElement("stations", u.formatRecentStationHash(station_name, station))

text = format.formatStation(station_name, station)
bot.api.call('editMessageText', {
'chat_id': cb.chat.id, 'message_id': cb.message.message_id,
Expand Down Expand Up @@ -496,6 +503,34 @@ def process_callback(bot, cb, u):
)

# ITINERARY CALLBACK
elif "itinerary@" in cb.query:
arguments = cb.query.split('@')
del(arguments[0])
station_a, station_b = arguments[0].split("_")
u.state('train_byiti_3')
u.setRedis('iti_station1', station_a)
u.setRedis('iti_station2', station_b)
u.addRecentElement('itineraries', u.formatRecentItineraryHash(station_a, station_b))

text = (
"<b>🛤 Cerca treno</b> per itinerario"
"\nInserisci ora <b>la data</b> e/o <b>l'orario di partenza</b> desiderati "
"(per esempio: <code>{a}</code>; <code>{b}</code>"
.format(a=datetime.now().strftime("%H:%M %d/%m/%y"),
b=datetime.now().strftime("%H:%M"))
)
bot.api.call('editMessageText', {
'chat_id': cb.chat.id, 'message_id': cb.message.message_id,
'text': text, 'parse_mode': 'HTML', 'reply_markup':
json.dumps(
{"inline_keyboard": [
[{"text": "🕒 Orario attuale", "callback_data": "train_byiti@now"}],
[{"text": "⬅️ Torna indietro", "callback_data": "home"}]
]}
)
})
return

elif cb.query == "train_byiti@now":
def minifyStation(__str):
__str = __str[1:]
Expand All @@ -509,8 +544,10 @@ def minifyStation(__str):

date = datetime.now()

station_a = minifyStation(u.getRedis('iti_station1').decode('utf-8'))
station_b = minifyStation(u.getRedis('iti_station2').decode('utf-8'))
station_a = u.getRedis('iti_station1').decode('utf-8')
station_b = u.getRedis('iti_station2').decode('utf-8')
u.addRecentElement('itineraries', u.formatRecentItineraryHash(station_a, station_b))
station_a, station_b = minifyStation(station_a), minifyStation(station_b)

u.increaseStat('stats_trains_byiti')

Expand Down Expand Up @@ -602,6 +639,7 @@ def process_inline_callback(bot, cb, u):

if not arguments:
u.increaseStat('stats_trains_bynum')
u.addRecentElement('trains', cb.query.split("@")[1] + "@" + raw['compNumeroTreno'])

text = format.formatTrain(raw)
bot.api.call('editMessageText', {
Expand Down
10 changes: 6 additions & 4 deletions src/updates/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def process_messages(bot, message, u):
u.increaseStat('stats_trains_bynum')

raw = api.call('andamentoTreno', results[0][1], message.text) # andamentoTreno; departure station; number
u.addRecentElement('trains', results[0][1] + "_" + message.text + "@" + raw['compNumeroTreno'])
text = format.formatTrain(raw)
bot.api.call('sendMessage', {
'chat_id': chat.id, 'text': text, 'parse_mode': 'HTML', 'reply_markup':
Expand Down Expand Up @@ -234,10 +235,10 @@ def minifyStation(__str):
x += 1
return __str

station_a = minifyStation(u.getRedis('iti_station1').decode('utf-8'))
station_b = minifyStation(u.getRedis('iti_station2').decode('utf-8'))
u.delRedis('iti_station1')
u.delRedis('iti_station2')
station_a = u.getRedis('iti_station1').decode('utf-8')
station_b = u.getRedis('iti_station2').decode('utf-8')
u.addRecentElement('itineraries', u.formatRecentItineraryHash(station_a, station_b))
station_a, station_b = minifyStation(station_a), minifyStation(station_b)

u.increaseStat('stats_trains_byiti')

Expand Down Expand Up @@ -275,6 +276,7 @@ def minifyStation(__str):

elif len(results) == 1:
u.increaseStat('stats_stations')
u.addRecentElement("stations", u.formatRecentStationHash(results[0]['nomeLungo'], results[0]['id']))

text = format.formatStation(results[0]['nomeLungo'], results[0]['id'])
bot.api.call('sendMessage', {
Expand Down

0 comments on commit b3dfe5f

Please sign in to comment.