Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 39 additions & 0 deletions bin/check-content
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import pathlib
import re
import struct
import sys
import tomllib

import yaml

Expand Down Expand Up @@ -553,6 +554,43 @@ SECURITY_TXT = ROOT / "static" / ".well-known" / "security.txt"
SECURITY_TXT_NOTICE_DAYS = 30


CONFIG = ROOT / "config.toml"

# The keys of [params.association] that only the Management Board can fill,
# and what each one is for. See the comment in config.toml.
ASSOCIATION_KEYS = {
"address": "the registered address, which LSSI-CE article 10 requires the "
"legal notice to publish",
"registry": "the entry in the Registre d'Associacions de la Generalitat "
"de Catalunya, which LSSI-CE article 10 requires too",
}


def check_association():
"""The legal notice reads who the association is from config.toml.

Two of those facts are not a volunteer's to write: the registered address
and the entry in the register of associations. Should either be emptied,
this says so on every run rather than letting the legal notice go out
with a gap in the one section the law asks for.

A warning and not an error: the site builds and serves fine without them,
and an error would turn every pull request red for a reason no
contributor can fix. The page that needs them is the gate.
"""
try:
with open(CONFIG, "rb") as handle:
config = tomllib.load(handle)
except (OSError, tomllib.TOMLDecodeError) as problem:
error(CONFIG, f"cannot be read: {problem}")
return
association = (config.get("params") or {}).get("association") or {}
for key, what in sorted(ASSOCIATION_KEYS.items()):
if not str(association.get(key, "")).strip():
warn(CONFIG, f"params.association.{key} is empty. It is {what}. "
f"Only the Management Board can fill it.")


def check_security_txt():
"""Report a security.txt that has expired, or is about to.

Expand Down Expand Up @@ -596,6 +634,7 @@ def main():
check_agenda()
check_orphans(people, listed_people)
check_security_txt()
check_association()

for line in warnings:
print(f"WARNING {line}")
Expand Down
24 changes: 24 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ unsafe=true
short_name = "PyBCN"
extended_name = "The Barcelona Python Association"

# Who the association is in law. Spanish law 34/2002 (LSSI-CE) article 10
# requires a site run by an association to publish its name, its address,
# an email, its entry in the register it is recorded in, and its tax
# number. The legal notice page is what shows them, and reads them from
# here rather than holding them in its own text, so that the association
# can correct a fact without a volunteer editing a page of legal prose.
#
# The values match the association's entry in the Registre d'Entitats de
# la Generalitat de Catalunya, which is public open data:
# https://analisi.transparenciacatalunya.cat/d/y6fz-g3ff
# Only the Management Board changes address, registry or registered_on:
# they describe the association as the register records it, not as
# volunteers know it. The register names the register itself, not only
# the number, because article 10 asks for the entry in the register and a
# bare number names no register. bin/check-content reports an empty
# address or registry as a warning. The legal notice page cannot be
# published while either is empty: the page is the one place the law
# asks for them, and a page that leaves them out does not do its job.
[params.association]
legal_name = "Associació Python Barcelona"
tax_id = "G67254045"
address = "Carrer de Concepció Arenal, 165, 08027 Barcelona"
registry = "Registre d'Associacions de la Generalitat de Catalunya, núm. 64158"

main_contact_name_pyladies = "PyLadiesBCN Organizers"
main_contact_email_pyladies = "pyladies-bcn@googlegroups.com"

Expand Down
57 changes: 57 additions & 0 deletions content/pybcn_association/legal-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "Legal notice"
description: "Who runs pybcn.org, how to reach us, and the terms of use"
menu:
main:
parent: 'The association'
weight: 6
aliases:
- /legal-notice

layout: single
heroBackground: /images/photos/reg-desk-pyday-2019.jpg

---

This website, [pybcn.org](https://pybcn.org), is run by **Associació Python Barcelona** (PyBCN), a non-profit association of volunteers who organise Python meetups and events in Barcelona.

## Who we are

{{< association-identity >}}

The Management Board is responsible for this website. You can see who sits on it on the [Information](/pybcn_association/information/) page.

## What this site is

This is an informational site. It describes the association, its events, the people who organise them and speak at them, and how to join, propose a talk, or sponsor us. Nothing is sold through this site. The membership fee is paid on PayPal's own site, not here. Some pages embed a Google Form or a Google Calendar; those are served by Google.

The site is a set of static pages, published from a public repository on GitHub and served by GitHub Pages. We keep no server of our own and we run no analytics. The [Privacy policy](/pybcn_association/privacy-policy/) says what personal data this involves.

## Using the content

- The text on this site is written by volunteers and belongs to the association. You can quote it with a link to the page. Ask us before you reuse more than that.
- The photographs and biographies on the people pages belong to the people shown. Do not reuse them without their permission.
- The logos of sponsors and partner organisations belong to their owners.
- The site code is in a [public repository](https://github.com/pybcn/pybcn.github.io) on GitHub. The theme is free software under the MIT licence.

## Links to other sites

We link to Meetup, YouTube, GitHub, LinkedIn, Google Docs, and to the sites of speakers and sponsors. We do not control those sites and we are not responsible for what they publish or how they treat your data.

## Accuracy

Volunteers maintain this site in their free time. We try to keep it correct and we fix errors when someone tells us. Event details can change after they are published: the Meetup event page is the one to trust for date, time, and venue. We cannot promise that the site is always available or free of errors.

## Code of Conduct

Our [Code of Conduct](/pybcn_association/coc/) applies to every space the association runs, online and in person.

## Changes to this notice

We may update this notice. Every change is visible in the [history of this page](https://github.com/pybcn/pybcn.github.io/commits/edition/content/pybcn_association/legal-notice.md) on GitHub.

## Applicable law

Spanish law applies to this notice and to the use of this site. Any dispute goes to the courts of Barcelona, unless the law gives you the right to the courts of your own domicile.

Last updated: 2026-10-07
97 changes: 97 additions & 0 deletions content/pybcn_association/privacy-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
title: "Privacy policy"
description: "What personal data this site involves, why, and how to ask us to change or remove it"
menu:
main:
parent: 'The association'
weight: 7
aliases:
- /privacy-policy

layout: single
heroBackground: /images/photos/people-pyday-2019.jpg

---

PyBCN is a volunteer association. This page says what personal data this website involves, why we have it, who else sees it, and how to ask us to change or remove it. We wrote it to be read, so it is short. If something is not covered here, ask us.

## Who is responsible

**Associació Python Barcelona** (CIF G67254045) is the data controller.

- **Email**: [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com)
- **Registered address**: *pending. The association must add its registered address here before this page is published.*

The Management Board handles requests about personal data. We have no data protection officer: the law does not require one for an association of our size and activity.

## What data this site involves, and why

### People pages

The site has pages for the people who organise our events, speak at them, mentor at workshops, or collaborate with the association. Each page shows a name, a photograph, a short biography, the role in PyBCN or at an event, and links to the person's own profiles (GitHub, LinkedIn, Twitter, personal site).

- **Where it comes from**: the person. Each one sent the photograph and wrote or approved the text for publication here. Someone who did not want a photograph did not send one, and the page shows a silhouette instead.
- **Why we have it**: with the person's consent (GDPR article 6.1.a). You can withdraw it at any time, and we remove the page. Withdrawing consent does not affect what was published before.
- **How long we keep it**: until the person asks us to remove it, or until we take the page down ourselves because it is out of date.
- **One thing to know**: the source of this site is a public Git repository on GitHub. When we remove a page, it disappears from the site and from the current version of the repository. The old text remains in the repository history, as with any Git project. Tell us if you also want it gone from there and we will work it out with you. Copies kept by search engines and web archives are outside our control.

### Forms

A few pages link to or embed a Google Form:

- the **membership form**, to become a member of the association;
- the **propose a talk** form, for a talk at a PyBCN meetup;
- the **PyLadies BCN call for proposals** form;
- the **call for proposals** of each PyDay BCN edition (workshops and lightning talks), and the speaker, mentor, and attendee forms of some workshops.

Each form asks for what it needs to handle your request: usually your name, an email address to answer you, and the content of your proposal or your membership details.

- **Where it goes**: into a Google Forms spreadsheet in a Google account run by the association's organizers. Google stores it under its own [privacy policy](https://policies.google.com/privacy).
- **Why we have it**: to do what you asked for, which is the membership agreement or the steps you take to propose a talk or join a workshop (GDPR article 6.1.b).
- **Who sees it**: the organizers of that event or working group.
- **How long we keep it**: responses to an event form are needed until the event is over and its programme is published. We have no automatic deletion after that. Ask us and we delete your response. Membership data stays in the member register for as long as you are a member; the law requires associations to keep that register and the related accounting records for some years after.

### Membership payments

The membership fee is paid on [PayPal](https://www.paypal.com)'s site through a Subscribe button. PayPal tells us your name, your email address, and the amount paid. We never see your card or bank details. PayPal is a separate controller under its own [privacy statement](https://www.paypal.com/es/legalhub/privacy-full). We keep the payment record because the accounting and tax rules require it.

### Email

Our contact addresses, such as pybcn@googlegroups.com and pyladies-bcn@googlegroups.com, are Google Groups. A message you send there is stored in the group and read by the organizers who are members of that group. We use it to answer you and to follow up on what you asked (GDPR article 6.1.b and 6.1.f). The thread stays in the group archive; ask us and we delete it.

### Embedded Google content

A few pages embed a Google Form or a Google Calendar in a frame. The frame is served by Google: when the page loads, Google sees your IP address and browser details, and may set its own cookies inside the frame. Google's [privacy policy](https://policies.google.com/privacy) applies to that.

### Cookies

This site sets no cookies of its own, and runs no analytics or tracking scripts. Your browser also loads a few images from unsplash.com (page headers) and paypalobjects.com (the PayPal button). Like any image host, those servers see your IP address and browser details.

### Hosting

The site is served by [GitHub Pages](https://pages.github.com). GitHub may log the IP address and request details of each visit for security and operation, under the [GitHub privacy statement](https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement). We do not see or receive those logs.

## Who else sees your data

Nobody buys or receives your data from us. The companies named above see it because we use their services: Google (forms, calendar, mailing lists, documents), PayPal (payments), and GitHub (hosting and the source repository). All three are based in the USA. Each publishes the safeguards it applies to data from the EU, and we rely on those.

## Your rights

You can ask us to:

- see the data we hold about you (access);
- correct it (rectification);
- delete it (erasure), including a whole people page;
- limit how we use it (restriction), or object to a use (objection);
- give it to you in a usable format (portability);
- withdraw your consent, for a people page or anything else.

To do so, write to [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com). Say what you want and which page or form it concerns. For a people page, write from the email address or one of the profiles linked on the page, so we know it is you. The law gives us one month to answer. We do it by hand, as volunteers, so a few days is normal.

If you think we handle your data wrongly, you can complain to the Spanish data protection authority, the [Agencia Española de Protección de Datos](https://www.aepd.es).

## Changes to this policy

We may update this policy. Every change is visible in the [history of this page](https://github.com/pybcn/pybcn.github.io/commits/edition/content/pybcn_association/privacy-policy.md) on GitHub.

Last updated: 2026-10-07
29 changes: 29 additions & 0 deletions layouts/shortcodes/association-identity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{- /*
Who the association is in law, as a list, for the legal notice.

Takes no argument. Everything comes from [params.association] in
config.toml and from the main contact email beside it.

Spanish law 34/2002, LSSI-CE article 10, asks a site run by an
association for its name, its address, an email, its entry in the
register it is recorded in, and its tax number. They are read from the
configuration and not written into the page, so the association can
correct one of them without a volunteer editing a page of legal prose.
The registration date is not asked for; it goes on the registry line
when it is set, because it is what the register itself prints.
See the comment on [params.association] for the rest of the reasoning.

A value that is empty prints as a line that says so, in the page, rather
than as a missing bullet. A missing bullet reads as a page that never
claimed to carry the fact; a line that says the fact is missing is the
page admitting it does not yet do its job. bin/check-content warns about
the same two keys on every run.
*/ -}}
{{- $a := site.Params.association -}}
<ul>
<li><strong>Name</strong>: {{ $a.legal_name }}</li>
<li><strong>Tax ID (CIF)</strong>: {{ $a.tax_id }}</li>
<li><strong>Registered address</strong>: {{ with $a.address }}{{ . }}{{ else }}<em>not published yet. The Management Board has to supply it.</em>{{ end }}</li>
<li><strong>Registry</strong>: {{ with $a.registry }}{{ . }}{{ with $a.registered_on }}, registered on {{ . }}{{ end }}{{ else }}<em>not published yet. The entry in the Registre d'Associacions de la Generalitat de Catalunya has to come from the Management Board.</em>{{ end }}</li>
<li><strong>Email</strong>: <a href="mailto:{{ site.Params.main_contact_email }}">{{ site.Params.main_contact_email }}</a></li>
</ul>
1 change: 0 additions & 1 deletion themes/pybcn_theme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Based on https://github.com/alanorth/hugo-theme-bootstrap4-blog
- Supports Google, Bing, and Yandex site verification via meta tags
- Supports Google Analytics (async version), see [Hugo docs](https://gohugo.io/extras/analytics/)
- Supports Disqus comments, see [Hugo docs](https://gohugo.io/extras/comments/)
- Can show a message about cookie usage to the user, see [`exampleSite/config.toml`](https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/exampleSite/config.toml)
- Allow addition of custom `<head>` code in site's `layouts/partials/head-custom.html` (see [#17](https://github.com/alanorth/hugo-theme-bootstrap4-blog/pull/17))
- Configurable display of summaries of content in list templates.
- Configurable keywords for every post
Loading
Loading