Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Team images #3750

Merged
merged 20 commits into from
Sep 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gratipay/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from gratipay.security import authentication, csrf, security_headers
from gratipay.utils import erase_cookie, http_caching, i18n, set_cookie, timer
from gratipay.version import get_version
from gratipay.renderers import csv_dump, jinja2_htmlescaped
from gratipay.renderers import csv_dump, jinja2_htmlescaped, eval_

import aspen
from aspen.website import Website
Expand All @@ -25,9 +25,11 @@
website.renderer_default = 'unspecified' # require explicit renderer, to avoid escaping bugs

website.renderer_factories['csv_dump'] = csv_dump.Factory(website)
website.renderer_factories['eval'] = eval_.Factory(website)
website.renderer_factories['jinja2_htmlescaped'] = jinja2_htmlescaped.Factory(website)
website.default_renderers_by_media_type['text/html'] = 'jinja2_htmlescaped'
website.default_renderers_by_media_type['text/plain'] = 'jinja2' # unescaped is fine here
website.default_renderers_by_media_type['image/*'] = 'eval'

website.renderer_factories['jinja2'].Renderer.global_context = {
# This is shared via class inheritance with jinja2_htmlescaped.
Expand Down
72 changes: 59 additions & 13 deletions gratipay/models/team.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
"""Teams on Gratipay receive payments and distribute payroll.
"""
import requests
from postgres.orm import Model
from aspen import json, log

status_icons = { "unreviewed": "✋"
, "rejected": "❌"
, "approved": "✅"
}
from gratipay.models import add_event
from postgres.orm import Model


class Team(Model):
Expand Down Expand Up @@ -79,13 +75,19 @@ def create_github_review_issue(self):
, "body": "https://gratipay.com/{}/\n\n".format(self.slug) +
"(This application will remain open for at least a week.)"
})
r = requests.post(api_url, auth=self.review_auth, data=data)
if r.status_code == 201:
out = r.json()['html_url']
else:
log(r.status_code)
log(r.text)
out = "https://github.com/gratipay/team-review/issues#error-{}".format(r.status_code)
out = ''
try:
r = requests.post(api_url, auth=self.review_auth, data=data)
if r.status_code == 201:
out = r.json()['html_url']
else:
log(r.status_code)
log(r.text)
err = str(r.status_code)
except:
err = "eep"
if not out:
out = "https://github.com/gratipay/team-review/issues#error-{}".format(err)
return out


Expand Down Expand Up @@ -178,4 +180,48 @@ def migrate_tips(self):
) SELECT count(*) FROM rows;
""", {'slug': self.slug, 'owner': self.owner})


# Images
# ======

IMAGE_SIZES = ('original', 'large', 'small')

def get_image_url(self, size):
assert size in ('original', 'large', 'small'), size
return '/{}/image?size={}'.format(self.slug, size)

def save_image(self, original, large, small, image_type):
with self.db.get_cursor() as c:
oids = {}
for size in self.IMAGE_SIZES:
lobject = c.connection.lobject(getattr(self, 'image_oid_'+size), mode='wb')
lobject.write(locals()[size])
oids[size] = lobject.oid
lobject.close()

c.run("""UPDATE teams
SET image_oid_original=%s, image_oid_large=%s, image_oid_small=%s
, image_type=%s
WHERE id=%s"""
, (oids['original'], oids['large'], oids['small'], image_type, self.id)
)
add_event(c, 'team', dict( action='upsert_image'
, id=self.id
, **oids
))
self.set_attributes( image_type=image_type
, **{'image_oid_'+size: oids[size] for size in oids}
)
return oids

def load_image(self, size):
assert size in self.IMAGE_SIZES, size
image = None
oid = getattr(self, 'image_oid_{}'.format(size))
if oid != 0:
with self.db.get_connection() as c:
image = c.lobject(oid, mode='rb').read()
return image


class AlreadyMigrated(Exception): pass
11 changes: 11 additions & 0 deletions gratipay/renderers/eval_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from __future__ import absolute_import, division, print_function, unicode_literals

from aspen import renderers


class Renderer(renderers.Renderer):
def render_content(self, context):
return eval(self.compiled, globals(), context)

class Factory(renderers.Factory):
Renderer = Renderer
5 changes: 4 additions & 1 deletion js/gratipay/new_team.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ Gratipay.new_team.submitForm = function (e) {

$input = $(this)
$form = $(this).parent('form');
var data = $form.serializeArray();
var data = new FormData($form[0]);

$input.prop('disable', true);

$.ajax({
url: $form.attr('action'),
type: 'POST',
data: data,
processData: false,
contentType: false,
dataType: 'json',
success: function (d) {
$('a.team_url').attr('href', d.team_url).text(d.team_url);
$('a.review_url').attr('href', d.review_url).text(d.review_url);
$('form').slideUp(500, function() {
$('.application-complete').slideDown(250);
Expand Down
29 changes: 20 additions & 9 deletions scss/pages/homepage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
width: 288px;
font: normal 14px/18px $Ideal;
padding: 24px;
background: white;
background: $white;
border: 2px solid $black;
@include border-radius(5px);
box-shadow: 0px 0px 32px 16px rgba($black, 0.5);
Expand Down Expand Up @@ -53,34 +53,45 @@
background: none !important;
color: $green !important;
}
img {
width: 48px;
height: 48px;
position: absolute;
top: 8px;
left: 0;
}
.name {
display: block;
color: $black;
font: bold 18px/22px $Ideal;
font: bold 20px/24px $Ideal;
position: absolute;
z-index: 1;
top: 0;
left: 0;
padding: 8px 0 0;
left: 56px;
padding: 12px 0 0;
width: 100%;
height: 100%;
}
.details {
font: normal 12px/15px $Ideal;
min-height: 48px;
padding: 30px 64px 0 0;
left: 0;
min-height: 64px;
padding: 38px 144px 0 56px;
.owner a {
color: $medium-gray;
position: relative;
z-index: 2;
}
span {
white-space: nowrap;
}
.status-icon {
width: 14px;
font-size: 12px;
padding: 0;
}
}
.numbers {
position: absolute;
bottom: 3px;
bottom: 8px;
right: 0;
z-index: 0;
font-size: 11px;
Expand Down
7 changes: 7 additions & 0 deletions sql/branch.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
BEGIN;
CREATE TYPE supported_image_types AS ENUM ('image/png', 'image/jpeg');
ALTER TABLE teams ADD COLUMN image_oid_original oid NOT NULL DEFAULT 0;
ALTER TABLE teams ADD COLUMN image_oid_large oid NOT NULL DEFAULT 0;
ALTER TABLE teams ADD COLUMN image_oid_small oid NOT NULL DEFAULT 0;
ALTER TABLE teams ADD COLUMN image_type supported_image_types;
END;
Loading