Tesco Mobile Ireland Balance

Displays your current Tesco Mobile Ireland balance and available data, text and voice allowances

Image preview of Tesco Mobile Ireland Balance plugin.

tescomobileirl.1h.py

Edit
Open on GitHub
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# <xbar.title>Tesco Mobile Ireland Balance</xbar.title>
# <xbar.version>v1.0.0</xbar.version>
# <xbar.author>Jack Higgins</xbar.author>
# <xbar.author.github>skhg</xbar.author.github>
# <xbar.desc>Displays your current Tesco Mobile Ireland balance and available data, text and voice allowances</xbar.desc>
# <xbar.image>https://github.com/skhg/BitBar-Plugins/blob/master/TescoMobileIrl/tescobalance.jpg?raw=true</xbar.image>
# <xbar.dependencies>python 2.7 or 3.6, pytescomobileirl</xbar.dependencies>
# <xbar.abouturl>https://github.com/skhg/BitBar-Plugins/tree/master/TescoMobileIrl</xbar.abouturl>







# START USER DETAILS

# Enter your tescomobile.ie login details here. These are sent only to the tesco mobile
# website and never stored or transmitted anywhere else.

phone_num = "MyPhoneNumber"
password = "MyPassword"

# END USER DETAILS






from sys import exit

# VERIFY DEPENDENCIES
try:
    from pytescomobileirl import TescoSession
except ImportError:
    print("Tesco Mobile Ireland")
    print("---")
    print("Looks like the package 'pytescomobileirl' isn't installed.")
    print("You need it to run this tool. To install, click 'Install Now',")
    print("then click 'Preferences' -> 'Refresh All...'")
    print("Install Now. | bash='sudo /usr/local/bin/pip install pytescomobileirl'")
    exit()






# START APP

import pickle
import os
import subprocess

class StateMgmt:
    
    def __init__(self):
        os.chdir(self.get_bitbar_plugins_dir())
        self.relative_state_dir = "./.tescomobileirl_state/"
        self.state_dump_file = self.relative_state_dir+"tescomobileirl_last_state.pickle"

    def get_bitbar_plugins_dir(self):
        bitbar_defaults = subprocess.check_output(["defaults", "read", "com.matryer.BitBar"]).split(";")
        for entry in bitbar_defaults:
            if "pluginsDirectory" in entry:
                return entry.split("\"")[1]

        raise IOError("BitBar plugins directory could not be found")
    
    def check_state_dir_exists(self, state_dir):
        if os.path.exists(state_dir) is False:
            os.mkdir(state_dir)
    
    def load_state(self):
        self.check_state_dir_exists(self.relative_state_dir)

        if os.path.exists(self.state_dump_file) is False:
            return None
        else:
            try:
                with open(self.state_dump_file,"r") as f_read:
                    return pickle.load(f_read)
            except:
                return None
    
    def dump_state(self, current_state):
        self.check_state_dir_exists(self.relative_state_dir)

        with open(self.state_dump_file,"w") as f_write:
            pickle.dump(current_state,f_write)

class ResultsFormatter:
	def print_output(self, balances, is_live):
		print(balances.remaining_total("data").summary())
		print("---")
		if is_live is False:
		    print("❌ : Using cached data, last update failed")
		    print("---")

		print("Number: "+phone_num)
		print("---")
		print(u'€{:,.2f} credit'.format(balances.credit_remaining).encode("utf-8"))
		print("---")
		print("Active bundles:")
		for bundle in balances.active_balances():
		    print(bundle.summary() + " for "+ str(bundle.days_remaining())+" days")
		print("---")

		print("tescomobile.ie | href=https://my.tescomobile.ie/tmi-selfcare-web/login")
    
	def print_error_message(self):
		print("❌")
		print("---")
		print("Error: Unable to retrieve Tesco Mobile state.")
		print("---")

		print("tescomobile.ie | href=https://my.tescomobile.ie/tmi-selfcare-web/login")

def run():
    login_ok= False

    session = TescoSession()

    try:
        login_ok = session.login(phone_num, password)
    except Exception:
        pass

    state = StateMgmt()
    formatter = ResultsFormatter()

    if login_ok:
        balances = session.get_balances()
        
        state.dump_state(balances)
        formatter.print_output(balances,True)
    else:
        loaded_state = state.load_state()
        if loaded_state is not None:
            formatter.print_output(loaded_state,False)
        else:
            formatter.print_error_message()

run()