def list(exts, page, pages, name, exts_count, files_count, total_size): def _page(p): name = ('pages/' + str(p) if p > 1 else 'index') + '.html' link = L.a(href='/' + name) / (' %d ' % p) if p == page: return L.strong / link return link return _base(( L.div(style="text-align: center") / ( L.strong / _add_commas(exts_count), ' extensions, ', L.strong / _add_commas(files_count), ' versions, ', L.strong / _sizeof_fmt(total_size), ' stored', L.br, 'Last update: ' + datetime.datetime.now().strftime('%Y-%m-%d'), ), L.div(style="text-align: center") / ('Pages:', *(_page(p) for p in range(1, pages)), '(ordered by # of users)'), L.hr, *(_simple_ext(ext) for ext in exts), ))
def homepage(request): deputes = Depute.objects.filter(actif=True).order_by( Lower('nom'), 'prenom') return HttpResponse( template([ raw(""" <div class="alert alert-dismissible alert-info"> <p>Ce site permet de retrouver facilement les votes de vos députés</p> <p>Vous pouvez trouver votre député par circonscription sur <a href="https://www.nosdeputes.fr/circonscription" class="alert-link">NosDéputés.fr</a></p> </div> """), L.p / L.a(href="/deputes/inactifs") / L.button(".btn.btn-warning") / "voir députés inactifs", L.h2 / ["Députés ", L.small(".text-muted") / " actifs"], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=dep.url()) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / f"{dep.nom}, {dep.prenom}", L.small / f"{dep.groupe}" ] ] for dep in deputes ], ]))
def list(exts, page, pages, name, exts_count, files_count, total_size): def _page(p): name = ('pages/' + str(p) if p > 1 else 'index') + '.html' link = L.a(href='/' + name) / (' %d ' % p) if p == page: return L.strong / link return link return _base(( L.div(style="text-align: center") / ( L.strong / _add_commas(exts_count), ' extensions, ', L.strong / _add_commas(files_count), ' versions, ', L.strong / _sizeof_fmt(total_size), ' stored', L.br, 'Last update: ' + datetime.datetime.now().strftime('%Y-%m-%d'), ), L.div(style="text-align: center") / ( 'Pages:', *(_page(p) for p in range(1, pages)), '(ordered by # of users)' ), L.hr, *(_ext(ext) for ext in exts), ))
def depute(request, dep_id): dep = Depute.objects.get(identifiant=dep_id) dossiers = Dossier.objects.filter( date_promulgation__isnull=False).order_by("-date_promulgation", "titre") return HttpResponse( template([ _render_breadcrumb([dep]), L.p / ( L.a(href=dep.url() + "/lois-en-cours") / L.button(".btn.btn-warning") / "voir lois en cours", ' ', L.a(href=dep.url() + "/autres-votes") / L.button(".btn.btn-warning") / "voir autres votes", ), L.h2 / ["Lois", L.small(".text-muted") / " promulguées"], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=dos.url(dep)) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / dos.titre, _display_depute_vote(dos, dep), ] ] for dos in dossiers ] ]))
def top_pour_lois(request): results = [] for dossier in Dossier.objects.filter(date_promulgation__isnull=False): c = 0 c = Vote.objects.filter(scrutin_dossier=None, scrutin__etape__dossier=dossier, position='pour').count() c2 = Vote.objects.filter(scrutin_dossier=None, scrutin__etape__dossier=dossier).count() if c2: results.append([dossier, c / c2, c]) else: results.append([dossier, 0, 0]) results.sort(key=lambda r: (-r[1], -r[2])) lines = [] for i, r in enumerate(results): dossier, c, c2 = r lines.append( L.span( ".list-group-item.list-group-item-action.flex-column.align-items-start" ) / f"{i+1}: {dossier} avec {round(c*100, 2)}% de votes pour ({c2} votes)" ) return HttpResponse( template([ L.h2 / "Top des lois promulguées par le pourcentage de votes pour", L.div(".list-group") / lines, ]))
def top_contre_pourcentage(request): results = [] for dep in Depute.objects.all(): c = Vote.objects.filter(scrutin_dossier=None, scrutin__article__isnull=True, depute=dep, position='contre').count() c2 = Vote.objects.filter(scrutin_dossier=None, scrutin__article__isnull=True, depute=dep).count() if c2: results.append([dep, c / c2, c]) else: results.append([dep, 0, 0]) results.sort(key=lambda r: (-r[1], -r[2])) lines = [] for i, r in enumerate(results): dep, c, c2 = r lines.append( L.span( ".list-group-item.list-group-item-action.flex-column.align-items-start" ) / f"{i+1}: {dep} ({dep.groupe}) avec {round(c*100, 2)}% de votes contre ({c2} votes)" ) return HttpResponse( template([ L.h2 / "Top des députés qui ont votés contre les lois promulguées", L.div(".list-group") / lines, ]))
def test_escaping(self): self.assertEqual(str(L.div(id='hello & ; " \'')), '<div id="hello & ; " '"></div>') self.assertEqual( str(L.h1 / '<script>alert("h4x0r")</script>'), '<h1><script>alert("h4x0r")</script></h1>') self.assertEqual( str(L.button(onclick=raw('alert(\'follow the rabbit\')'))), '<button onclick="alert(\'follow the rabbit\')"></button>')
def deputes_inactifs(request): deputes_inactifs = Depute.objects.filter(actif=False).order_by( Lower('nom'), 'prenom') return HttpResponse( template([ L.h2 / ["Députés ", L.small(".text-muted") / " inactifs"], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=dep.url()) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / f"{dep.nom}, {dep.prenom}", L.small / f"{dep.groupe}" ] ] for dep in deputes_inactifs ] ]))
def lois_en_cours(request, dep_id): dep = Depute.objects.get(identifiant=dep_id) dossiers = Dossier.objects.filter(date_promulgation__isnull=True) return HttpResponse( template([ _render_breadcrumb([dep, 'Lois en cours']), L.h2 / ["Lois", L.small(".text-muted") / " en cours d'étude"], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=dos.url(dep)) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / dos.titre, _display_depute_vote(dos, dep), ] ] for dos in dossiers ] ]))
def autres_votes(request, dep_id): dep = Depute.objects.get(identifiant=dep_id) scrutins = Scrutin.objects.filter(dossier__isnull=True, etape__isnull=True) return HttpResponse( template([ _render_breadcrumb([dep, 'Autres votes']), L.h2 / [ "Autres votes", ], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=dep.url() + '/scrutin/' + str(scrutin.id)) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / scrutin.objet, _display_scrutin_vote(dep, scrutin), ] ] for scrutin in scrutins ] ]))
def depute_dossier(request, dep_id, dos_id): dep = Depute.objects.get(identifiant=dep_id) dos = Dossier.objects.get(identifiant=dos_id) etapes = Etape.objects.filter(dossier=dos).order_by("-date") return HttpResponse( template([ _render_breadcrumb([dep, dos]), L.p / L.a(href=dos.url_an()) / L.button(".btn.btn-info") / "dossier législatif", L.h2 / [ "Étapes", ], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href=etape.url(dep)) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / etape.titre, _display_etape_vote(etape, dep), ] ] for etape in etapes ] ]))
def _base(content='', title_prefix=''): return str(L.html / ( L.head / ( L.meta(charset="utf-8"), L.meta(content="width=device-width, initial-scale=1", name="viewport"), L.title / (title_prefix + "Chrome Extensions Archive"), L.link(href="/style.css", media="screen", rel="stylesheet", type="text/css"), ), L.body() / ( L.a(href='/') / (L.h1 / "Chrome Extensions Archive"), L.div(style='text-align: right') / ( L.a(href="https://github.com/mdamien/chrome-extensions-archive") / "github.com/mdamien/chrome-extensions-archive" ), L.hr, content, ), ))
def _base(content, title_prefix=''): return str(L.html / ( L.head / ( L.meta(charset="utf-8"), L.meta(content="width=device-width, initial-scale=1", name="viewport"), L.title / (title_prefix + "Chrome Extensions Archive"), L.link(href="/style.css", media="screen", rel="stylesheet", type="text/css"), ), L.body() / ( L.a(href='/') / (L.h1 / "Chrome Extensions Archive"), L.div(style='text-align: right') / ( L.a(href="https://github.com/mdamien/chrome-extensions-archive") / "github.com/mdamien/chrome-extensions-archive" ), L.hr, content, ), ))
def top_pour(request): results = [] for dep in Depute.objects.all(): c = Vote.objects.filter(scrutin_dossier=None, scrutin__article__isnull=True, depute=dep, position='pour').count() results.append([dep, c]) results.sort(key=lambda r: -r[1]) lines = [] for i, r in enumerate(results): dep, c = r lines.append( L.span( ".list-group-item.list-group-item-action.flex-column.align-items-start" ) / f"{i+1}: {dep} ({dep.groupe}) avec {c} votes pour") return HttpResponse( template([ L.h2 / "Top des députés qui ont votés pour les lois promulguées", L.div(".list-group") / lines, ]))
def index(request): email = None message = None if 'token' in request.GET: try: token = LoginToken.objects.get(email=request.GET['email'], token=request.GET['token']) email = token.email except LoginToken.DoesNotExist: pass if email: # logged in account = Account.objects.get(email=email) if request.method == 'POST': # todo: atomize / transaction # todo: validate email dest_email = request.POST['email'] dest_amount = -1 message = 'invalid amount' try: dest_amount = int(request.POST['amount']) except ValueError: pass optional_message = '' if request.POST['message']: optional_message = '\nHis message: \n' + slugify(request.POST['message'][:140], allow_unicode=True) if account.amount >= dest_amount and dest_amount > 0: # TODO: else "not enough founds" try: dest_account = Account.objects.get(email=dest_email) dest_account.amount += dest_amount dest_account.save() except Account.DoesNotExist: dest_account = Account.objects.create(email=dest_email, amount=dest_amount) token = get_random_string() LoginToken.objects.create(email=dest_email, token=token, expire_on=datetime.date.today() + datetime.timedelta(days=1)) send_mail('[petals] %s sent you %d petals' % (email, dest_amount), """%s sent you %d petals.%s You current balance is now: %d petals http://petal.x.dam.io/?token=%s&email=%s """ % (email, dest_amount, optional_message, dest_account.amount, token, dest_email), '*****@*****.**', [dest_email], fail_silently=False) account.amount -= dest_amount account.save() message = '%d sent' % dest_amount else: if request.method == 'POST': email = request.POST['email'] try: account = Account.objects.get(email=email) token = get_random_string() LoginToken.objects.create(email=email, token=token, expire_on=datetime.date.today() + datetime.timedelta(days=1)) send_mail('[petals] link to connect to your account', """Here is a temporary link to connect to your account: http://petal.x.dam.io/?token=%s&email=%s """ % (token, email), '*****@*****.**', [email], fail_silently=False) message = 'connection link sent to %s' % email except Account.DoesNotExist: pass email = None # lol total = sum([account.amount for account in Account.objects.all()]) content = L.div('.container') / ( L.div('.row') / ( L.div('.col-sm-12') / ( L.h3 / (L.a(href='/') / 'Petal'), L.strong / ('%d petals in circulation' % total), L.hr, ), ), ( L.div('.row') / ( L.div('.col-sm-3') / ( L.h3 / email, L.p / ('You have %d petals' % account.amount), L.h4 / 'send petals', L.form(method='post') / ( L.input(type='hidden', name='csrfmiddlewaretoken', value=get_token(request)), L.div / ( L.label('control-label') / 'email', L.br, L.input(name='email'), ), L.div / ( L.label('control-label') / 'amount', L.br, L.input(name='amount', type='number'), ), L.div / ( L.label('control-label') / 'message (optional)', L.br, L.input(name='message', max_length="140"), ), L.br, L.button(type='submit') / 'send petals', ), L.i / message, ), ) ) if email else ( L.div('.row') / ( L.div('.col-sm-3') / ( L.h3 / 'see your account', L.p / 'You will receive an email with a link to login to your account', L.form(method='post') / ( L.input(type='hidden', name='csrfmiddlewaretoken', value=get_token(request)), L.div / ( L.label('control-label') / 'email', L.br, L.input(name='email'), ), L.br, L.button(type='submit') / 'send email with login link' ), L.i / message, ), ) ) ) return HttpResponse(tpl_base(content))
def depute_etape(request, dep_id, etape_id): dep = Depute.objects.get(identifiant=dep_id) etape = Etape.objects.get(identifiant=etape_id) dos = etape.dossier try: scrutin = etape.scrutin_set.filter(dossier__isnull=True, article__isnull=True).first() except: scrutin = None articles = etape.scrutin_set.values_list( 'article', flat=True).order_by('article').distinct() articles = [a for a in articles if a] articles.sort(key=_sort_articles) scrutins_amendements = etape.scrutin_set.filter(dossier=dos, etape=etape) return HttpResponse( template([ _render_breadcrumb([dep, dos, etape]), (L.span('.badge.badge-info') / ( 'Le ', scrutin.date, (' ', scrutin.heure) if scrutin.heure else None, ), ) if scrutin else None, L.p / (( ' ', L.a(href=scrutin.url_an) / L.button(".btn.btn-info") / f'Scrutin', ( ' ', L.a(href=scrutin.url_video) / L.button(".btn.btn-info") / "video du vote", ) if scrutin.url_video else None, ( ' ', L.a(href=scrutin.url_CR) / L.button(".btn.btn-info") / "compte-rendu", ) if scrutin.url_CR else None, ) if scrutin else None), (L.h2 / ["Articles", L.small(".text-muted") / " votés"], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href="/" + dep.identifiant + "/etape/" + etape.identifiant + "/article/" + article) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / f"Article {article}", _display_article_vote(etape, dep, article), ] ] for article in articles ]) if articles else None, (L.br, L.br, L.h2 / [ "Amendements et motions", L.small(".text-muted") / " votés" ], L.div(".list-group") / [ L. a(".list-group-item.list-group-item-action.flex-column.align-items-start", href="/" + dep.identifiant + "/scrutin/" + str(amdt_scrutin.id)) / [ L.div(".d-flex.w-100.justify-content-between") / [ L.h5(".mb-1") / f"{amdt_scrutin.objet}", _display_scrutin_vote(dep, amdt_scrutin), ] ] for amdt_scrutin in scrutins_amendements ]) if scrutins_amendements.count() else None, ]))