Compare commits

..

No commits in common. "6e06bc963a030720ca10fd0f10753163e4c08ab2" and "eb0fd408993e691434c4fb6f6a0d82878891cf85" have entirely different histories.

108
nauta.py
View file

@ -55,13 +55,6 @@ def parse_time(t):
except: except:
return 0 return 0
def get_password(username):
with dbm.open(CARDS_DB) as cards_db:
if not username in cards_db:
return None
info = json.loads(cards_db[username].decode())
return info['password']
def select_card(): def select_card():
cards = [] cards = []
with dbm.open(CARDS_DB) as cards_db: with dbm.open(CARDS_DB) as cards_db:
@ -88,19 +81,12 @@ def up(args):
print("Looks like you're already connected. Use 'nauta down' to log out.") print("Looks like you're already connected. Use 'nauta down' to log out.")
return return
if args.username: username, password = select_card()
username = args.username if username is None:
password = get_password(username) print("No card available, add one with 'nauta cards add'")
if password is None: return
print("Invalid card: {}".format(args.username))
return
else:
username, password = select_card()
if username is None:
print("No card available, add one with 'nauta cards add'")
return
username = username.decode()
username = username.decode()
tl = time_left(username) tl = time_left(username)
print("Using card {}. Time left: {}".format(username, tl)) print("Using card {}. Time left: {}".format(username, tl))
log("Connecting with card {}. Time left on card: {}".format(username, tl)) log("Connecting with card {}. Time left on card: {}".format(username, tl))
@ -241,10 +227,9 @@ def fetch_expire_date(username, password):
form['password'] = password form['password'] = password
r = session.post(action, form) r = session.post(action, form)
soup = bs4.BeautifulSoup(r.text, 'html.parser') soup = bs4.BeautifulSoup(r.text, 'html.parser')
exp_node = soup.find(string=re.compile("expiración")) exp_text = soup.find(string=re.compile("expiración"))\
if not exp_node: .parent.find_next_sibling('td')\
return "**invalid credentials**" .text.strip()
exp_text = exp_node.parent.find_next_sibling('td').text.strip()
exp_text = exp_text.replace('\\', '') exp_text = exp_text.replace('\\', '')
return exp_text return exp_text
@ -253,36 +238,34 @@ def fetch_usertime(username):
r = session.get("https://secure.etecsa.net:8443/EtecsaQueryServlet?op=getLeftTime&op1={}".format(username)) r = session.get("https://secure.etecsa.net:8443/EtecsaQueryServlet?op=getLeftTime&op1={}".format(username))
return r.text return r.text
def time_left(username, fresh=False, cached=False): def time_left(username, fresh=False):
now = time.time() now = time.time()
with dbm.open(CARDS_DB, "c") as cards_db: with dbm.open(CARDS_DB, "c") as cards_db:
card_info = json.loads(cards_db[username].decode()) card_info = json.loads(cards_db[username].decode())
last_update = card_info.get('last_update', 0) last_update = card_info.get('last_update', 0)
password = card_info['password'] password = card_info['password']
if not cached: if (now - last_update > 60) or fresh:
if (now - last_update > 60) or fresh: time_left = fetch_usertime(username)
time_left = fetch_usertime(username) last_update = time.time()
last_update = time.time() if re.match(r'[0-9:]+', time_left):
if re.match(r'[0-9:]+', time_left): card_info['time_left'] = time_left
card_info['time_left'] = time_left card_info['last_update'] = last_update
card_info['last_update'] = last_update cards_db[username] = json.dumps(card_info)
cards_db[username] = json.dumps(card_info)
time_left = card_info.get('time_left', '-') time_left = card_info.get('time_left', '-')
return time_left return time_left
def expire_date(username, fresh=False, cached=False): def expire_date(username, fresh=False):
# expire date computation won't depend on last_update # expire date computation won't depend on last_update
# because the expire date will change very infrequently # because the expire date will change very infrequently
# in the case of rechargeable accounts and it will # in the case of rechargeable accounts and it will
# never change in the case of non-rechargeable cards # never change in the case of non-rechargeable cards
with dbm.open(CARDS_DB, "c") as cards_db: with dbm.open(CARDS_DB, "c") as cards_db:
card_info = json.loads(cards_db[username].decode()) card_info = json.loads(cards_db[username].decode())
if not cached: if (not 'expire_date' in card_info) or fresh:
if (not 'expire_date' in card_info) or fresh: password = card_info['password']
password = card_info['password'] exp_date = fetch_expire_date(username, password)
exp_date = fetch_expire_date(username, password) card_info['expire_date'] = exp_date
card_info['expire_date'] = exp_date cards_db[username] = json.dumps(card_info)
cards_db[username] = json.dumps(card_info)
exp_date = card_info['expire_date'] exp_date = card_info['expire_date']
return exp_date return exp_date
@ -313,32 +296,14 @@ def cards(args):
print("{}\t{}\t{}\t(expires {})".format( print("{}\t{}\t{}\t(expires {})".format(
card, card,
password, password,
time_left(card, args.fresh, args.cached), time_left(card, args.fresh),
expire_date(card, args.fresh, args.cached) expire_date(card, args.fresh)
)) ))
def verify(username, password):
session = requests.Session()
r = session.get("https://secure.etecsa.net:8443/")
soup = bs4.BeautifulSoup(r.text, 'html.parser')
form = get_inputs(soup)
action = "https://secure.etecsa.net:8443/EtecsaQueryServlet"
form['username'] = username
form['password'] = password
r = session.post(action, form)
soup = bs4.BeautifulSoup(r.text, 'html.parser')
exp_node = soup.find(string=re.compile("expiración"))
if not exp_node:
return False
return True
def cards_add(args): def cards_add(args):
username = args.username or input("Username: ") if not args.username:
username = input("Username: ")
password = input("Password: ") password = input("Password: ")
if not verify(username, password):
print("Credentials seem incorrect")
return
with dbm.open(CARDS_DB, "c") as cards_db: with dbm.open(CARDS_DB, "c") as cards_db:
cards_db[username] = json.dumps({ cards_db[username] = json.dumps({
'password': password, 'password': password,
@ -355,7 +320,7 @@ def cards_clean(args):
delete_cards(cards_to_purge) delete_cards(cards_to_purge)
def cards_rm(args): def cards_rm(args):
delete_cards(args.usernames) delete_cards(args.cards)
def cards_info(args): def cards_info(args):
username = args.username username = args.username
@ -399,9 +364,9 @@ def main(args):
epilog=dedent("""\ epilog=dedent("""\
Subcommands: Subcommands:
up [username] up
down down
cards [-v] [-f] [-c] cards [-v] [-f]
cards add [username] cards add [username]
cards clean cards clean
cards rm username [username ...] cards rm username [username ...]
@ -412,10 +377,6 @@ def main(args):
formatter_class=argparse.RawDescriptionHelpFormatter formatter_class=argparse.RawDescriptionHelpFormatter
) )
subparsers = parser.add_subparsers() subparsers = parser.add_subparsers()
parser.add_argument("-d", "--debug",
action="store_true",
help="show debug info"
)
cards_parser = subparsers.add_parser('cards') cards_parser = subparsers.add_parser('cards')
cards_parser.set_defaults(func=cards) cards_parser.set_defaults(func=cards)
@ -427,10 +388,6 @@ def main(args):
action="store_true", action="store_true",
help="force a fresh request of card time" help="force a fresh request of card time"
) )
cards_parser.add_argument("-c", "--cached",
action="store_true",
help="shows cached data, avoids the network"
)
cards_subparsers = cards_parser.add_subparsers() cards_subparsers = cards_parser.add_subparsers()
cards_add_parser = cards_subparsers.add_parser('add') cards_add_parser = cards_subparsers.add_parser('add')
cards_add_parser.set_defaults(func=cards_add) cards_add_parser.set_defaults(func=cards_add)
@ -449,18 +406,11 @@ def main(args):
up_parser = subparsers.add_parser('up') up_parser = subparsers.add_parser('up')
up_parser.set_defaults(func=up) up_parser.set_defaults(func=up)
up_parser.add_argument('username', nargs="?")
down_parser = subparsers.add_parser('down') down_parser = subparsers.add_parser('down')
down_parser.set_defaults(func=down) down_parser.set_defaults(func=down)
args = parser.parse_args() args = parser.parse_args()
if args.debug:
logging.basicConfig(level=logging.DEBUG)
from http.client import HTTPConnection
HTTPConnection.debuglevel = 2
if 'func' in args: if 'func' in args:
args.func(args) args.func(args)
else: else: