Big website update

This commit is contained in:
Deltaion Lee 2023-02-01 21:13:52 -06:00
parent af134d9959
commit c08ef3e6aa
12 changed files with 179 additions and 60 deletions

View File

@ -22,8 +22,10 @@ Due to the nature of this app, it constantly scrapes the bot's friend list and s
| `mii` | `text` | | `mii` | `text` |
| `joinable` | `boolean` | | `joinable` | `boolean` |
| `gameDescription` | `text` | | `gameDescription` | `text` |
| `jeuFavori`\* | `bigint` |
The above objects are scraped and stored by the friend bot. The above objects are scraped and stored by the friend bot.
\*`jeuFavori` is the user's favorite game
<h3 id = 'article2'>How Do I Opt-Out?</h3> <h3 id = 'article2'>How Do I Opt-Out?</h3>

View File

@ -112,21 +112,27 @@ async def main():
ti.unk2 = 0 # A cursed (but operable) 'hack' ti.unk2 = 0 # A cursed (but operable) 'hack'
try: try:
j1 = await friends_client.get_friend_comment([ti,]) j1 = await friends_client.get_friend_persistent_info([ti.unk1,])
except: except:
continue continue
comment = j1[0].message
jeuFavori = 0
username = '' username = ''
face = '' face = ''
if not j1[0].comment.endswith(' '): if not comment.endswith(' '):
# Get user's mii + username from mii
m = await friends_client.get_friend_mii([ti,]) m = await friends_client.get_friend_mii([ti,])
username = m[0].mii.unk1 username = m[0].mii.unk1
mii_data = m[0].mii.mii_data mii_data = m[0].mii.mii_data
obj = MiiData() obj = MiiData()
obj.decode(obj.convert(io.BytesIO(mii_data))) obj.decode(obj.convert(io.BytesIO(mii_data)))
face = obj.mii_studio()['data'] face = obj.mii_studio()['data']
# Get user's favorite game
jeuFavori = j1[0].game_key.title_id
else: else:
j1[0].comment = '' comment = ''
cursor.execute('UPDATE friends SET username = \'%s\', message = \'%s\', mii = \'%s\' WHERE friendCode = \'%s\'' % (username, j1[0].comment, face, str(convertPrincipalIdtoFriendCode(ti.unk1)).zfill(12))) cursor.execute('UPDATE friends SET username = \'%s\', message = \'%s\', mii = \'%s\', jeuFavori = \'%s\' WHERE friendCode = \'%s\'' % (username, comment, face, jeuFavori, str(convertPrincipalIdtoFriendCode(ti.unk1)).zfill(12)))
con.commit() con.commit()
for friend in rotation + cleanUp: for friend in rotation + cleanUp:

View File

@ -35,7 +35,7 @@ def handler404(e):
# Limiter limits # Limiter limits
userPresenceLimit = '3/minute' userPresenceLimit = '3/minute'
newUserLimit = '2/minute' newUserLimit = '2/minute'
cdnLimit = '20/minute' cdnLimit = '30/minute'
# Database files # Database files
titleDatabase = [] titleDatabase = []
@ -157,6 +157,7 @@ def getPresence(friendCode:int, *, créerCompte:bool = True, ignoreUserAgent = F
'accountCreation': result[5], 'accountCreation': result[5],
'lastAccessed': result[4], 'lastAccessed': result[4],
'lastOnline': result[11], 'lastOnline': result[11],
'favoriteGame': result[12],
} }
} }
except Exception as e: except Exception as e:
@ -212,18 +213,40 @@ def settings():
response = make_response(render_template('dist/settings.html', data = sidenav())) response = make_response(render_template('dist/settings.html', data = sidenav()))
return response return response
# Register page
@app.route('/register.html')
def register():
response = make_response(render_template('dist/register.html'))
return response
# Failure page
@app.route('/failure.html')
def failure():
return render_template('dist/failure.html')
# Success page
@app.route('/success.html')
def success():
data = {
'url': 'user/' + request.args.get('fc'),
}
return render_template('dist/success.html', data = data)
@app.route('/user/<string:friendCode>/') @app.route('/user/<string:friendCode>/')
def userPage(friendCode:str): def userPage(friendCode:str):
try: try:
userData = getPresence(int(friendCode), créerCompte = False, ignoreUserAgent = True, ignoreBackend = True) userData = getPresence(int(friendCode.replace('-', '')), créerCompte = False, ignoreUserAgent = True, ignoreBackend = True)
if userData['Exception'] or not userData['User']['username']: if userData['Exception'] or not userData['User']['username']:
raise Exception(userData['Exception']) raise Exception(userData['Exception'])
except: except:
return redirect('/404.html') return render_template('dist/404.html')
if userData['User']['online'] and userData['User']['Presence']: if userData['User']['online'] and userData['User']['Presence']:
userData['User']['Presence']['game'] = getTitle(userData['User']['Presence']['titleID'], titlesToUID, titleDatabase) userData['User']['Presence']['game'] = getTitle(userData['User']['Presence']['titleID'], titlesToUID, titleDatabase)
else: else:
userData['User']['Presence']['game'] = None userData['User']['Presence']['game'] = None
userData['User']['favoriteGame'] = getTitle(userData['User']['favoriteGame'], titlesToUID, titleDatabase)
if userData['User']['favoriteGame']['name'] == 'Home Screen':
userData['User']['favoriteGame'] = None
for i in ('accountCreation','lastAccessed','lastOnline'): for i in ('accountCreation','lastAccessed','lastOnline'):
if userData['User'][i] == 0: if userData['User'][i] == 0:
userData['User'][i] = 'Never' userData['User'][i] = 'Never'
@ -250,9 +273,10 @@ def terms():
# Create entry in database with friendCode # Create entry in database with friendCode
@app.route('/api/user/create/<int:friendCode>/', methods=['POST']) @app.route('/api/user/create/<int:friendCode>/', methods=['POST'])
@limiter.limit(newUserLimit) @limiter.limit(newUserLimit)
def newUser(friendCode:int): def newUser(friendCode:int, userCheck:bool = True):
try: try:
userAgentCheck() if userCheck:
userAgentCheck()
createUser(friendCode, True) createUser(friendCode, True)
return { return {
'Exception': False, 'Exception': False,
@ -302,6 +326,16 @@ def cdnImage(file:str):
response.headers['Content-Type'] = 'image/jpeg' response.headers['Content-Type'] = 'image/jpeg'
return response return response
# Login route
@app.route('/login', methods=['POST'])
def login():
try:
fc = str(convertPrincipalIdtoFriendCode(convertFriendCodeToPrincipalId(request.form['fc']))).zfill(12)
newUser(fc, False)
except:
return redirect('/failure.html')
return redirect(f'/success.html?fc={fc}')
if __name__ == '__main__': if __name__ == '__main__':
cacheTitles() cacheTitles()
if local: if local:

View File

@ -10,7 +10,8 @@ Create Table friends(
mii text, mii text,
joinable boolean, joinable boolean,
gameDescription text, gameDescription text,
lastOnline bigint NOT NULL lastOnline bigint NOT NULL,
jeuFavori bigint NOT NULL
); );
Create Table config( Create Table config(

View File

@ -27,7 +27,6 @@ html(lang='en')
include includes/head/title.pug include includes/head/title.pug
include includes/head/css.pug include includes/head/css.pug
include includes/head/icons.pug include includes/head/icons.pug
include includes/navigation/topnav.pug
body(style="background-image: url({{ url_for('static',filename='assets/img/background.png') }}); background-repeat: no-repeat; background-size: cover;") body(style="background-image: url({{ url_for('static',filename='assets/img/background.png') }}); background-repeat: no-repeat; background-size: cover;")

View File

@ -12,16 +12,10 @@ nav.sb-topnav.navbar.navbar-expand.navbar-dark(id = 'topnav')
form.d-none.d-md-inline-block.form-inline.ms-auto.me-0.me-md-3.my-2.my-md-0 form.d-none.d-md-inline-block.form-inline.ms-auto.me-0.me-md-3.my-2.my-md-0
// What was once the account toolbar... // What was once the account toolbar...
//-ul.navbar-nav.ms-auto.ms-md-0.me-3.me-lg-4 ul.navbar-nav.ms-auto.ms-md-0.me-3.me-lg-4
li.nav-item.dropdown li.nav-item.dropdown
a#navbarDropdown.nav-link.dropdown-toggle(href='#' role='button' data-bs-toggle='dropdown' aria-expanded='false') a#navbarDropdown.nav-link.dropdown-toggle(href='#' role='button' data-bs-toggle='dropdown' aria-expanded='false')
i.fas.fa-user.fa-fw i.fas.fa-user.fa-fw
ul.dropdown-menu.dropdown-menu-end(aria-labelledby='navbarDropdown')#accountSymbol ul.dropdown-menu.dropdown-menu-end(aria-labelledby='navbarDropdown')
li li
a.dropdown-item(href='settings.html') Settings a.dropdown-item(href='register.html') Register
li
a.dropdown-item(href='activity.html') Activity Log
li
hr.dropdown-divider
li
a.dropdown-item(href='logout') Logout

View File

@ -0,0 +1,11 @@
extends ../layouts/error.pug
block content
.container
.row.justify-content-center
.col-lg-6
.text-center.mt-4
p.lead Something went wrong! But what?
a(href='/')
i.fas.fa-arrow-left.me-1
| Return to Home

View File

@ -1,5 +1,13 @@
// Optionally, add white background to here as well. card.mb-X // Optionally, add white background to here as well. card.mb-X
h1.mt-4 #{pageTitle} if index || settings
h1.mt-4 #{pageTitle}
else
h1.mt-4
| #{pageTitle}
small(style = 'font-size: 0.7em;')#splitTHIS #{fc}
script.
let x = document.getElementById('splitTHIS');
x.textContent = '(' + (x.textContent.match(/.{1,4}/g) ?? []).join('-') + ')';
if index if index
ol.breadcrumb.mb-4 ol.breadcrumb.mb-4
li.breadcrumb-item.active #{pageTitle} li.breadcrumb-item.active #{pageTitle}

View File

@ -0,0 +1,26 @@
extends ../layouts/authentication.pug
block config
- var pageTitle = 'Register'
block content
.container
.row.justify-content-center
.col-lg-6
.card.shadow-lg.border-0.rounded-lg.mt-5
.card-header
h3.text-center.font-weight-light.my-4 Register
.card-body
form(action = '/login', method = 'POST')
.form-floating.mb-3
input#inputFC.form-control(type = 'text', placeholder = '1234-5678-9012', name = 'fc', value = '')
label(for = 'inputFC') Friend Code
.d-flex.align-items-center.justify-content-end.mt-4.mb-0
input.btn.btn-primary(type = 'submit', value = 'Login')
.card-footer.text-center
.small
| By using this service, you agree to the
a(href='/terms') Terms and Services

View File

@ -1,17 +1,19 @@
extends ../layouts/authentication.pug extends ../layouts/dashboard.pug
block config block config
- var pageTitle = 'Settings' - var bodyClass = 'sb-nav-fixed'
- var pageTitle = "Settings"
- var sidenavStyle = 'sb-sidenav-dark'
- var settings = true;
block content block content
.container .container-fluid.px-4
.row.justify-content-center include includes/page-header.pug
.col-lg-10
.card.shadow-lg.border-0.rounded-lg.mt-5
.card-header
h3.text-center.font-weight-light.my-4 Settings
.card-body
| These are some settings!
.d-flex.justify-content-center
.col-lg-10
.card.text-center
.card-header
b Settings
.card-body
| There's nothing here!

View File

@ -0,0 +1,15 @@
extends ../layouts/error.pug
block content
.container
.row.justify-content-center
.col-lg-6
.text-center.mt-4
h3 Your account has been created!
p.lead But it'll take a minute or two for your profile to be loaded.
a(href='/{{ data["url"] }}')
| Try Profile
br
a(href='/')
i.fas.fa-arrow-left.me-1
| Return to Home

View File

@ -3,51 +3,67 @@ extends ../layouts/dashboard.pug
block config block config
- var bodyClass = 'sb-nav-fixed' - var bodyClass = 'sb-nav-fixed'
- var pageTitle = "{{ data['User']['username'] }}" - var pageTitle = "{{ data['User']['username'] }}"
- var fc = "{{ data['User']['friendCode'] }}"
- var sidenavStyle = 'sb-sidenav-dark' - var sidenavStyle = 'sb-sidenav-dark'
block content block content
.container-fluid.px-4 .container-fluid.px-4
include includes/page-header.pug include includes/page-header.pug
html {% if data['User']['Presence']['game'] %} html {% for game in (data['User']['Presence']['game'], data['User']['favoriteGame']) %}
.modal.fade#gameInfo(tabindex = '-1', aria-labelledby = 'modelLabel', aria-hidden = 'true') html {% if game %}
.modal.fade(tabindex = '-1', aria-labelledby = 'modelLabel', aria-hidden = 'true')
.modal-dialog .modal-dialog
.modal-content .modal-content
.modal-header .modal-header
h5.modal-title#modalLabel h5.modal-title#modalLabel
b {{ data['User']['Presence']['game']['name'] }} b {{ game['name'] }}
| by {{ data['User']['Presence']['game']['publisher']['name'] }} | by {{ game['publisher']['name'] }}
button.btn-close(type = 'button' data-bs-dismiss = 'modal' aria-label = 'Close') button.btn-close(type = 'button' data-bs-dismiss = 'modal' aria-label = 'Close')
.modal-body .modal-body
div div
img(src = "{{ data['User']['Presence']['game']['banner_url'] }}", style = "height: 100%; width: 100%;") img(src = "{{ game['banner_url'] }}", style = "height: 100%; width: 100%;")
div.d-flex.justify-content-between div.d-flex.justify-content-between
div Genre: {{ data['User']['Presence']['game']['display_genre'] }} div Genre: {{ game['display_genre'] }}
div Rating: div Rating:
b {{ data['User']['Presence']['game']['star_rating_info']['score'] }}/5 b {{ game['star_rating_info']['score'] }}/5
| Stars | Stars
div.d-flex.justify-content-between div.d-flex.justify-content-between
div Price: {{ data['User']['Presence']['game']['price_on_retail'] }} div Price: {{ game['price_on_retail'] }}
div Released: div Released:
b {{ data['User']['Presence']['game']['release_date_on_eshop'] }} b {{ game['release_date_on_eshop'] }}
.modal-footer .modal-footer
html {% if data['User']['Presence']['game']['name'] != 'Home Screen' %} html {% if game['name'] != 'Home Screen' %}
button.btn.btn-secondary(type = 'button' onclick = "window.open(`https://www.google.com/search?q={{ '+'.join((data['User']['Presence']['game']['name'] + ' ' + data['User']['Presence']['game']['publisher']['name']).split(' ')) }}`, `_blank`);") Search Online button.btn.btn-secondary(type = 'button' onclick = "window.open(`https://www.google.com/search?q={{ '+'.join((game['name'] + ' ' + game['publisher']['name']).split(' ')) }}`, `_blank`);") Search Online
html {% endif %} html {% endif %}
button.btn.btn-primary(type = 'button' data-bs-dismiss = 'modal') Close button.btn.btn-primary(type = 'button' data-bs-dismiss = 'modal') Close
html {% else %}
.modal.fade(tabindex = '-1', aria-labelledby = 'modelLabel', aria-hidden = 'true')
.modal-dialog
.modal-content
.modal-footer
button.btn.btn-primary(type = 'button' data-bs-dismiss = 'modal') Close
html {% endif %} html {% endif %}
html {% endfor %}
script.
let f = document.getElementsByClassName('modal');
for (let i = 0; i < f.length; i++)
{
f[i].id = 'ID' + i.toString();
}
.row .row
.col-sm-2.d-flex.align-items-end .col-sm-2.d-flex.align-items-end
img(src = "{{ data['User']['mii']['face'] }}", width = '100%', style = 'background: linear-gradient(0deg, rgb(255, 198, 147) 0%, rgb(254, 245, 239, 0.1) 100%);') img(src = "{{ data['User']['mii']['face'] }}", width = '100%', style = 'background: linear-gradient(0deg, rgb(255, 198, 147) 0%, rgb(254, 245, 239, 0.1) 100%);')
.col-md-5 .col-md-5
.row(style = 'padding-top: 25px') .row(style = 'padding-top: 2rem;')
.card.text-center .card.text-center
html {% if data['User']['Presence']['game'] %} html {% if data['User']['Presence']['game'] %}
.card-header(style = 'background-color: inherit;') .card-header(style = 'background-color: inherit;')
| Currently playing... b CURRENTLY PLAYING
html {% endif %} html {% endif %}
a.card-body.d-flex.align-items-center.text-black(style = 'text-decoration: none;', data-bs-toggle="modal", href = '#gameInfo') a.card-body.d-flex.align-items-center.text-black(style = 'text-decoration: none;', data-bs-toggle="modal", href = '#ID0')
html {% if data['User']['Presence']['game'] %} html {% if data['User']['Presence']['game'] %}
.col-md-2 .col-md-2
img(src = "{{ data['User']['Presence']['game']['icon_url'] }}", width = '100%') img(src = "{{ data['User']['Presence']['game']['icon_url'] }}", width = '100%')
@ -66,30 +82,35 @@ block content
html {% endif %} html {% endif %}
.row .row
html {% if data['User']['message'] %} html {% if data['User']['message'] %}
.col-xl-2(style = 'padding-top: 25px') .col-xl-2(style = 'padding-top: 2rem')
.card .card
.card-header(style = 'background-color: inherit;') .card-header
b STATUS b STATUS
.card-body .card-body
| {{ data['User']['message'] }} | {{ data['User']['message'] }}
html {% endif %} html {% endif %}
.col-xl-2(style = 'padding-top: 25px') .col-xl-2(style = 'padding-top: 2rem')
.card .card
.card-header(style = 'background-color: inherit;') .card-header
b MEMBER SINCE b MEMBER SINCE
.card-body .card-body
| {{ data['User']['accountCreation'] }} | {{ data['User']['accountCreation'] }}
.col-xl-2(style = 'padding-top: 25px') .col-xl-2(style = 'padding-top: 2rem')
.card .card
.card-header(style = 'background-color: inherit;') .card-header
b LAST ONLINE b LAST ONLINE
.card-body .card-body
| {{ data['User']['lastOnline'] }} | {{ data['User']['lastOnline'] }}
.row.d-flex.justify-content-between(style = 'padding-top: 2rem;') .row(style = 'padding-top: 2rem; padding-bottom: 2rem;')
.col-xl-7 .col-xl-6
.card .card
.card-header(style = 'background-color: inherit;') .card-header
i.fas.fa-chart-area.me-1 b FAVORITE GAME
| Activity Log a.card-body.d-flex.align-items-center.text-black(style = 'text-decoration: none;', data-bs-toggle="modal", href = '#ID1')
.card-body html {% if data['User']['favoriteGame'] %}
.col-md-2
img(src = "{{ data['User']['favoriteGame']['icon_url'] }}", width = '100%')
p(style = 'padding-left: 1rem;') {{ data['User']['favoriteGame']['name'] }}
html {% else %}
.text-muted.text-center None
html {% endif %}