Skip to content

Commit

Permalink
Merge branch 'main' into whatsapp-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
djamg committed Nov 9, 2023
2 parents 247e54f + d9ef187 commit 689dc0a
Show file tree
Hide file tree
Showing 35 changed files with 445 additions and 382 deletions.
27 changes: 24 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ci:
skip: [
'pip-audit',
'yesqa',
'creosote',
'no-commit-to-branch',
# 'hadolint-docker',
'docker-compose-check',
Expand Down Expand Up @@ -52,9 +53,9 @@ repos:
rev: v3.15.0
hooks:
- id: pyupgrade
args: ['--keep-runtime-typing', '--py310-plus']
args: ['--keep-runtime-typing', '--py311-plus']
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.1
rev: v0.1.4
hooks:
- id: ruff
args: ['--fix', '--exit-non-zero-on-fix']
Expand Down Expand Up @@ -100,7 +101,7 @@ repos:
additional_dependencies:
- tomli
- repo: https://github.com/psf/black
rev: 23.10.0
rev: 23.10.1
hooks:
- id: black
# Mypy is temporarily disabled until the SQLAlchemy 2.0 migration is complete
Expand Down Expand Up @@ -148,6 +149,26 @@ repos:
args: ['-c', 'pyproject.toml']
additional_dependencies:
- 'bandit[toml]'
- repo: https://github.com/fredrikaverpil/creosote
rev: v3.0.0
hooks:
- id: creosote
args:
- --venv=.venv
- --path=funnel
- --path=tests
- --path=migrations/versions
- --deps-file=requirements/base.in
- --exclude-dep=argon2-cffi # Optional dep for passlib
- --exclude-dep=bcrypt # Optional dep for passlib
- --exclude-dep=gunicorn # Not imported, used as server
- --exclude-dep=linkify-it-py # Optional dep for markdown-it-py
- --exclude-dep=psycopg # Optional dep for SQLAlchemy
- --exclude-dep=rq-dashboard # Creosote fails to recognise the import
- --exclude-dep=tzdata # Data-only dep, therefore no import statement
- --exclude-dep=urllib3 # Required to silence a pip-audit warning
- --exclude-dep=wtforms-sqlalchemy # Temp dep on an unreleased git branch

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
Expand Down
3 changes: 1 addition & 2 deletions funnel/devtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
import weakref
from collections.abc import Callable, Iterable
from secrets import token_urlsafe
from typing import Any, NamedTuple
from typing_extensions import Protocol
from typing import Any, NamedTuple, Protocol

from flask import Flask

Expand Down
4 changes: 3 additions & 1 deletion funnel/forms/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ class ProfileTransitionForm(forms.Form):

def set_queries(self) -> None:
"""Prepare form for use."""
self.transition.choices = list(self.edit_obj.state.transitions().items())
self.transition.choices = list(
self.edit_obj.profile_state.transitions().items()
)


@Account.forms('logo')
Expand Down
3 changes: 2 additions & 1 deletion funnel/models/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,19 @@
ClassVar,
Generic,
Optional,
Protocol,
TypeVar,
Union,
cast,
get_args,
get_origin,
)
from typing_extensions import Protocol, get_original_bases
from uuid import UUID, uuid4

from sqlalchemy import event
from sqlalchemy.orm import column_keyed_dict
from sqlalchemy.orm.exc import NoResultFound
from typing_extensions import get_original_bases
from werkzeug.utils import cached_property

from baseframe import __
Expand Down
4 changes: 2 additions & 2 deletions funnel/models/notification_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class RegistrationReceivedNotification(


class OrganizationAdminMembershipNotification(
DocumentHasAccount,
DocumentIsAccount,
Notification[Account, AccountMembership],
type='organization_membership_granted',
):
Expand All @@ -263,7 +263,7 @@ class OrganizationAdminMembershipNotification(


class OrganizationAdminMembershipRevokedNotification(
DocumentHasAccount,
DocumentIsAccount,
Notification[Account, AccountMembership],
type='organization_membership_revoked',
shadows=OrganizationAdminMembershipNotification,
Expand Down
15 changes: 15 additions & 0 deletions funnel/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class Project(UuidMixin, BaseScopedNameMixin, Model):
None: {
'admin': 'account_admin',
'follower': 'account_participant',
'member': 'account_member',
}
},
# `account` only appears in the 'primary' dataset. It must not be included in
Expand Down Expand Up @@ -191,6 +192,12 @@ class Project(UuidMixin, BaseScopedNameMixin, Model):
read={'all'},
datasets={'primary', 'without_parent', 'related'},
)

#: Auto-generated preview image for Open Graph
preview_image: Mapped[bytes | None] = sa.orm.mapped_column(
sa.LargeBinary, nullable=True, deferred=True
)

allow_rsvp: Mapped[bool] = with_roles(
sa.orm.mapped_column(sa.Boolean, default=True, nullable=False),
read={'all'},
Expand Down Expand Up @@ -840,6 +847,14 @@ def published_project_count(self) -> int:
self.listed_projects.filter(Project.state.PUBLISHED).order_by(None).count()
)

@with_roles(grants_via={None: {'participant': 'member'}})
@cached_property
def membership_project(self) -> Project | None:
"""Return a project that has memberships flag enabled (temporary)."""
return self.projects.filter(
Project.boxoffice_data.op('@>')({'has_membership': True})
).first()


class ProjectRedirect(TimestampMixin, Model):
__tablename__ = 'project_redirect'
Expand Down
3 changes: 3 additions & 0 deletions funnel/models/sync_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ class TicketEvent(GetTitleMixin, Model):
'read': {'name', 'title'},
'write': {'name', 'title'},
},
'project_usher': {
'read': {'name', 'title'},
},
}


Expand Down
3 changes: 1 addition & 2 deletions funnel/models/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
Mapped,
Model,
Query,
TimestampMixin,
TSVectorType,
UuidMixin,
backref,
Expand Down Expand Up @@ -47,7 +46,7 @@ class VISIBILITY_STATE(LabeledEnum): # noqa: N801
RESTRICTED = (2, 'restricted', __("Restricted"))


class Update(UuidMixin, BaseScopedIdNameMixin, TimestampMixin, Model):
class Update(UuidMixin, BaseScopedIdNameMixin, Model):
__tablename__ = 'update'

_visibility_state = sa.orm.mapped_column(
Expand Down
2 changes: 1 addition & 1 deletion funnel/templates/account_menu.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</li>
{%- for orgmem in orgmemlist.recent %}
<li>
<a href="{{ orgmem.account.profile_url }}"
<a href="{{ orgmem.account.url_for() }}"
class="header__dropdown__item header__dropdown__item--flex header__dropdown__item--morepadding mui--text-dark nounderline">
<span class="profile-avatar margin-right">
{%- if orgmem.account.logo_url.url %}
Expand Down
2 changes: 1 addition & 1 deletion funnel/templates/macros.html.jinja2
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{%- set img_size = namespace() %}
{%- set img_size.profile_banner = 1200 %}
{%- set img_size.spotlight_banner = 700 %}
{%- set img_size.spotlight_banner = 1200 %}
{%- set img_size.card_banner = 400 %}
{%- set img_size.card_banner_small = 100 %}
{%- set img_size.profile_logo = 240 %}
Expand Down
30 changes: 15 additions & 15 deletions funnel/templates/profile.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
{{ featured_section(featured_project) }}
{{ upcoming_section(upcoming_projects) }}

{% if has_membership_project %}
{% if membership_project %}
<div class="projects-wrapper">
<div class="mui-container">
<div class="grid">
Expand All @@ -158,10 +158,10 @@
<div class="mui-container membership-container">
<div class="grid">
<div class="grid__col-md-7 grid__col-lg-8 mui--hidden-xs mui--hidden-sm mui--hidden-md">
{% if has_membership_project.bg_image.url %}
<img class="img-responsive img-rounded-border js-lazyload-img" data-src="{{ has_membership_project.bg_image.resize(img_size.profile_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
{% if membership_project.bg_image.url %}
<img class="img-responsive img-rounded-border js-lazyload-img" data-src="{{ membership_project.bg_image.resize(img_size.profile_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
<noscript>
<img class="img-responsive img-rounded-border" src="{{ has_membership_project.bg_image.resize(img_size.profile_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
<img class="img-responsive img-rounded-border" src="{{ membership_project.bg_image.resize(img_size.profile_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
</noscript>
{% else %}
<img class="img-responsive img-rounded-border" src="{{ url_for('static', filename='img/default-banner.png') }}" alt="{% trans %}Membership{% endtrans %}"/>
Expand All @@ -170,23 +170,23 @@
<div class="grid__col-12 grid__col-md-5 grid__col-lg-4">
<div class="card card--shaped mui--hidden-lg mui--hidden-xl">
<div class="card__image-wrapper">
{% if has_membership_project.bg_image.url %}
<img class="card__image js-lazyload-img" data-src="{{ has_membership_project.bg_image.resize(img_size.spotlight_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
{% if membership_project.bg_image.url %}
<img class="card__image js-lazyload-img" data-src="{{ membership_project.bg_image.resize(img_size.spotlight_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
<noscript>
<img class="card__image" src="{{ has_membership_project.bg_image.resize(img_size.spotlight_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
<img class="card__image" src="{{ membership_project.bg_image.resize(img_size.spotlight_banner) }}" alt="{% trans %}Membership{% endtrans %}"/>
</noscript>
{% else %}
<img class="card__image" src="{{ url_for('static', filename='img/default-banner.png') }}" alt="{% trans %}Membership{% endtrans %}"/>
{% endif %}
</div>
<div class="card__body">
<div class="markdown">{{ has_membership_project.description }}</div>
<div class="markdown">{{ membership_project.description }}</div>
</div>
</div>
<div class="markdown membership-container__content mui--hidden-xs mui--hidden-sm mui--hidden-md">{{ has_membership_project.description }}</div>
{% if has_membership_project.current_roles.ticket_participant %}
<div class="markdown membership-container__content mui--hidden-xs mui--hidden-sm mui--hidden-md">{{ membership_project.description }}</div>
{% if profile.current_roles.member %}
<div class="membership-container__btn-wrapper"><button class="mui-btn mui-btn--accent mui-btn--small zero-bottom-margin zero-top-margin mui--is-disabled display-block">{% trans %}You are a member{% endtrans %}</button></div>
{% elif has_membership_project.features.show_tickets %}
{% elif membership_project.features.show_tickets %}
<div class="membership-container__btn-wrapper">
<button class="js-open-ticket-widget mui-btn mui-btn--primary price-btn zero-bottom-margin zero-top-margin display-block">
<span class="price-btn__txt" data-cy="unregistered">{% trans %}Become a member{% endtrans %}</span>
Expand Down Expand Up @@ -269,13 +269,13 @@
<script type="text/javascript">
$(function() {
var tickets;
{% if has_membership_project and has_membership_project.features.show_tickets -%}
{% if membership_project and membership_project.features.show_tickets -%}
tickets = {
boxofficeUrl: {{ config['BOXOFFICE_SERVER']|tojson }},
widgetElem: "#boxoffice-widget",
org: {{ has_membership_project.boxoffice_data.org|tojson }},
itemCollectionId: {{ has_membership_project.boxoffice_data.item_collection_id|tojson }},
itemCollectionTitle: {{ has_membership_project.title|tojson }}
org: {{ membership_project.boxoffice_data.org|tojson }},
itemCollectionId: {{ membership_project.boxoffice_data.item_collection_id|tojson }},
itemCollectionTitle: {{ membership_project.title|tojson }}
};
{%- endif %}
window.Hasgeek.homeInit('.markdown', tickets);
Expand Down
8 changes: 4 additions & 4 deletions funnel/templates/profile_layout.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,10 @@
{% if profile.is_organization_profile %}
<a class="sub-navbar__item mui--text-subhead mui--text-dark mui--hidden-xs mui--hidden-sm {% if current_page == 'profile' %}sub-navbar__item--active{%- endif %}" href="{%- if current_page != 'profile' -%}{{ profile.url_for() }}{%- endif %}" data-cy-navbar="profile">{% trans %}Home{% endtrans %}</a>
<a class="sub-navbar__item mui--text-subhead mui--text-dark {% if current_page == 'admins' %}sub-navbar__item--active{%- endif %}" href="{%- if current_page != 'admins' -%}{{ profile.urls['members'] }}{%- endif %}" data-cy-navbar="admins">{% trans %}Admins{% endtrans %} <span class="sub-navbar__item__icon mui--pull-right">{{ faicon(icon='chevron-right', icon_size='subhead') }}</span></a>
{% else %}
<a class="sub-navbar__item mui--text-subhead mui--text-dark mui--hidden-xs mui--hidden-sm {% if current_page == 'profile' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for() }}">{% trans %}Sessions{% endtrans %}</a>
<a class="sub-navbar__item mui--text-subhead mui--text-dark {% if current_page == 'projects' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for('user_participated_projects') }}">{% trans %}Projects{% endtrans %}<span class="sub-navbar__item__icon mui--pull-right">{{ faicon(icon='chevron-right', icon_size='subhead') }}</span></a>
<a class="sub-navbar__item mui--text-subhead mui--text-dark {% if current_page == 'submissions' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for('user_proposals') }}" data-cy="submissions">{% trans %}Submissions{% endtrans %}<span class="sub-navbar__item__icon mui--pull-right">{{ faicon(icon='chevron-right', icon_size='subhead') }}</span></a>
{% elif not profile.features.is_private() %}
<a class="sub-navbar__item mui--text-subhead mui--text-dark mui--hidden-xs mui--hidden-sm {% if current_page == 'profile' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for() }}">{% trans %}Sessions{% endtrans %}</a>
<a class="sub-navbar__item mui--text-subhead mui--text-dark {% if current_page == 'projects' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for('user_participated_projects') }}">{% trans %}Projects{% endtrans %}<span class="sub-navbar__item__icon mui--pull-right">{{ faicon(icon='chevron-right', icon_size='subhead') }}</span></a>
<a class="sub-navbar__item mui--text-subhead mui--text-dark {% if current_page == 'submissions' %}sub-navbar__item--active{%- endif %}" href="{{ profile.url_for('user_proposals') }}" data-cy="submissions">{% trans %}Submissions{% endtrans %}<span class="sub-navbar__item__icon mui--pull-right">{{ faicon(icon='chevron-right', icon_size='subhead') }}</span></a>
{% endif %}
</nav>
</div>
Expand Down
4 changes: 2 additions & 2 deletions funnel/templates/project_layout.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<a class="register-block__btn full-width-btn mui-btn mui-btn--primary" href="{{ project.buy_tickets_url.url }}" data-action="external register url" target="_blank" rel="noopener"><span>{{ faicon(icon='arrow-up-right-from-square', baseline=true, css_class="mui--text-white fa-icon--right-margin") }}{{ project.views.register_button_text() }}</span></a>
{% endif %}
</div>
{% if project.current_roles.ticket_participant %}
{% if project.current_roles.account_member %}
<div class="register-block__content {% if project.features.rsvp() or project.buy_tickets_url.url %} register-block__content--half {%- endif %}"><button class="mui-btn mui-btn--accent register-block__btn mui--is-disabled">{% trans %}You are a member{% endtrans %}</button></div>
{% elif project.features.show_tickets %}
<div class="register-block__content {% if project.features.rsvp() or project.buy_tickets_url.url %} register-block__content--half {%- endif %}">
Expand Down Expand Up @@ -502,7 +502,7 @@
</div>
{% endif %}
<div class="project-footer {% if current_page == 'project' %}project-footer--main{%- endif %}">
{{ registerblock(project)}}
{{ registerblock(project) }}
</div>
<div class="mui--hidden-xs mui--hidden-sm">
{{ project_details(project) }}
Expand Down
26 changes: 15 additions & 11 deletions funnel/templates/user_profile.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,22 @@
<div class="mui-container">
<div class="page-content">
{% block contentwrapper %}
<div class="grid projects-wrapper" id="tagged-sessions">
<div class="grid__col-xs-12">
{% if not tagged_sessions %}
<p class="mui-panel bg-accent">{% trans %}No tagged sessions yet{% endtrans %}</p>
{% endif %}
</div>
{% for session in tagged_sessions %}
<div class="grid__col-xs-12 grid__col-sm-6 grid__col-sm-4">
{{ video_thumbnail(session) }}
{% if profile.features.is_private() %}
<p class="mui-panel bg-accent">{% trans %}This is a private account{% endtrans %}</p>
{% else %}
<div class="grid projects-wrapper" id="tagged-sessions">
<div class="grid__col-xs-12">
{% if not tagged_sessions %}
<p class="mui-panel bg-accent">{% trans %}No tagged sessions yet{% endtrans %}</p>
{% endif %}
</div>
{% endfor %}
</div>
{% for session in tagged_sessions %}
<div class="grid__col-xs-12 grid__col-sm-6 grid__col-sm-4">
{{ video_thumbnail(session) }}
</div>
{% endfor %}
</div>
{% endif %}
{% endblock contentwrapper %}
</div>
</div>
Expand Down
30 changes: 18 additions & 12 deletions funnel/templates/user_profile_projects.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@

{% block contentwrapper %}
<div class="grid projects-wrapper" id="tagged-projects">
<div class="grid__col-xs-12">
{% if not participated_projects %}
<p class="mui-panel bg-accent">{% trans %}No participation yet{% endtrans %}</p>
{% endif %}
</div>
<ul class="mui-list--unstyled grid upcoming" role="list">
{% for project in participated_projects %}
<li class="grid__col-xs-12 grid__col-sm-6 grid__col-lg-4" role="listitem">
{{ projectcard(project, include_calendar=true, calendarwidget_compact=false) }}
</li>
{%- endfor -%}
</ul>
{% if profile.features.is_private() %}
<div class="grid__col-xs-12">
<p class="mui-panel bg-accent">{% trans %}This is a private account{% endtrans %}</p>
</div>
{% else %}
<div class="grid__col-xs-12">
{% if not participated_projects %}
<p class="mui-panel bg-accent">{% trans %}No participation yet{% endtrans %}</p>
{% endif %}
</div>
<ul class="mui-list--unstyled grid upcoming" role="list">
{% for project in participated_projects %}
<li class="grid__col-xs-12 grid__col-sm-6 grid__col-lg-4" role="listitem">
{{ projectcard(project, include_calendar=true, calendarwidget_compact=false) }}
</li>
{%- endfor -%}
</ul>
{% endif %}
</div>
{% endblock contentwrapper %}

Expand Down
10 changes: 7 additions & 3 deletions funnel/templates/user_profile_proposals.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
{% block contentwrapper %}
<div class="grid projects-wrapper" id="tagged-submissions">
<div class="grid__col-xs-12">
{% if submitted_proposals %}
{{ proposal_list(submitted_proposals) }}
{% if profile.features.is_private() %}
<p class="mui-panel bg-accent">{% trans %}This is a private account{% endtrans %}</p>
{% else %}
<p class="mui-panel bg-accent">{% trans %}No submissions{% endtrans %}</p>
{% if submitted_proposals %}
{{ proposal_list(submitted_proposals) }}
{% else %}
<p class="mui-panel bg-accent">{% trans %}No submissions{% endtrans %}</p>
{% endif %}
{% endif %}
</div>
</div>
Expand Down
3 changes: 1 addition & 2 deletions funnel/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from __future__ import annotations

from typing import Optional, TypeAlias, TypeVar, Union
from typing_extensions import ParamSpec
from typing import Optional, ParamSpec, TypeAlias, TypeVar, Union

from flask.typing import ResponseReturnValue
from werkzeug.wrappers import Response # Base class for Flask Response
Expand Down
Loading

0 comments on commit 689dc0a

Please sign in to comment.