mirror of https://codeberg.org/dribdat/dribdat.git
GitHub/GitLab avatar support
This commit is contained in:
parent
16c898e4ea
commit
4327d81b08
1
Procfile
1
Procfile
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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):
|
||||
|
|
25
manage.py
25
manage.py
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue