Skip to content

Commit a19bcf8

Browse files
authored
Merge pull request #33 from Schluggi/new_live
chore(deps): bump python dependencies
2 parents f5a09a4 + d0dc71b commit a19bcf8

24 files changed

Lines changed: 443 additions & 187 deletions

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
codenames/static/img/codes/**/*.jpg
2+
codenames/static/img/cards/**/*.jpg

.github/workflows/lint-docker.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Linting Dockerfile
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
paths:
8+
- 'Dockerfile'
9+
pull_request:
10+
paths:
11+
- 'Dockerfile'
12+
13+
# Allows you to run this workflow manually from the Actions tab
14+
workflow_dispatch:
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
linting:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
persist-credentials: false
28+
29+
- name: Hadolint Dockerfile Linter
30+
uses: hadolint/hadolint-action@v3.1.0
31+
with:
32+
dockerfile: Dockerfile

.github/workflows/lint-python.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Linting Python
2+
# https://medium.com/swlh/enhancing-code-quality-with-github-actions-67561c6f7063
3+
4+
on:
5+
push:
6+
branches:
7+
- "main"
8+
paths:
9+
- '**.py'
10+
- src/requirements.txt
11+
pull_request:
12+
paths:
13+
- '**.py'
14+
- src/requirements.txt
15+
16+
# Allows you to run this workflow manually from the Actions tab
17+
workflow_dispatch:
18+
19+
permissions:
20+
checks: write
21+
contents: write
22+
23+
jobs:
24+
linting:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v4
29+
with:
30+
persist-credentials: false
31+
32+
- name: Set up Python
33+
uses: actions/setup-python@v5
34+
with:
35+
python-version: 3.13
36+
37+
- name: Install Python dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install -r requirements.txt
41+
42+
- name: Install Python linters
43+
run: pip install flake8 pylint
44+
45+
- name: Run linters
46+
uses: wearerequired/lint-action@v2
47+
with:
48+
flake8: true
49+
flake8_args: |
50+
--ignore=E501
51+
continue_on_error: false
52+
pylint: true
53+
# https://github.com/pylint-dev/pylint/issues/8138
54+
pylint_args: |
55+
--disable=missing-module-docstring \
56+
--disable=missing-class-docstring \
57+
--disable=missing-function-docstring \
58+
--disable=line-too-long \
59+
--disable=too-few-public-methods \
60+
--disable=W0511

.github/workflows/lint-yaml.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Linting YAML
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
paths:
8+
- '**.yaml'
9+
- '**.yml'
10+
pull_request:
11+
paths:
12+
- '**.yaml'
13+
- '**.yml'
14+
15+
# Allows you to run this workflow manually from the Actions tab
16+
workflow_dispatch:
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
linting:
23+
runs-on: ubuntu-latest
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
with:
29+
persist-credentials: false
30+
31+
- name: yaml-lint
32+
uses: ibiqlik/action-yamllint@v3
33+
with:
34+
config_data: |
35+
extends: default
36+
rules:
37+
comments:
38+
level: error
39+
comments-indentation:
40+
level: error
41+
document-end: disable
42+
document-start: disable
43+
line-length: disable
44+
truthy:
45+
allowed-values:
46+
- 'true'
47+
- 'false'
48+
- 'on'

.github/workflows/sast.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Static Application Security Testing (SAST)
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
pull_request:
8+
workflow_dispatch:
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME: ${{ github.repository }}
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
sast:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
with:
24+
persist-credentials: false
25+
fetch-depth: 0
26+
27+
- name: Dependency Scanning (SCA)
28+
uses: anchore/scan-action@v6.3.0
29+
with:
30+
path: "."
31+
fail-build: true
32+
output-format: table
33+
34+
35+
- name: Create empty ".truffleignore" in case it doesn't exist
36+
run: touch .truffleignore
37+
38+
- name: "Secret Scanning"
39+
id: trufflehog
40+
uses: trufflesecurity/trufflehog@v3.89.2
41+
continue-on-error: false
42+
with:
43+
path: ./
44+
base: ${{ github.head_ref }}
45+
extra_args: --exclude-paths=.truffleignore

.hadolint.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ignored:
2+
- DL3013 # Pin versions in pip. Instead of `pip install <package>` use `pip install <package>==<version>` or `pip install --requirement <requirements file>`

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM python:3.13-alpine
2+
LABEL authors="Schluggi"
3+
4+
WORKDIR /app
5+
6+
COPY codenames /app/codenames
7+
COPY words2img /app/words2img
8+
COPY requirements.txt /app/requirements.txt
9+
10+
RUN pip install --no-cache-dir --upgrade pip gunicorn eventlet
11+
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt \
12+
&& rm -f /app/requirements.txt
13+
14+
RUN python words2img/words2img.py
15+
16+
EXPOSE 5000
17+
ENTRYPOINT ["gunicorn", "--worker-class", "eventlet", "-w", "2", "-b", "0.0.0.0:5000", "codenames:app"]

README.md

Lines changed: 49 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,79 @@
11
# Codenames
2+
23
<a href="https://www.buymeacoffee.com/schluggi" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/white_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
34

5+
I like the game cardboard game [codenames](https://en.wikipedia.org/wiki/Codenames_\(board_game\)) and now that COVID-19 is part of our life I have played a lot online with my friends on [this](https://www.horsepaste.com/) website. But I realized that I want to play codename pictures instead. So I've decided to create my own.
46

5-
I like the game cardboard game [codenames](https://en.wikipedia.org/wiki/Codenames_\(board_game\)) and now that COVID-19 is
6-
part of our life I have played a lot online with my friends on [this](https://www.horsepaste.com/) website. But I
7-
realized that I want to play codename pictures instead. So I've decided to create my own.
7+
# Features
88

9-
## Features
109
- Realtime online multiplayer
1110
- Multiple game modes:
1211
- Codename classic (with words)
13-
- Codename pictures
12+
- Codename pictures
1413
- Does not include any images (for copyright reasons, but you can import your own)
15-
- Just like the codenames board game...
16-
17-
## Requirements
18-
- Python >= 3.6
19-
- [Almost every](https://docs.sqlalchemy.org/en/13/core/engines.html#database-urls) database engine is supported (SQLite
20-
in memory by default)
21-
22-
## Installation & Quickstart
23-
1. Clone this repo
24-
2. Create a virtualenv and join them
25-
3. Install python requirements
26-
```shell script
27-
$ pip3 install -r requirements.txt
28-
```
29-
4. Generate text images (for the classic mode)
30-
```shell script
31-
$ ./words2img/words2img.py
32-
```
33-
Optional: [Import images](https://github.com/Schluggi/codenames#import-images) for picture mode
34-
5. Configuration
35-
- 5.1 Create a secret key by running `python3 -c "import os; print(os.urandom(24).hex())"` and insert that key into the
36-
`config.py`
37-
6. Test your setup by running `flask run`
38-
7. If everything works as expected, you should now be able to play at `http://localhost:5000`
39-
40-
## Configuring
41-
### Add new words or languages
14+
- Just like the codenames board game but online
15+
16+
# Quickstart
17+
18+
## Docker
19+
20+
```commandline
21+
docker run -p 5000:5000 -e GAME_MODES="pictures,classic_de,classic_en,classic_en-undercover" <placeholder>:latest
22+
```
23+
24+
## Git
25+
26+
```commandline
27+
git clone git@github.com:Schluggi/codenames.git
28+
cd codenames
29+
python3 -m venv .venv
30+
source .venv/bin/activate
31+
pip install -r requirements.txt
32+
python3 ./words2img/words2img.py
33+
flask --app codenames run
34+
```
35+
36+
Optional: [Import images](https://github.com/Schluggi/codenames#import-images) for picture mode
37+
38+
# Configuring
39+
40+
## Environment variables
41+
42+
| name | Description | required | default |
43+
|------------|------------------------------------------------|----------|------------------------------------------------------|
44+
| GAME_MODES | A comma separated list of available game modes | No | pictures,classic_de,classic_en,classic_en-undercover |
45+
| SECRET_KEY | A secret key to encrypt the user sessions | No | \<a random key will be created\> |
46+
47+
## Add new words or languages
48+
4249
In this example we'll add france as language for the classic mode.
4350

4451
1. Create a language file: `./words2img/words/fr.txt` (one word each line)
4552
2. Run the script (existing files will be overwritten)
46-
```shell script
47-
$ python3 ./words2img/words2img.py
53+
```commandline
54+
python3 ./words2img/words2img.py
4855
```
49-
3. Append `classic_fr` to the `GAME_MODES` list in the `config.py`
56+
3. Append `classic_fr` to your `GAME_MODES` environment variable
57+
58+
## Import images
5059
51-
### Import images
5260
To get the best experience it's recommend to buy the original cardboard game and scan all images. In my case I scanned
53-
all pictures with 400dpi and used [picpunch](https://github.com/Schluggi/picpunch) to cut them to size and render for
61+
all pictures with 400dpi and used [picpunch](https://github.com/Schluggi/picpunch) to cut them to size and render for
5462
web (`--border 5 --quallity 30`).The new images have to be placed into the corresponding folders.
5563
5664
The code images into (at least 20):
65+
5766
- `codenames/static/images/codes`
5867
5968
And the colored team cards (at least 1 each):
60-
- `codenames/static/images/cards/assassin`
69+
70+
- `codenames/static/images/cards/assassin`
6171
- `codenames/static/images/cards/blue`
6272
- `codenames/static/images/cards/neutral`
6373
- `codenames/static/images/cards/red`
6474
6575
The filename does not matter. But the file extension and type has to be JPEG/JPG.
6676
67-
### Apache2 with mod_wsgi
68-
`flask run` works fine but you should'nt use it for production deployment. However you can use Apache2 instead.
69-
If not already installed you have to install `libapache2-mod-wsgi-py3`. After installation you can create a virtualhost
70-
like in this example:
71-
72-
```
73-
<VirtualHost *:80>
74-
ServerName codenames.example.org
75-
Redirect / https://codenames.example.org/
76-
</VirtualHost>
77-
78-
<VirtualHost *:443>
79-
ServerName codenames.example.org
80-
81-
WSGIDaemonProcess wsgi_codenames user=www-data group=www-data processes=1 threads=5 python-home=python-home=/virtualenvs/codenames/
82-
WSGIScriptAlias / /var/www/codenames/wsgi.py
83-
84-
SSLEngine On
85-
SSLCertificateFile /etc/letsencrypt/live/codenames.example.org/cert.pem
86-
SSLCertificateKeyFile /etc/letsencrypt/live/codenames.example.org/privkey.pem
87-
SSLCertificateChainFile /etc/letsencrypt/live/codenames.example.org/chain.pem
88-
SSLProtocol ALL -SSLv2 -SSLv3
89-
SSLHonorCipherOrder On
90-
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:
91-
SSLCompression Off
92-
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
93-
94-
<Directory /var/www/codenames/>
95-
WSGIProcessGroup wsgi_codenames
96-
WSGIApplicationGroup %{GLOBAL}
97-
</Directory>
98-
</VirtualHost>
99-
```
100-
I use Let's Encrypt for free ssl certificates. Please ensure that all paths are correct. After restating Apache2,
101-
codenames should be run as part of the Apache2-daemon.
77+
# Credits
10278
103-
## Credits
10479
Created and maintained by Schluggi.

0 commit comments

Comments
 (0)