User:Youjung/SI30: Unbordering/Prototyping: Difference between revisions
| (18 intermediate revisions by the same user not shown) | |||
| Line 14: | Line 14: | ||
== PLACES I WOULD NORMALLY NOT VISIT IN ROTTERDAM == | == PLACES I WOULD NORMALLY NOT VISIT IN ROTTERDAM == | ||
* [https://git.xpub.nl/youjung/places_i_would_not_normally_visit git repository] | |||
* [https://hub.xpub.nl/sergio/SI30/fieldwork-tools/places_i_would_not_visit/ page link] | |||
=== Idea === | === Idea === | ||
[[File:Screenshot 2026-04-18 at 09.50.51.png|thumb|vernacular web design vibes...]] | |||
Where are the places that you would normally not visit? And why would you not visit these places? Maybe it's because you do not have the needs, you do not like the vibe, you do not like the neighborhood or you have some kind of phobia. | Where are the places that you would normally not visit? And why would you not visit these places? Maybe it's because you do not have the needs, you do not like the vibe, you do not like the neighborhood or you have some kind of phobia. | ||
Rotterdam is a culturally diverse city, and there are invisible borders that divide they neighborhood. What determines these borders can be boundaries created by cultural/religious differences. This boundary can be derived from fear, overwhelm, unfamiliarity or even disgust. You might need courage to cross these borders. These borders and boundaries are very situated on personal background. Through this flask prototype, I'd like to document places that I fear to visit, maybe with some friends and try to identify what are our borders. Maybe even find patterns and compare. | Rotterdam is a culturally diverse city, and there are invisible borders that divide they neighborhood. What determines these borders can be boundaries created by cultural/religious differences. This boundary can be derived from fear, overwhelm, unfamiliarity or even disgust. You might need courage to cross these borders. These borders and boundaries are very situated on personal background. Through this flask prototype, I'd like to document places that I fear to visit, maybe with some friends and try to identify what are our borders. Maybe even find patterns and compare. | ||
The protocol is that you have to physically visit the location, take a picture, maybe even go inside and engage with the people there and share an anecdote | The protocol is that you have to physically visit the location, take a picture, maybe even go inside and engage with the people there and share an anecdote. | ||
=== Requirements === | === Requirements === | ||
| Line 98: | Line 102: | ||
[] | [] | ||
If there is data, it would look like this: | If there is data, it would look like this: | ||
at the last {}, you should not include , | |||
<span style="color: magenta;">at the last {}, you should not include ,</span> | |||
<syntaxhighlight> | <syntaxhighlight> | ||
[ | [ | ||
| Line 104: | Line 109: | ||
"name": "coffeeshop Bilbao", | "name": "coffeeshop Bilbao", | ||
"address": "Carnisselaan 20A, 3083 HJ Rotterdam", | "address": "Carnisselaan 20A, 3083 HJ Rotterdam", | ||
"anecdote": " | "anecdote": "", | ||
"user": "Youjung", | "user": "Youjung", | ||
"image": "Screenshot 2026-04-14 at 14.50.45.png" | "image": "Screenshot 2026-04-14 at 14.50.45.png" | ||
| Line 111: | Line 116: | ||
"name": "andy's darts", | "name": "andy's darts", | ||
"address": "Strevelsweg 734, 3083 AS Rotterdam", | "address": "Strevelsweg 734, 3083 AS Rotterdam", | ||
"anecdote": " | "anecdote": "", | ||
"user": " | "user": "Youjung", | ||
"image": "Screenshot 2026-04-14 at 14.49.01.png" | "image": "Screenshot 2026-04-14 at 14.49.01.png" | ||
} | } | ||
| Line 119: | Line 124: | ||
==== observations.html ==== | ==== observations.html ==== | ||
{%%} | Use if statement | ||
<code>{% if observation.visitor %}</code> <code>{% elif %}</code> <code>{% endif %}</code> | |||
<syntaxhighlight lang=html> | |||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> | |||
<link rel="stylesheet" href="{{ url_for('static', filename='reset.css') }}"> | |||
<!-- TITLE & DESCRIPTION --> | |||
<div class="about"> | |||
<h1>PLACES I WOULD NORMALLY<br>NOT VISIT IN ROTTERDAM</h1> | |||
<p>What are the invisible boundaries or borders within the city in Rotterdam? These borders are very personal and different according where the person is from. I've gathered places that I would not go or I need big courage to go. Maybe I should visit them. I wonder what their reaction would be. </p> | |||
<!-- FORM --> | |||
<details> | |||
<summary>Location Upload Form</summary> | |||
<form method="POST" enctype="multipart/form-data"> | |||
<label for="name">Location Name</label> | |||
<textarea name="name"></textarea> | |||
<label for="address">Address</label> | |||
<textarea name="address"></textarea> | |||
<label for="anecdote">Anecdote on why you are hesitant to enter</label> | |||
<textarea name="anecdote"></textarea> | |||
<label for="visited">Visited</label> | |||
<input type="checkbox" name="visited" id=""> | |||
<label name="images">Upload Image</label> | |||
<input type="file" id="images" name="images" accept="image/png, image/jpeg, image/jpg"> | |||
<label name="user-select">By whom</label> | |||
<select name="user" id="user"> | |||
<option value="">I am...</option> | |||
<option value="Youjung">Youjung</option> | |||
<option value="Daan">Daan</option> | |||
</select> | |||
<input id="collect" type="submit" value="COLLECT"/> | |||
</form> | |||
</details> | |||
<details> | |||
<summary>Collector Profile</summary> | |||
<div class="collector-box"> | |||
<div class="collector"> | |||
<p class="name">Youjung</p> | |||
<p> | |||
Nationality: South Korean<br> | |||
Age: 27<br> | |||
Pronouns: she/her<br> | |||
Religion: atheist<br> | |||
Occupation: Master student at Piet Zwart Institute<br> | |||
About: | |||
</p> | |||
</div> | |||
<div class="collector"> | |||
<p class="name">Daan</p> | |||
<p> | |||
Nationality: Dutch<br> | |||
Age: <br> | |||
Pronouns: <br> | |||
Religion: <br> | |||
Occupation: <br> | |||
About: | |||
</p> | |||
</div> | |||
</div> | |||
</details> | |||
</div> | |||
<!-- OUTPUT GRID --> | |||
<div class="grid"> | |||
{% for observation in observations %} | |||
#CUSTOMIZED BORDER FOR EACH USER | |||
<div class="box" style="border: 1px dashed {% if observation.user == 'Youjung' %}deeppink{% elif observation.user == 'Daan' %}lime{% else %}white{% endif %}"> | |||
<div> | |||
<span class="attr">Name: </span> | |||
<span>{{ observation.name }}</span> | |||
</div> | |||
<div> | |||
<span class="attr">Address: </span> | |||
<span>{{ observation.address }}</span> | |||
</div> | |||
<div> | |||
{% if observation.visited %} | |||
<span class="attr">Visited: </span> | |||
<span>Yes</span> | |||
{% else %} | |||
<span class="attr">Visited: </span> | |||
<span>No</span> | |||
{% endif %} | |||
</div> | |||
<div> | |||
<span class="attr">Collector: </span> | |||
<span>{{ observation.user }}</span> | |||
</div> | |||
<div> | |||
<span class="attr">Anecdote: </span> | |||
<span>{{ observation.anecdote }}</span> | |||
</div> | |||
<div> | |||
{% if observation.image %} | |||
<img src="{{ url_for('static', filename='uploads/' + observation.image) }}" style="width: 100%; margin-top: 0.5rem;"> | |||
{% endif %} | |||
</div> | |||
</div> | |||
{% endfor %} | |||
</div> | |||
</syntaxhighlight> | |||
=== Uploading to Sergio(server) === | === Uploading to Sergio(server) === | ||
| Line 135: | Line 244: | ||
# install flask | # install flask | ||
.venv/bin/pip install flask | .venv/bin/pip install flask | ||
2. Import '''PrefixMiddleware''' in '''observation.py''' | 2. Import '''PrefixMiddleware''' in '''observation.py''' | ||
<syntaxhighlight lang=python> | |||
from prefix import PrefixMiddleware | |||
</syntaxhighlight> | |||
3. Host setting --host=0.0.0.0 | 3. Host setting --host=0.0.0.0 | ||
<code>0.0.0.0</code> means listen to all network not only localhost. | |||
<syntaxhighlight lang=python> | |||
if __name__ == "__main__": | |||
app.run(host="0.0.0.0", port=5110) | |||
# app.run(debug=True) | |||
</syntaxhighlight> | |||
4. Reload nginx | 4. Reload nginx | ||
sudo nginx -t | |||
sudo systemctl reload nginx | |||
5. 413 Request Entity too large | 5. 413 Request Entity too large | ||
nginx image size is limited to 1MB. So open nginx | |||
sudo nano /etc/nginx/sites-enabled/hub.xpub.nl | |||
Edit maximum file size | |||
location /sergio/SI30/fieldwork-tools/places_i_would_not_visit/ { | |||
client_max_body_size 5M; | |||
proxy_pass http://localhost:5110/sergio/SI30/fieldwork-tools/places_i_would_not_visit/; | |||
include proxy_params; | |||
} | |||
=== Editing the file and updating === | |||
* systemmd system file name: placesiwouldnotvisit.service | |||
$ sudo systemctl start placesiwouldnotvisit | |||
$ sudo systemctl status placesiwouldnotvisit | |||
$ sudo systemctl restart placesiwouldnotvisit | |||
$ sudo systemctl stop placesiwouldnotvisit | |||
$ sudo systemctl enable placesiwouldnotvisit | |||
== Noticing Dutch Streets == | |||
[https://git.xpub.nl/youjung/Noticing_Dutch_Streets git repository] | |||
=== Uploading file to git === | |||
1. Create Repository | |||
2. Follow the step below to upload files | |||
If you are working with flask add .gitignore. It ignores the .venv and image folders. | |||
<pre> | |||
git init | |||
touch README.md | |||
touch .gitignore | |||
</pre> | |||
In .gitignore write this | |||
<pre> | |||
venv/ | |||
__pycache__/ | |||
*.pyc | |||
.env | |||
static/uploads/ | |||
</pre> | |||
And then Push! | |||
<pre> | |||
git add . | |||
git commit -m "add message" | |||
git push | |||
</pre> | |||
The command below allows you to save packages that were installed using pip in the virtual environment. | |||
<pre> | |||
uv pip freeze > requirements.txt | |||
git commit -m "add message" | |||
git push | |||
</pre> | |||
=== Cloning Git to Server === | |||
ssh to sergio and cd to public_html | |||
<pre> | |||
git clone https://git.xpub.nl/youjung/Noticing_Dutch_Streets | |||
cd Noticing_Dutch_Streets | |||
</pre> | |||
Then activate virtual environment and install requirement.txt | |||
<pre> | |||
uv venv | |||
source .venv/bin/activate | |||
uv pip install -r requirements.txt | |||
</pre> | |||
Latest revision as of 23:57, 31 May 2026
Documentation on prototyping with flask.
Flask Set up
Flask documentation page from prototyping class.
1. Install
$ uv venv $ source .venv/bin/activate $ uv pip install flask
2. Restarting your project
$ source .venv/bin/activate $ flask --app <filename> run
PLACES I WOULD NORMALLY NOT VISIT IN ROTTERDAM
Idea
Where are the places that you would normally not visit? And why would you not visit these places? Maybe it's because you do not have the needs, you do not like the vibe, you do not like the neighborhood or you have some kind of phobia.
Rotterdam is a culturally diverse city, and there are invisible borders that divide they neighborhood. What determines these borders can be boundaries created by cultural/religious differences. This boundary can be derived from fear, overwhelm, unfamiliarity or even disgust. You might need courage to cross these borders. These borders and boundaries are very situated on personal background. Through this flask prototype, I'd like to document places that I fear to visit, maybe with some friends and try to identify what are our borders. Maybe even find patterns and compare.
The protocol is that you have to physically visit the location, take a picture, maybe even go inside and engage with the people there and share an anecdote.
Requirements
This page needs a form that includes...
- location name
- address
- visited check box
- anecdote
- image upload
- select contributor
These collected data will be stored in a .json file and images would be collected in a separate folder.
File structure
CSS and uploaded images are stored in the static folder because they need to be directly accessible by the browser. Flask automatically serves anything in this folder publicly.
. ├── database.json ├── observations.py ├── static │ ├── reset.css │ ├── style.css │ └── uploads │ └── collectedimg.png └── templates └── observations.html
Code
observations.py
1. Saving data to json
2. Uploading image
import json
import os
from flask import Flask, render_template, request
from prefix import PrefixMiddleware
app = Flask(__name__)
#UPLOAD TO SERVER
app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/sergio/SI30/fieldwork-tools/places_i_would_not_visit')
os.makedirs("static/uploads", exist_ok=True)
@app.route("/", methods=["GET", "POST"])
def main():
with open("database.json", "r") as f:
observations = json.load(f)
if request.method == "POST":
observation = dict(request.form)
img = request.files["images"]
#ADD IMAGE
if img and img.filename != "":
img.save("static/uploads/" + img.filename)
observation["image"] = img.filename
else:
observation["image"] = None
observations.append(observation)
#WRITE TO DATABASE
with open("database.json", "w+") as f:
f.write(json.dumps(observations, indent=2))
return render_template("observations.html", observations=observations)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5110)
# app.run(debug=True)
database.json
[]
If there is data, it would look like this:
at the last {}, you should not include ,
[
{
"name": "coffeeshop Bilbao",
"address": "Carnisselaan 20A, 3083 HJ Rotterdam",
"anecdote": "",
"user": "Youjung",
"image": "Screenshot 2026-04-14 at 14.50.45.png"
},
{
"name": "andy's darts",
"address": "Strevelsweg 734, 3083 AS Rotterdam",
"anecdote": "",
"user": "Youjung",
"image": "Screenshot 2026-04-14 at 14.49.01.png"
}
]observations.html
Use if statement
{% if observation.visitor %} {% elif %} {% endif %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='reset.css') }}">
<!-- TITLE & DESCRIPTION -->
<div class="about">
<h1>PLACES I WOULD NORMALLY<br>NOT VISIT IN ROTTERDAM</h1>
<p>What are the invisible boundaries or borders within the city in Rotterdam? These borders are very personal and different according where the person is from. I've gathered places that I would not go or I need big courage to go. Maybe I should visit them. I wonder what their reaction would be. </p>
<!-- FORM -->
<details>
<summary>Location Upload Form</summary>
<form method="POST" enctype="multipart/form-data">
<label for="name">Location Name</label>
<textarea name="name"></textarea>
<label for="address">Address</label>
<textarea name="address"></textarea>
<label for="anecdote">Anecdote on why you are hesitant to enter</label>
<textarea name="anecdote"></textarea>
<label for="visited">Visited</label>
<input type="checkbox" name="visited" id="">
<label name="images">Upload Image</label>
<input type="file" id="images" name="images" accept="image/png, image/jpeg, image/jpg">
<label name="user-select">By whom</label>
<select name="user" id="user">
<option value="">I am...</option>
<option value="Youjung">Youjung</option>
<option value="Daan">Daan</option>
</select>
<input id="collect" type="submit" value="COLLECT"/>
</form>
</details>
<details>
<summary>Collector Profile</summary>
<div class="collector-box">
<div class="collector">
<p class="name">Youjung</p>
<p>
Nationality: South Korean<br>
Age: 27<br>
Pronouns: she/her<br>
Religion: atheist<br>
Occupation: Master student at Piet Zwart Institute<br>
About:
</p>
</div>
<div class="collector">
<p class="name">Daan</p>
<p>
Nationality: Dutch<br>
Age: <br>
Pronouns: <br>
Religion: <br>
Occupation: <br>
About:
</p>
</div>
</div>
</details>
</div>
<!-- OUTPUT GRID -->
<div class="grid">
{% for observation in observations %}
#CUSTOMIZED BORDER FOR EACH USER
<div class="box" style="border: 1px dashed {% if observation.user == 'Youjung' %}deeppink{% elif observation.user == 'Daan' %}lime{% else %}white{% endif %}">
<div>
<span class="attr">Name: </span>
<span>{{ observation.name }}</span>
</div>
<div>
<span class="attr">Address: </span>
<span>{{ observation.address }}</span>
</div>
<div>
{% if observation.visited %}
<span class="attr">Visited: </span>
<span>Yes</span>
{% else %}
<span class="attr">Visited: </span>
<span>No</span>
{% endif %}
</div>
<div>
<span class="attr">Collector: </span>
<span>{{ observation.user }}</span>
</div>
<div>
<span class="attr">Anecdote: </span>
<span>{{ observation.anecdote }}</span>
</div>
<div>
{% if observation.image %}
<img src="{{ url_for('static', filename='uploads/' + observation.image) }}" style="width: 100%; margin-top: 0.5rem;">
{% endif %}
</div>
</div>
{% endfor %}
</div>
Uploading to Sergio(server)
Followed this documentation but encountered some problems. This is how I solved it.
1. Replace .venv and install flask
# remove existing venv rm -rf .venv # make new venv on server python3 -m venv .venv # install flask .venv/bin/pip install flask
2. Import PrefixMiddleware in observation.py
from prefix import PrefixMiddleware
3. Host setting --host=0.0.0.0
0.0.0.0 means listen to all network not only localhost.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5110)
# app.run(debug=True)
4. Reload nginx
sudo nginx -t sudo systemctl reload nginx
5. 413 Request Entity too large nginx image size is limited to 1MB. So open nginx
sudo nano /etc/nginx/sites-enabled/hub.xpub.nl
Edit maximum file size
location /sergio/SI30/fieldwork-tools/places_i_would_not_visit/ {
client_max_body_size 5M;
proxy_pass http://localhost:5110/sergio/SI30/fieldwork-tools/places_i_would_not_visit/;
include proxy_params;
}
Editing the file and updating
- systemmd system file name: placesiwouldnotvisit.service
$ sudo systemctl start placesiwouldnotvisit $ sudo systemctl status placesiwouldnotvisit $ sudo systemctl restart placesiwouldnotvisit $ sudo systemctl stop placesiwouldnotvisit
$ sudo systemctl enable placesiwouldnotvisit
Noticing Dutch Streets
Uploading file to git
1. Create Repository
2. Follow the step below to upload files
If you are working with flask add .gitignore. It ignores the .venv and image folders.
git init touch README.md touch .gitignore
In .gitignore write this
venv/ __pycache__/ *.pyc .env static/uploads/
And then Push!
git add . git commit -m "add message" git push
The command below allows you to save packages that were installed using pip in the virtual environment.
uv pip freeze > requirements.txt git commit -m "add message" git push
Cloning Git to Server
ssh to sergio and cd to public_html
git clone https://git.xpub.nl/youjung/Noticing_Dutch_Streets cd Noticing_Dutch_Streets
Then activate virtual environment and install requirement.txt
uv venv source .venv/bin/activate uv pip install -r requirements.txt