Files
zwift-offline/scripts/get_strava_names.py
2023-04-13 22:52:13 +10:00

146 lines
4.8 KiB
Python
Executable File

#! /usr/bin/env python
# Please be patient
import os
import json
import re
import argparse
import binascii
from requests import Request, Session
import urllib.parse
from requests_toolbelt.multipart.encoder import MultipartEncoder
from bs4 import BeautifulSoup
import re
from nameparser import HumanName
import geograpy
import country_converter as coco
import sys
import getpass
cc = coco.CountryConverter()
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description='Populate Bot names with your strava following list')
parser.add_argument('-u', '--user', help='Zwift user name')
parser.add_argument('country', help="Default country")
args = parser.parse_args()
s = Session()
def find_follows(tag):
return tag and re.compile("type=following").search(tag)
def find_next(tag):
return tag and tag.has_attr("rel") and tag.string == u""
def find_athelete(tag):
return tag.name == 'li' and tag.has_attr("data-athlete-id")
def get_names(response, defcode):
data = []
follow_soup = BeautifulSoup(response.text)
for div in follow_soup.find_all(find_athelete):
tmp = {}
name = HumanName(div.div['title'])
tmp['first_name']=name.first
tmp['last_name']=name.last
resp = urllib.request.urlopen("https://api.genderize.io?name="+name.first.encode("ascii",errors="ignore").decode()).read()
sex = json.loads(resp)
tmp['is_male']=(sex['gender']=="male")
country = geograpy.get_geoPlace_context(text=div.contents[5].text)
code = defcode
if len(country.countries) > 0:
code = cc.convert(names=country.countries[0], to='ISOnumeric')
tmp['country_code'] = code
data.append(tmp)
for tag in follow_soup.find_all(find_next):
next_link = "https://www.strava.com/" + tag['href']
try:
fresponse = s.get(next_link);
except Exception as e:
print('unknown error: ')
return data
data = data + get_names(fresponse, code)
return data
return data
def login(url, username, password, code):
data = []
# acquire cookie
response = s.get(url);
text = response.text
# Get authenticity_token
try:
token = re.search(r'type="hidden" name="authenticity_token" value="(.+?)"', text).group(1)
except AttributeError as e:
print('Cannot find token')
return data
#print ('found token:' + token)
# Login
loginData = urllib.parse.urlencode({
'utf8' : '✓',
'authenticity_token' : token,
'plan' : '',
'email' : username,
'password' : password})
binary_data = loginData.encode('utf-8')
try:
response = s.post("https://www.strava.com/session", data=loginData);
except Exception as e:
print('unknown error: ')
return data
else:
m = re.search('Log Out', response.text)
if m:
print('Successfully logged in')
else:
print('Unsuccessfull login')
sys.exit()
soup = BeautifulSoup(response.text)
for tag in soup.find_all(href=find_follows):
following_link = "https://www.strava.com/" + tag['href']
try:
response = s.get(following_link);
except Exception as e:
print('unknown error: ')
sys.exit()
data = get_names(response, code)
#should be only 1 follow page, so return here
return data
def main() :
if args.user:
username = args.user
else:
username = input("Enter Strava login (e-mail): ")
if not sys.stdin.isatty(): # This terminal cannot support input without displaying text
print('*WARNING* The current shell (%s) cannot support hidden text entry.' % os.name)
print('Your password entry WILL BE VISIBLE.')
print('If you are running a bash shell under windows, try executing this program via winpty:')
print('>winpty python %s' % argv[0])
password = input("Enter password (will be shown):")
else:
password = getpass.getpass("Enter password: ")
code = cc.convert(args.country, to='ISOnumeric')
total_data = {}
total_data['riders'] = login("https://www.strava.com/login", username, password, code)
total_data['body_types'] = [16, 48, 80, 272, 304, 336, 528, 560, 592]
total_data['hair_types'] = [25953412, 175379869, 398510584, 659452569, 838618949, 924073005, 1022111028, 1262230565, 1305767757, 1569595897, 1626212425, 1985754517, 2234835005, 2507058825, 3092564365, 3200039653, 3296520581, 3351295312, 3536770137, 4021222889, 4179410997, 4294226781]
total_data['facial_hair_types'] = [248681634, 398510584, 867351826, 1947387842, 2173853954, 3169994930, 4131541011, 4216468066]
with open('bot.txt', 'w') as outfile:
json.dump(total_data, outfile, indent=2)
if __name__ == "__main__":
main()