Skip to content

Instantly share code, notes, and snippets.

@gene1wood
Last active December 11, 2021 21:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gene1wood/236f1dcc082950afb4851a382951820c to your computer and use it in GitHub Desktop.
Save gene1wood/236f1dcc082950afb4851a382951820c to your computer and use it in GitHub Desktop.
Tool to fetch a Redpocket account's balance of minutes, texts and data and write that in JSON to a file
import logging
from bs4 import BeautifulSoup
import requests
import yaml
import json
import os.path
import datetime
import re
import sys
# https://gist.github.com/gene1wood/236f1dcc082950afb4851a382951820c
logging.basicConfig()
logger = logging.getLogger()
loglevel = logging.DEBUG if '-v' in sys.argv else logging.ERROR
logger.setLevel(loglevel)
WARN_VOICE = 15
WARN_MESSAGING = 10
WARN_DATA = 50
MIN_VOICE = 15
MIN_MESSAGING = 10
MIN_DATA = 50
DATA_UNIT_MULTIPLIER = {
'MB': 1,
'GB': 1024
}
def buy_addon(user, jar):
# TODO : Finish developing this auto buy thing
page = requests.post(
'https://www.redpocket.com/refill/refill-addons',
cookies=jar)
# get sku
page = requests.get(
'https://www.redpocket.com/refill/refill-plan-new/%s' % sku,
cookies=jar)
page = requests.post(
'https://www.redpocket.com/refill/setup-payment/%s' % sku,
cookies=jar)
# get securityNumber
data = user['billing']
data['term_check'] = 1
data['securityNumber'] = 'foo'
data['autorenew'] = 0
page = requests.post(
'https://www.redpocket.com/refill/charge',
data=data,
cookies=jar)
# {
# "name": "fname",
# "value": "First"
# },
# {
# "name": "lname",
# "value": "Last"
# },
# {
# "name": "phone",
# "value": "2125555555"
# },
# {
# "name": "email",
# "value": "user@example.com"
# },
# {
# "name": "address1",
# "value": "123+First+St."
# },
# {
# "name": "address2",
# "value": ""
# },
# {
# "name": "country",
# "value": "US"
# },
# {
# "name": "state",
# "value": "NY"
# },
# {
# "name": "city",
# "value": "New York"
# },
# {
# "name": "zip",
# "value": "10002"
# },
# {
# "name": "term_check",
# "value": "1"
# },
# {
# "name": "securityNumber",
# "value": "6a39762c8441da30f52a7138999688c26a39762c8441da30f52a7138999688c2"
# },
# {
# "name": "autorenew",
# "value": "0"
# },
# {
# "name": "stripeSource",
# "value": "src_JVxUnuf208q3dNkuJVxUnuf2"
# }
def process_user(user):
jar = requests.cookies.RequestsCookieJar()
page = requests.get('https://www.redpocket.com/login', cookies=jar)
soup = BeautifulSoup(page.text, 'html.parser')
csrf = soup.select(
'body div.content div.container div form.form-signin input[name=csrf]'
)[0]['value']
logger.debug('CSRF is {}'.format(csrf))
data = {
'mdn': user['username'],
'password': user['password'],
'remember_me': 1,
'redirect_url': '',
'csrf': csrf
}
requests.post(
'https://www.redpocket.com/login',
data=data,
cookies=jar)
logger.debug('Cookies are {}'.format(jar))
data = {'refill_mdn': user['mdn']}
page = requests.post(
'https://www.redpocket.com/refill/get-account-info',
data=data,
cookies=jar
)
result = page.json()
logger.debug('get-account-info : {}'.format(result))
total = {}
# 30 Day- Unlimited Everything (10GB@4G LTE)
# 30 Day- Unlimited Everything (3GB@4G LTE)
# 30 Day- Unlimited Everything (5GB@4G LTE)
# 30 Day- Unlimited Everything (3GB@ 4G LTE)
# 30 Day- Unlimited Everything (1GB@4G LTE)
# 30 Day- Unlimited Minutes, Unlimited Texts, 3GB@ 4G LTE
# 30 Day- Unlimited Minutes, Unlimited Texts, 1.5GB@4G LTE
# 30 Day- Unlimited Minutes, Unlimited Texts, 1GB@ 4G LTE
# 30 Day- Unlimited Minutes, Unlimited Texts, 500MB@4G LTE
# 30 Day- Unlimited Minutes, Unlimited Texts, 500MB@ 4G LTE
# 30 Day- 300 Minutes, Unlimited Texts & Data (2GB@4G LTE)
# 90 Day- 1000 Minutes, 1000 Texts & 1GB@4G LTE
# 30 Day- 1000 Minutes, 1000 Texts & 1GB@4G LTE
# 30 Day- 500 Minutes, 500 Texts & 500MB@4G LTE
# 180 Day- PayGo Plan
# 90 Day- PayGo Plan
# 30 Day- PayGo Plan
# $60- Annual 100 MOU/100 SMS/500MB Plan
user_output = {
'datetime': "%s" % datetime.datetime.now(),
'plan_name': result['plan'],
'expiration_date': result['aed']}
logger.debug('Plan : {}'.format(result['plan']))
if 'PayGo' in result['plan']:
pass
elif 'Annual' in result['plan']:
match = re.search(
r'(\d+) MOU/(\d+) SMS/([.\d]+)([MG]B)', result['plan'])
if match:
total['minutes'] = match.group(1)
total['messaging'] = match.group(2)
total['data'] = (
int(match.group(3)) * DATA_UNIT_MULTIPLIER[match.group(4)])
else:
match = re.search(
r'(\d+|Unlimited) (Minutes|Everything)', result['plan'])
if match:
total['minutes'] = (
0 if match.group(1) == 'Unlimited'
else int(match.group(1)))
match = re.search(
r'(\d+|Unlimited) (Texts|Everything)', result['plan'])
if match:
total['messaging'] = (
0 if match.group(1) == 'Unlimited'
else int(match.group(1)))
if ('Unlimited Everything' in result['plan']
or 'Unlimited Texts & Data' in result['plan']):
finite_data_type = '4g_data'
total['data'] = 0
else:
finite_data_type = 'data'
match = re.search(r'([.\d]+)([MG]B)', result['plan'])
if match:
total[finite_data_type] = (
int(match.group(1)) * DATA_UNIT_MULTIPLIER[match.group(2)])
if '4g_data' not in total:
total['4g_data'] = total['data']
user_output['voice_balance'] = result.get('voice_balance')
user_output['total_voice'] = total.get('minutes')
user_output['messaging_balance'] = result.get('messaging_balance')
user_output['total_messaging'] = total.get('messaging')
user_output['data_balance'] = result.get('data_balance')
user_output['status'] = True
user_output['description'] = ''
if result['voice_balance'] < WARN_VOICE:
user_output['status'] = False
user_output['description'] += (
'Remaining voice balance is only %s minutes. ' %
result['voice_balance'])
if result['messaging_balance'] < WARN_MESSAGING:
user_output['status'] = False
user_output['description'] += (
'Remaining SMS balance is only %s texts. ' %
result['messaging_balance'])
if result['data_balance'] < WARN_DATA:
user_output['status'] = False
user_output['description'] += (
'Remaining data balance is only %s MB' %
result['data_balance'])
if user.get('buy_addons') and result['data_balance'] < MIN_DATA:
result = buy_addon(user, jar)
return user_output
def main():
with open(os.path.expanduser('~/.redpocket.conf')) as f:
config = yaml.load(f)
output = {}
status = True
description = ''
for user in config['users']:
output[user['username']] = process_user(user)
status = status and output[user['username']]['status']
description += output[user['username']]['description']
if not description:
description = (
'All pocket accounts have enough data minutes and messages '
'remaining')
output['status'] = status
output['description'] = description
logger.debug('Result : {}'.format(output))
with open('/var/www/html/redpocket-balance.json', 'w') as f:
json.dump(output, f, indent=4, sort_keys=True)
with open('/var/www/html/redpocket-balance.csv', 'a') as f:
for user in config['users']:
record = output[user['username']]
f.write("{},{},{},{},{}\n".format(
record['datetime'], user['username'], record['data_balance'],
record['messaging_balance'], record['voice_balance']))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment