Skip to content

Commit

Permalink
add UslugiOn to tele2 and beeline, fix web server plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
artyl committed Jun 17, 2020
1 parent 1435e8c commit a6e424f
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 84 deletions.
30 changes: 26 additions & 4 deletions plugin/beeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@


def api(session, token, login, item):
apiURL = 'https://my.beeline.ru/api/1.0/' + \
item + '?ctn=' + login + '&token=' + token
apiURL = 'https://my.beeline.ru/api/1.0/' + item + '?ctn=' + login + '&token=' + token
response = session.get(apiURL)
if response.status_code != 200:
raise RuntimeError(
f'api get {item} error status_code {response2.status_code}!=200')
f'api get {item} error status_code {response.status_code}!=200')
if 'json' not in response.headers.get('content-type'):
raise RuntimeError(f'api {item} not return json {response.text}')
return response.json()
Expand All @@ -32,7 +31,7 @@ def get_balance(login, password, storename=None):
response1 = session.get(uri)
if response1.status_code != 200:
raise RuntimeError(
f'Login error: status_code {response2.status_code}!=200')
f'Login error: status_code {response1.status_code}!=200')

if 'json' not in response1.headers.get('content-type') or response1.json()['meta']['status'] != 'OK':
raise RuntimeError(f'Login error: .meta.status!=OK {response1.text}')
Expand All @@ -50,6 +49,29 @@ def get_balance(login, password, storename=None):
if jsonTariff['meta']['status'] == 'OK':
result['TarifPlan'] = jsonTariff['pricePlanInfo']['entityName']

# список услуг
jsonSubscr = api(session, token, login, 'info/subscriptions')
subscr = len(jsonSubscr.get('subscriptions',[]))
jsonServices = api(session, token, login, 'info/serviceList')
paid_sum = 0
ppi = jsonTariff['pricePlanInfo']
if ppi['rcRate'] is not None and ppi['rcRatePeriod'] is not None:
kperiod = 30 if jsonTariff['pricePlanInfo']['rcRatePeriod'].split('.')[-1]=='dayly' else 1
paid_sum = ppi['rcRate'] * kperiod
services = []
for el in jsonServices['services']:
if el['rcRate'] is not None and el['rcRatePeriod'] is not None:
kperiod = 30 if el['rcRatePeriod'].split('.')[-1]=='dayly' else 1
fee = el['rcRate'] * kperiod
else:
fee = 0
services.append((el['entityName'],fee))
free = len([a for a, b in services if b == 0]) # бесплатные
paid = len([a for a, b in services if b != 0]) # платные
paid_sum = paid_sum+round(sum([b for a, b in services if b != 0]), 2)
result['UslugiOn'] = f'{free}/{subscr}/{paid}({paid_sum})'
result['UslugiList'] = '\n'.join([f'{a}\t{b}' for a, b in services])

jsonStatus = api(session, token, login, 'info/status')
if jsonStatus['meta']['status'] == 'OK':
result['BlockStatus'] = jsonStatus['status']
Expand Down
15 changes: 15 additions & 0 deletions plugin/dbengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,20 @@ def report(self,fields):
data = rows.fetchall()
return headers,data

def write_result_to_db(plugin, login, result):
'пишем в базу если в ini установлен sqlitestore=1'
try:
options = store.read_ini()['Options']
if options.get('sqlitestore','0') == '1':
dbfilename = options.get('dbfilename', settings.dbfilename)
logging.info(f'Пишем в базу {dbfilename}')
db = dbengine(dbfilename)
db.write_result(plugin, login, result)
except AttributeError:
logging.info(f'Отсутствуют параметры {"".join(traceback.format_exception(*sys.exc_info()))} дополнительные действия не производятся')
except Exception:
logging.error(f'Ошибка при записи в БД {"".join(traceback.format_exception(*sys.exc_info()))}')


if __name__ == '__main__':
print('This is module dbengine')
47 changes: 30 additions & 17 deletions plugin/httpserver_mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@

lang='p' # Для плагинов на python преффикс lang всегда 'p'

def result_to_html(result):
'Конвертирует словарь результатов в готовый к отдаче вид '
# Коррекция SMS и Min (должны быть integer)
if 'SMS' in result:
result['SMS'] = int(result['SMS'])
if 'Min' in result:
result['Min'] = int(result['Min'])
body = json.dumps(result, ensure_ascii=False)
return f'<html><meta charset="windows-1251"><p id=response>{body}</p></html>'

def find_ini_up(fn):
allroot = [os.getcwd().rsplit('\\',i)[0] for i in range(len(os.getcwd().split('\\')))]
all_ini = [i for i in allroot if os.path.exists(os.path.join(i,fn))]
Expand All @@ -36,6 +26,7 @@ def getbalance(param):
if len(param) != 4:
return 'text/html', [f'<html>Unknown call - use getbalance/plugin/login/password/date</html>']
fplugin,login,password,date = param
logging.info(f'Start {fplugin} {login}')
#print(f'{fn=} {fn.split("/")=}')
#print(f'{fplugin=} {login=} {password=} {date=}')
# Это плагин от python ?
Expand All @@ -45,9 +36,14 @@ def getbalance(param):
module = __import__(plugin, globals(), locals(), [], 0)
importlib.reload(module) # обновляем модуль, на случай если он менялся
result = module.get_balance(login, password, f'{lang}_{plugin}_{login}')
text = result_to_html(result)
#print(text)
text = store.result_to_html(result)
# пишем в базу
dbengine.write_result_to_db(f'{lang}_{plugin}', login, result)
# генерируем balance_html
write_report()
logging.info(f'Complete {fplugin} {login}')
return 'text/html', text
logging.error(f'Unknown plugin {fplugin}')
return 'text/html', [f'<html>Unknown plugin {fplugin}</html>']
except Exception:
exception_text = f'Ошибка: {"".join(traceback.format_exception(*sys.exc_info()))}'
Expand Down Expand Up @@ -137,6 +133,20 @@ def getreport(param=[]):
res = template.format(style=style, html_header=html_header, html_table='\n'.join(html_table))
return 'text/html', [res]


def write_report():
'сохраняем отчет balance_html если в ini createhtmlreport=1'
try:
options = store.read_ini()['Options']
if options.get('createhtmlreport','0') == '1':
_,res = getreport()
balance_html = options.get('balance_html', settings.balance_html)
logging.info(f'Создаем {balance_html}')
open(balance_html,encoding='utf8',mode='w').write('\n'.join(res))
except Exception:
logging.error(f'Ошибка генерации {balance_html} {"".join(traceback.format_exception(*sys.exc_info()))}')


class TrayIcon:
def __init__(self):
msg_TaskbarRestart = win32gui.RegisterWindowMessage("TaskbarCreated");
Expand Down Expand Up @@ -195,12 +205,13 @@ def OnDestroy(self, hwnd, msg, wparam, lparam):

def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
if lparam==win32con.WM_LBUTTONDBLCLK:
print("You double-clicked me - goodbye")
win32gui.DestroyWindow(self.hwnd)
#print("You double-clicked me - goodbye")
#win32gui.DestroyWindow(self.hwnd)
pass
elif lparam==win32con.WM_RBUTTONUP:
print("You right clicked me.")
menu = win32gui.CreatePopupMenu()
#win32gui.AppendMenu( menu, win32con.MF_STRING, 1024, "Say Hello")
win32gui.AppendMenu( menu, win32con.MF_STRING, 1024, "Open report")
win32gui.AppendMenu( menu, win32con.MF_STRING, 1025, "Exit program" )
pos = win32gui.GetCursorPos()
# See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp
Expand All @@ -211,8 +222,10 @@ def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):

def OnCommand(self, hwnd, msg, wparam, lparam):
id = win32api.LOWORD(wparam)
#if id == 1024: print("Hello")
if id == 1025:
if id == 1024:
port = int(store.read_ini()['HttpServer'].get('port', settings.port))
os.system('start http://localhost:8000/report')
elif id == 1025:
print("Goodbye")
win32gui.DestroyWindow(self.hwnd)
else:
Expand Down
42 changes: 5 additions & 37 deletions plugin/mbplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,10 @@
import time, os, sys, logging, traceback
import xml.etree.ElementTree as etree
sys.path.append(os.path.split(os.path.abspath(sys.argv[0]))[0])
import dbengine, store, settings
import dbengine, store, settings, httpserver_mobile

lang = 'p' # Для плагинов на python преффикс lang всегда 'p'


def result_to_xml(result):
'Конвертирует словарь результатов в готовый к отдаче вид '
# Коррекция SMS и Min (должны быть integer)
if 'SMS' in result:
result['SMS'] = int(result['SMS'])
if 'Min' in result:
result['Min'] = int(result['Min'])
for k, v in result.items():
if type(v) == float:
result[k] = round(v, 2) # Чтобы не было паразитных микрокопеек
body = ''.join([f'<{k}>{v}</{k}>' for k, v in result.items()])
return f'<Response>{body}</Response>'


def main():
logging_level = store.read_ini()['Options']['logginglevel']
logging.basicConfig(filename="..\\log\\mbplugin.log", level=logging_level,
Expand Down Expand Up @@ -70,33 +55,16 @@ def main():
return -1
# Готовим результат
try:
sys.stdout.write(result_to_xml(result))
sys.stdout.write(store.result_to_xml(result))
except Exception:
exception_text = f'Ошибка при подготовке результата: {"".join(traceback.format_exception(*sys.exc_info()))}'
logging.error(exception_text)
sys.stdout.write(exception_text)
return -1
# пишем в базу
try:
options = store.read_ini()['Options']
if options.get('sqlitestore','0') == '1':
logging.info(f'Пишем в базу sqlite')
dbfilename = options.get('dbfilename', settings.dbfilename)
db = dbengine.dbengine(dbfilename)
db.write_result(f'{lang}_{plugin}', login, result)
except AttributeError:
logging.info(f'Отсутствуют параметры {"".join(traceback.format_exception(*sys.exc_info()))} дополнительные действия не производятся')
except Exception:
logging.error(f'Ошибка при записи в БД {"".join(traceback.format_exception(*sys.exc_info()))}')
try:
options = store.read_ini()['Options']
if options.get('createhtmlreport','0') == '1':
import httpserver_mobile
_,res = httpserver_mobile.getreport()
balance_html = options.get('balance_html', settings.balance_html)
open(balance_html,encoding='utf8',mode='w').write('\n'.join(res))
except Exception:
logging.error(f'Ошибка генерации {balance_html} {"".join(traceback.format_exception(*sys.exc_info()))}')
dbengine.write_result_to_db(f'{lang}_{plugin}', login, result)
# генерируем balance_html
httpserver_mobile.write_report()
logging.debug(f'result = {result}')
logging.info(f'Complete {lang} {plugin} {login}\n')
return 0
Expand Down
8 changes: 4 additions & 4 deletions plugin/mts.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ def get_balance(login, password, storename=None):
if 'services' in data:
services = [(i['name'], i.get('subscriptionFees', [{}])[0].get('value', 0)) for i in data['services']]
services.sort(key=lambda i:(-i[1],i[0]))
u1 = len([a for a,b in services if b==0 and (a,b)!=('Ежемесячная плата за тариф', 0)])
u2 = len([a for a,b in services if b!=0])
u2_sum = round(sum([b for a,b in services if b!=0]),2)
result['UslugiOn']=f'{u1}/{u2}({u2_sum})'
free = len([a for a,b in services if b==0 and (a,b)!=('Ежемесячная плата за тариф', 0)])
paid = len([a for a,b in services if b!=0])
paid_sum = round(sum([b for a,b in services if b!=0]),2)
result['UslugiOn']=f'{free}/{paid}({paid_sum})'
result['UslugiList']='\n'.join([f'{a}\t{b}' for a,b in services])

response_json = get_api_json(session, pages, 'sharing/counters', longtask=True)
Expand Down
9 changes: 5 additions & 4 deletions plugin/settings.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# -*- coding: utf8 -*-
''' Файл с общими установками, распространяется с дистрибутивом '''
''' Файл с общими установками, распространяется с дистрибутивом
Значения по умолчанию, здесь ничего не меняем, если хотим поменять меняем в mbplugin.ini
'''
UNIT = {'GB': 1048576, 'ГБ': 1048576, 'GByte': 1048576,
'MB': 1024, 'МБ': 1024, 'MByte': 1024,
'KB': 1, 'КБ': 1, 'KByte': 1}

#Значения по умолчанию, здесь ничего не меняем, если хотим поменять меняем в mbplugin.ini
'KB': 1, 'КБ': 1, 'KByte': 1,
'day': 30, 'dayly': 30, 'month':1,}

# имя ini файла
mbplugin_ini = 'mbplugin.ini'
Expand Down
28 changes: 27 additions & 1 deletion plugin/store.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf8 -*-
'Модуль для хранения сессий и настроек а также чтения настроек из ini от MobileBalance'
import os, sys, re, pickle, requests, configparser
import os, sys, re, json, pickle, requests, configparser
import settings


Expand Down Expand Up @@ -96,6 +96,32 @@ def read_stocks(stocks_name):
stocks['remain'] = {i[0].upper(): int(i[1]) for i in remain_str if len(i) == 2 and i[1].isnumeric()}
return stocks


def result_to_xml(result):
'Конвертирует словарь результатов в готовый к отдаче вид '
# Коррекция SMS и Min (должны быть integer)
if 'SMS' in result:
result['SMS'] = int(result['SMS'])
if 'Min' in result:
result['Min'] = int(result['Min'])
for k, v in result.items():
if type(v) == float:
result[k] = round(v, 2) # Чтобы не было паразитных микрокопеек
body = ''.join([f'<{k}>{v}</{k}>' for k, v in result.items()])
return f'<Response>{body}</Response>'


def result_to_html(result):
'Конвертирует словарь результатов в готовый к отдаче вид '
# Коррекция SMS и Min (должны быть integer)
if 'SMS' in result:
result['SMS'] = int(result['SMS'])
if 'Min' in result:
result['Min'] = int(result['Min'])
body = json.dumps(result, ensure_ascii=False)
return f'<html><meta charset="windows-1251"><p id=response>{body}</p></html>'


if __name__ == '__main__':
print('Module store')
# print(list(read_ini('phones.ini').keys()))
Expand Down
49 changes: 34 additions & 15 deletions plugin/tele2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
''' Автор ArtyLa '''
import os, sys, re, logging
import requests
import store
import store, settings

def get_balance(login, password, storename=None):
''' На вход логин и пароль, на выходе словарь с результатами '''
Expand All @@ -25,8 +25,8 @@ def check_or_get_bearer(session):
f'Bearer get error {response2.status_code} for login {login}')
raise RuntimeError(f'Bearer get error {response2.status_code}')

def get_from_js(response, val):
return str(response.json()['data'][val]) if response.status_code == 200 else ''
def get_data(response):
return response.json().get('data',{}) if response.status_code == 200 else ''

result = {}
headers = {
Expand All @@ -44,18 +44,37 @@ def get_from_js(response, val):
session = requests.Session()
session.headers.update(headers)
session = check_or_get_bearer(session)
response = session.get(
f'https://api.tele2.ru/api/subscribers/7{login}/balance')
result['Balance'] = get_from_js(response, 'value') # баланс
response = session.get(
f'https://api.tele2.ru/api/subscribers/7{login}/tariff')
result['TarifPlan'] = get_from_js(response, 'frontName') # тариф
response = session.get(
f'https://api.tele2.ru/api/subscribers/7{login}/profile')
result['UserName'] = get_from_js(response, 'fullName') # ФИО владельца
response = session.get(
f'https://api.tele2.ru/api/subscribers/7{login}/rests')
rests = response.json().get('data', {}).get('rests', [])
response_b = session.get(f'https://api.tele2.ru/api/subscribers/7{login}/balance')
result['Balance'] = get_data(response_b).get('value') # баланс
response_t = session.get(f'https://api.tele2.ru/api/subscribers/7{login}/tariff')
result['TarifPlan'] = get_data(response_t).get('frontName', '') # тариф
response_p = session.get(f'https://api.tele2.ru/api/subscribers/7{login}/profile')
result['UserName'] = get_data(response_p).get('fullName', '') # ФИО владельца
siteId = get_data(response_p).get('siteId','') # регион

# список услуг
response_с = session.get(f'https://api.tele2.ru/api/subscribers/7{login}/{siteId}/services?status=connected')
# Тарифный план у tele2 за услугу не считается, так что просто прибавляем его цену
tarif_fee = get_data(response_t).get('currentAbonentFee', {}).get('amount', 0)
tarif_period = get_data(response_t).get('period')
paid_sum = tarif_fee*settings.UNIT.get(tarif_period, 1)
services = []
for el in get_data(response_с):
name = el.get('name', '')
abonentFee = el.get('abonentFee', {})
fee = abonentFee.get('amount', 0)
fee = 0 if fee is None else fee
kperiod = settings.UNIT.get(abonentFee.get('period', ''), 1)
services.append((name, fee*kperiod))
free = len([a for a, b in services if b == 0]) # бесплатные
paid = len([a for a, b in services if b != 0]) # платные
paid_sum = paid_sum+round(sum([b for a, b in services if b != 0]), 2)
result['UslugiOn'] = f'{free}/{paid}({paid_sum})'
result['UslugiList'] = '\n'.join([f'{a}\t{b}' for a, b in services])

# остатки
response_r = session.get(f'https://api.tele2.ru/api/subscribers/7{login}/rests')
rests = get_data(response_r).get('rests', [])
if len(rests) > 0:
result['Min'] = 0
result['Internet'] = 0
Expand Down
Loading

0 comments on commit a6e424f

Please sign in to comment.