GitHub/GitLab avatar support

This commit is contained in:
datalets 2022-10-09 00:01:28 +02:00
parent 16c898e4ea
commit 4327d81b08
8 changed files with 68 additions and 27 deletions

View File

@ -1,3 +1,4 @@
web: gunicorn --config=gunicorn.conf.py patched:init_app\(\)
default: gunicorn dribdat.app:init_app\(\) -b 0.0.0.0:$DEFAULT_PORT -w 3 --log-file=-
release: ./release.sh
socialize: ./manage.py socialize

View File

@ -42,6 +42,17 @@ def FetchGitlabProject(project_url):
}
def FetchGitlabAvatar(email):
apiurl = "https://gitlab.com/api/v4/avatar?email=%s&size=80"
data = requests.get(apiurl % email)
if data.text.find('{') < 0:
return None
json = data.json()
if 'avatar_url' not in json:
return None
return json['avatar_url']
def FetchGithubProject(project_url):
API_BASE = "https://api.github.com/repos/%s"
data = requests.get(API_BASE % project_url)

View File

@ -8,6 +8,7 @@ from flask import (
jsonify, flash, url_for
)
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from sqlalchemy import or_
from ..extensions import db
from ..utils import timesince, random_password
@ -277,7 +278,7 @@ def event_load_datapackage(): # noqa: C901
if ext not in ['json']:
return 'Invalid format (allowed: JSON)'
with tempfile.TemporaryDirectory() as tmpdir:
filepath = path.join(tmpdir, filedata.filename)
filepath = path.join(tmpdir, secure_filename(filedata.filename))
filedata.save(filepath)
try:
with open(filepath, mode='rb') as file:

View File

