mirror of
https://github.com/zoffline/zwift-offline.git
synced 2026-01-08 03:11:12 -08:00
146 lines
4.8 KiB
Python
Executable File
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()
|
|
|