@ -10,7 +10,7 @@ from dribdat.database import db
from dribdat.extensions import cache
from dribdat.aggregation import GetEventUsers
from dribdat.user import getProjectStages, isUserActive
from urllib.parse import quote, quote_plus
from urllib.parse import quote, quote_plus, urlparse
from datetime import datetime
import re
@ -34,7 +34,12 @@ def dashboard():
event = current_event()
if not event:
return 'No current event'
wall = 'twitter.com' in event.community_url
wall = False
social_domains = ['twitter.com']
host = urlparse(event.community_url).hostname
for d in social_domains:
if host == d:
wall = True
return render_template(
"public/dashboard.html",
current_event=event, with_social_wall=wall
@ -137,7 +142,7 @@ def user_cert():
# Proceed
return redirect(why)
if why == 'projects':
flash('Please Join a project you worked on to get a certificate.', 'info')
flash('Please Join your team project to get a certificate.', 'info')
elif why == 'event':
flash('A certificate is not yet available for this event.', 'info')
else:

View File

@ -23,7 +23,7 @@
<a href="{{ url_for('public.user', username=user.username) }}"
class="team-gravatar" data-id="{{ user.id }}">
{% if user.carddata %}
<img src="https://www.gravatar.com/avatar/{{user.carddata}}"/>
<img src="{{user.carddata}}"/>
{% endif %}
<span>{{ user.username }}</span>
<div class="team-roles">

View File

@ -73,14 +73,14 @@
<div class="row">
<h1 class="profile-header huge">
<img src="https://www.gravatar.com/avatar/{{user.carddata}}"/>
<img src="{{user.carddata}}"/>
<span>
{{ user.username }}
</span>
</h1>
</div>
<div class="row">
<div class="row mb-3">
{% if user.webpage_url %}
<div class="col-sm">
@ -129,7 +129,7 @@
{% if not projects %}
{% if current_user and current_user.id == user.id %}
<div class="alert alert-warning">
<div class="alert alert-success">
No projects here yet. Time to <b>Join</b> or <b>Start</b> something awesome!
</div>
{% endif %}

View File

@ -24,6 +24,7 @@ from dribdat.database import (
reference_col,
)
from dribdat.extensions import hashing
from dribdat.apifetch import FetchGitlabAvatar
from flask import current_app
from flask_login import UserMixin
from time import mktime
@ -31,7 +32,7 @@ from dateutil.parser import parse
import datetime as dt
import hashlib
import re
from urllib.parse import urlencode
from urllib.parse import urlencode, urlparse
# Standard library fix
from future.standard_library import install_aliases
install_aliases() # noqa: I005
@ -136,23 +137,34 @@ class User(UserMixin, PkModel):
def socialize(self):
"""Parse the user's web profile."""
self.cardtype = ""
self.carddata = ""
if self.webpage_url is None:
self.webpage_url = ""
elif 'github.com/' in self.webpage_url:
host = urlparse(self.webpage_url).hostname
print(host)
if host == 'github.com':
self.cardtype = 'github'
# self.carddata = self.webpage_url.strip('/').split('/')[-1]
elif 'twitter.com/' in self.webpage_url:
username = self.webpage_url.strip('/').split('/')[-1]
self.carddata = "https://github.com/%s.png?size=80" % username
elif host == 'gitlab.com':
self.cardtype = 'gitlab'
self.carddata = FetchGitlabAvatar(self.email)
elif host == 'twitter.com':
self.cardtype = 'twitter-square'
# self.carddata = self.webpage_url.strip('/').split('/')[-1]
elif 'linkedin.com/' in self.webpage_url:
# username = self.webpage_url.strip('/').split('/')[-1]
# self.carddata = FetchTwitterAvatar(username)
elif host == 'linkedin.com':
self.cardtype = 'linkedin-square'
elif 'stackoverflow.com/' in self.webpage_url:
elif host and host.endswith('stackoverflow.com'):
self.cardtype = 'stack-overflow'
gr_size = 80
email = self.email.lower().encode('utf-8')
gravatar_url = hashlib.md5(email).hexdigest() + "?"
gravatar_url += urlencode({'s': str(gr_size)})
self.carddata = gravatar_url
if not self.carddata:
# Default: generate a Gravatar link
gr_size = 80
email = self.email.lower().encode('utf-8')
gravatar_url = "https://www.gravatar.com/avatar/"
gravatar_url += hashlib.md5(email).hexdigest() + "?"
gravatar_url += urlencode({'s': str(gr_size)})
self.carddata = gravatar_url
self.save()
def joined_projects(self, with_challenges=True, limit=-1):

View File

@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Management functions for dribdat."""
import os
import click
from flask.cli import FlaskGroup
from dribdat.app import init_app
@ -14,7 +13,7 @@ TEST_PATH = os.path.join(HERE, 'tests')
def shell_context():
"""Return context dict for a shell session"""
"""Return context dict for a shell session."""
from dribdat.user.models import User, Event, Project, Category, Activity
return {
'User': User, 'Event': Event, 'Project': Project,
@ -23,7 +22,7 @@ def shell_context():
def create_app(script_info=None):
"""Initialise the app object"""
"""Initialise the app object."""
if os.environ.get("DRIBDAT_ENV") == 'prod':
app = init_app(ProdConfig)
else:
@ -33,10 +32,11 @@ def create_app(script_info=None):
@click.command()
@click.option('--name', default=None, help='Which test set to run (features, functional, ..)')
@click.argument('name', nargs=-1, required=False)
def test(name):
"""Run all or just a subset of tests."""
if name:
"""Parameter: which test set to run (features, functional, ..)"""
if len(name):
feat_test = os.path.join(TEST_PATH, "test_%s.py" % name)
else:
feat_test = TEST_PATH
@ -44,12 +44,23 @@ def test(name):
return subprocess.call(['pytest', feat_test])
@click.command()
def socialize():
"""Reset user profile data."""
with create_app().app_context():
from dribdat.user.models import User
q = [u.socialize() for u in User.query.all()]
print("Updated %d users." % len(q))
@click.group(cls=FlaskGroup, create_app=create_app)
def cli():
"""This is a management script for this application."""
"""Script for managing this application."""
pass
cli.add_command(test)
cli.add_command(socialize)
if __name__ == '__main__':
cli()