diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 03cf44a..0000000 --- a/TODO.md +++ /dev/null @@ -1,5 +0,0 @@ -TODO: comment the code - -TODO: remove new from homepage? -or -TODO: add per-new level in the xquisite branches (this makes more sense!) diff --git a/exquisite_branch/__init__.py b/exquisite_branch/__init__.py index 2482920..65dac4a 100644 --- a/exquisite_branch/__init__.py +++ b/exquisite_branch/__init__.py @@ -36,8 +36,8 @@ def create_app(test_config=None): os.path.join(app.root_path, "static"), "favicon.ico", mimetype="image/vnd.microsoft.icon", ) - from . import draw - app.register_blueprint(draw.bp) + from . import write + app.register_blueprint(write.bp) from . import share app.register_blueprint(share.bp) diff --git a/exquisite_branch/display.py b/exquisite_branch/display.py index 3559c05..ada9b0a 100644 --- a/exquisite_branch/display.py +++ b/exquisite_branch/display.py @@ -8,40 +8,38 @@ from exquisite_branch.db import get_db bp = Blueprint('display', __name__, url_prefix='/display') -@bp.route('/') -def display(): - db = get_db() - branches = db.execute( - "SELECT content, branch, parent, username FROM branches" - ).fetchall() - streams = [] - for branch in branches[::-1]: - if branch not in flatten(streams): - stream = [branch] - parent = branch['parent'] - while parent != 'NEW': - current = next( - (x for x in branches if x['branch'] == parent), None) - parent = current['parent'] - stream.append(current) +# branches = db.execute( +# "SELECT content, branch, parent, username FROM branches" +# ).fetchall() + +# streams = [] +# for branch in branches[::-1]: +# if branch not in flatten(streams): +# stream = [branch] +# parent = branch['parent'] +# while parent != 'NEW': +# current = next( +# (x for x in branches if x['branch'] == parent), None) +# parent = current['parent'] +# stream.append(current) - streams.append(stream[::-1]) +# streams.append(stream[::-1]) - return render_template('display_mako.html', branches=branches, streams=streams) +# return render_template('display_mako.html', branches=branches, streams=streams) -def flatten(t): - return [item for sublist in t for item in sublist] +# def flatten(t): +# return [item for sublist in t for item in sublist] -@bp.route('/linked') -def linked(): +@bp.route('/') +def display(): db = get_db() branches = db.execute( "SELECT content, branch, parent, username FROM branches" ).fetchall() - return render_template('display_linked_mako.html', branches=branches) \ No newline at end of file + return render_template('display.html', branches=branches) diff --git a/exquisite_branch/static/css/display.css b/exquisite_branch/static/css/display.css index 5f6ec1d..42a3af3 100644 --- a/exquisite_branch/static/css/display.css +++ b/exquisite_branch/static/css/display.css @@ -1,26 +1,41 @@ -.streams { - overflow-x: auto; - overflow-y: hidden; - position: relative; - height: 500px; + + +header { +padding: 32px; +max-width: 60ch; + } -.stream { - white-space: nowrap; - position: absolute; +header h1, +header p { +margin: 0; +} + +.container{ + display: block; + padding: 64px; } -.svg-container { +.stream, +.streams{ + /* white-space: nowrap; */ + position: relative; display: inline-block; - margin: 0; - padding: 0; + width: 40ch; position: relative; } -.author { +.text-container { position: absolute; - left: 50%; - bottom: 50px; + top: 0; + left: 0; + display: inline-block; + + +} + +.author { + position: relative; font-size: 1rem; background-color: white; } @@ -34,6 +49,3 @@ white-space: nowrap; } -.branch svg { - border-top: 1px solid currentColor; -} diff --git a/exquisite_branch/static/css/display_mako.css b/exquisite_branch/static/css/display_mako.css deleted file mode 100644 index 5f7bb80..0000000 --- a/exquisite_branch/static/css/display_mako.css +++ /dev/null @@ -1,52 +0,0 @@ - -.container{ - display: block; - padding: 2000px; -} -.streams { - overflow-x: auto; - overflow-y: hidden; - position: relative; - width: 500px; - height: 500px; - display: inline-block; -} - -.stream { - white-space: nowrap; - position: relative; - display: inline-block; - width: 500px; - height: 500px; - position: relative; -} - -.svg-container { - position: absolute; - top: 0; - left: 0; - display: inline-block; - - -} - -.author { - position: absolute; - left: 50%; - bottom: 50px; - font-size: 1rem; - background-color: white; -} - -.branches { - overflow-x: auto; - overflow-y: hidden; -} - -.branch { - white-space: nowrap; -} - -.branch svg { - border-top: 1px solid currentColor; -} diff --git a/exquisite_branch/static/css/draw.css b/exquisite_branch/static/css/draw.css deleted file mode 100644 index 778e7b3..0000000 --- a/exquisite_branch/static/css/draw.css +++ /dev/null @@ -1,32 +0,0 @@ -svg { - width: 500px; - height: 500px; - background-color: white; -} -#svg-container { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); -} - -#previous { - position: absolute; - top: 0; - transform: translateX(-100%); -} - -#previous svg { - background: none; - border: none; -} - -#previous::after { - content: ""; - width: 100%; - height: 100%; - left: 0; - position: absolute; - transform: translateX(-25%); - background-color: var(--background); -} diff --git a/exquisite_branch/static/css/global.css b/exquisite_branch/static/css/global.css index dbd6494..c0c4166 100644 --- a/exquisite_branch/static/css/global.css +++ b/exquisite_branch/static/css/global.css @@ -13,10 +13,11 @@ body { a { color: currentColor; text-decoration: none; + user-select: all; } a:hover { - color: tomato; + color: white; } nav { diff --git a/exquisite_branch/static/css/home.css b/exquisite_branch/static/css/home.css index 66b39ea..de5de2b 100644 --- a/exquisite_branch/static/css/home.css +++ b/exquisite_branch/static/css/home.css @@ -4,7 +4,7 @@ header { } header object { - width: 100vmin; + width: 500px; height: auto; margin: 0 auto; } diff --git a/exquisite_branch/static/css/variables.css b/exquisite_branch/static/css/variables.css index d927084..f663ca1 100644 --- a/exquisite_branch/static/css/variables.css +++ b/exquisite_branch/static/css/variables.css @@ -1,4 +1,4 @@ :root { - --background: #edd; + --background: #2a9d8f; --color: black; } diff --git a/exquisite_branch/static/img/title.svg b/exquisite_branch/static/img/title.svg new file mode 100755 index 0000000..a772b33 --- /dev/null +++ b/exquisite_branch/static/img/title.svg @@ -0,0 +1,4 @@ + + + + diff --git a/exquisite_branch/static/js/draw.js b/exquisite_branch/static/js/draw.js deleted file mode 100644 index 8935639..0000000 --- a/exquisite_branch/static/js/draw.js +++ /dev/null @@ -1,114 +0,0 @@ -// Great resource from https://stackoverflow.com/a/40700068 -// Thank you ConnorFan - -var strokeWidth = 2; -var bufferSize; - -var svgElement = document.getElementById("svgElement"); -var rect = svgElement.getBoundingClientRect(); -var path = null; -var strPath; -var buffer = []; // Contains the last positions of the mouse cursor - -svgElement.addEventListener("mousedown", function (e) { - bufferSize = document.getElementById("cmbBufferSize").value; - path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttribute("fill", "none"); - path.setAttribute("stroke", "currentColor"); - path.setAttribute("stroke-width", strokeWidth); - buffer = []; - var pt = getMousePosition(e); - appendToBuffer(pt); - strPath = "M" + pt.x + " " + pt.y; - path.setAttribute("d", strPath); - svgElement.appendChild(path); -}); - -svgElement.addEventListener("mousemove", function (e) { - if (path) { - appendToBuffer(getMousePosition(e)); - updateSvgPath(); - } -}); - -svgElement.addEventListener("mouseup", function () { - if (path) { - path = null; - } -}); - -svgElement.addEventListener("mouseleave", function () { - if (path) { - path = null; - } -}); - -var getMousePosition = function (e) { - return { - x: e.pageX - rect.left, - y: e.pageY - rect.top, - }; -}; - -var appendToBuffer = function (pt) { - buffer.push(pt); - while (buffer.length > bufferSize) { - buffer.shift(); - } -}; - -// Calculate the average point, starting at offset in the buffer -var getAveragePoint = function (offset) { - var len = buffer.length; - if (len % 2 === 1 || len >= bufferSize) { - var totalX = 0; - var totalY = 0; - var pt, i; - var count = 0; - for (i = offset; i < len; i++) { - count++; - pt = buffer[i]; - totalX += pt.x; - totalY += pt.y; - } - return { - x: totalX / count, - y: totalY / count, - }; - } - return null; -}; - -var updateSvgPath = function () { - var pt = getAveragePoint(0); - - if (pt) { - // Get the smoothed part of the path that will not change - strPath += " L" + pt.x + " " + pt.y; - - // Get the last part of the path (close to the current mouse position) - // This part will change if the mouse moves again - var tmpPath = ""; - for (var offset = 2; offset < buffer.length; offset += 2) { - pt = getAveragePoint(offset); - tmpPath += " L" + pt.x + " " + pt.y; - } - - // Set the complete current path coordinates - path.setAttribute("d", strPath + tmpPath); - } -}; - -// -// -// -// SAVE THE BRANCH - -const form = document.querySelector("form"); - -form.addEventListener("submit", () => { - let wrapper = document.createElement("div"); - wrapper.appendChild(svgElement); - form["content"].value = wrapper.innerHTML; - return true; -}); diff --git a/exquisite_branch/templates/base_mako.html b/exquisite_branch/templates/base_mako.html index d158eae..1ae9a20 100644 --- a/exquisite_branch/templates/base_mako.html +++ b/exquisite_branch/templates/base_mako.html @@ -13,8 +13,8 @@ ${self.body()} diff --git a/exquisite_branch/templates/display.html b/exquisite_branch/templates/display.html index 2ccdf51..d8a0dc9 100644 --- a/exquisite_branch/templates/display.html +++ b/exquisite_branch/templates/display.html @@ -1,49 +1,44 @@ -{%extends 'base.html' %} {%block head %} - - -Display -{%endblock%} {%block nav%} -Home -Draw - -{%endblock%} {%block contents%} - -

Exquisite Branch

- -
- {% for stream in streams %} -
- {% for branch in stream %} -
- {{branch['content'] | safe}} - - {{ branch['username']}} - -
- {%endfor%} -
- {%endfor%} -
- -{{colors}} - -

Branches

-
- {% for stream in streams %} -
- {% for branch in stream %} -
- {{branch['content'] | safe}} - {{ branch['username']}} +<%inherit file="base_mako.html" /> + + +<%block name="head"> + + + +
+

Exquisite Excerpts

+

Here texts branch and follow their own path. Click on an excerpt to create a new branch and continue toward new meanings.

+
+ +
+ + <% from random import random %> + <% from collections import defaultdict %> + <% transform = {'NEW': ''} %> + <% visited = defaultdict(int) %> + +
+ + % for branch in branches: + + <% visited[branch['parent']] += 1 %> + + + % if visited[branch['parent']] > 1: + <% steer = (random() - 0.5) * 0.25 %> + % else: + <% steer = 0 %> + % endif + + <% transform[branch['branch']] = f'{transform[branch["parent"]]} rotate({random() * 0.04 + steer}turn) translateX(100%)' %> + +
+ + ${branch['content']} + + ${branch['username']}
- {%endfor%} + + % endfor
- {%endfor%} -
-{%endblock%} + diff --git a/exquisite_branch/templates/display_linked_mako.html b/exquisite_branch/templates/display_linked_mako.html deleted file mode 100644 index d9c0563..0000000 --- a/exquisite_branch/templates/display_linked_mako.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - -<%inherit file="base_mako.html" /> - - -<%block name="head"> - - - - -
- - - <% from random import random %> - <% from collections import defaultdict %> - <% transform = {'NEW': ''} %> - <% visited = defaultdict(int) %> - -
- - % for branch in branches: - - - <% visited[branch['parent']] += 1 %> - - - % if visited[branch['parent']] > 1: - <% steer = (random() - 0.5) * 0.25 %> - % else: - <% steer = 0 %> - % endif - - - <% transform[branch['branch']] = f'{transform[branch["parent"]]} rotate({random() * 0.04 + steer}turn) translateX(100%)' %> - - - - % endfor -
-
\ No newline at end of file diff --git a/exquisite_branch/templates/display_mako.html b/exquisite_branch/templates/display_mako.html deleted file mode 100644 index e40b892..0000000 --- a/exquisite_branch/templates/display_mako.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - -<%inherit file="base_mako.html" /> - -<%block name="head"> - - - -<% from random import random %> -<% offset = 1 / (len(streams) - 1)%> -% for stream in streams: -
- <% transform = f'rotate({offset * loop.index}turn) translateX(100%) ' %> - % for branch in stream: - <% transform = transform + ' rotate(' + str((random() * 2 - 1) * 0.02) + 'turn) translateX(100%)'%> -
${branch['content']}
- % endfor -
-% endfor \ No newline at end of file diff --git a/exquisite_branch/templates/draw.html b/exquisite_branch/templates/draw.html deleted file mode 100644 index 163240e..0000000 --- a/exquisite_branch/templates/draw.html +++ /dev/null @@ -1,51 +0,0 @@ -{%extends 'base.html' %} {%block head %} -Draw - - - -{%endblock%} {%block nav%} -Home -Results - -{%endblock%} {%block contents%} - -

Draw

- -
- - -
- -
- - -
- -
- - - - -
-{%endblock%} diff --git a/exquisite_branch/templates/home.html b/exquisite_branch/templates/home.html index 9b4bbd7..5ce87d6 100644 --- a/exquisite_branch/templates/home.html +++ b/exquisite_branch/templates/home.html @@ -12,15 +12,14 @@
-

really exquisite indeed

- Start new
- Continue from last
+ Start new
+ Continue from last
Display results
diff --git a/exquisite_branch/templates/share.html b/exquisite_branch/templates/share.html index 3737349..1a74f9d 100644 --- a/exquisite_branch/templates/share.html +++ b/exquisite_branch/templates/share.html @@ -11,9 +11,9 @@ diff --git a/exquisite_branch/templates/write.html b/exquisite_branch/templates/write.html new file mode 100644 index 0000000..94823cc --- /dev/null +++ b/exquisite_branch/templates/write.html @@ -0,0 +1,27 @@ +{%extends 'base.html' %} {%block head %} +Draw + + + +{%endblock%} {%block nav%} +Home +Results + +{%endblock%} {%block contents%} + + + + + + +

Write

+ + +
+ + + + +
+ +{%endblock%} diff --git a/exquisite_branch/draw.py b/exquisite_branch/write.py similarity index 87% rename from exquisite_branch/draw.py rename to exquisite_branch/write.py index c8adfa1..30535f0 100644 --- a/exquisite_branch/draw.py +++ b/exquisite_branch/write.py @@ -6,11 +6,11 @@ from werkzeug.exceptions import abort from shortuuid import uuid -bp = Blueprint('draw', __name__, url_prefix='/draw') +bp = Blueprint('write', __name__, url_prefix='/write') @bp.route('/', methods=('GET', 'POST')) -def draw(parent=None): +def write(parent=None): db = get_db() if request.method == 'POST': @@ -42,7 +42,7 @@ def draw(parent=None): if previous is None: abort(404, f"Previous with id {parent} doesn't exist") - return render_template('draw.html', parent=parent, content=previous['content'], branch=branch) + return render_template('write.html', parent=parent, content=previous['content'], branch=branch) @bp.route('/last', methods=('GET', 'POST')) @@ -68,7 +68,7 @@ def last(): db.commit() return redirect(url_for('share.share', branch=branch)) - return render_template('draw.html', parent=parent, content=previous['content'], branch=branch) + return render_template('write.html', parent=parent, content=previous['content'], branch=branch) @bp.route('/', methods=('GET', 'POST')) @@ -90,4 +90,4 @@ def new(): db.commit() return redirect(url_for('share.share', branch=branch)) - return render_template('draw.html', parent=parent, branch=branch) + return render_template('write.html', parent=parent, branch=branch) diff --git a/linked.svg b/linked.svg new file mode 100755 index 0000000..fd01726 --- /dev/null +++ b/linked.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4565640 --- /dev/null +++ b/readme.md @@ -0,0 +1,61 @@ +# Exquisite Excerpts + +A branching version of the [exquisite corpse](https://en.wikipedia.org/wiki/Exquisite_corpse) game, forked from the [exquisite branch](https://git.xpub.nl/kamo/exquisite-branch) drawing app developed for [SI17](https://issue.xpub.nl/17/). + +Write something, upload it and send the link to someone else: they will continue from your excerpt. With a catch: if you send to just one person the chain will continue linearly, but send it to more people and things will start branching in different directions. + +Could be a writing machine to work on the collective pubblication for the graduation, inspired by what [Kim wrote here](https://pad.xpub.nl/p/gradcollectivexpub). + + +## Install + +Clone the repository. +``` +git clone https://git.xpub.nl/kamo/exex.git +``` + +Create a virtual environment. +``` +python3 -m venv venv +``` + +Install the requirements with `pip` and the `requirements.txt` file. +``` +pip install -r requirements.txt +``` + +Create an `.env` file in the root folder of the project with the following variables: +``` +DEBUG=True +FLASK_ENV=development +FLASK_APP=exquisite_branch +``` + +Before running the app for the first time, be sure to initialize the database. __Watch out:__ this will delete the previous instance of the database along with its contents! +``` +flask init-db +``` +After initializing the database you can run the flask application +``` +flask run +``` + +## Overview + +Exex saves contents in a database, and join them together in a branching version of the exquisite corpse. + +The original exquisite corpse data structure is something similar to a linked list, where every drawing is connected to the previous one. Contents in _exex_ are saved in a database with the same principle. + +![Diagram with the situationship of the entries](linked.svg) + +Each entry in the database has the following properties: + +- `id`: a unique identifier for every entry +- `branch`: a random name for the excerpt +- `parent`: the random name of the previous excerpt +- `content`: the actual content of the writings +- `username`: the author of the excerpt + +When generating the display page, every entry look up its `parent` property to position itself after that. + +Mhh should rewrite this better bc is super convoluted ahah. diff --git a/requirements.txt b/requirements.txt index 03a5179..dd00c74 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ autopep8==1.6.0 click==8.0.3 colorama==0.4.4 --e git+https://git.xpub.nl/kamo/exquisite-branch.git@ae185baf0c048ac5f9171314ea5e842362b99dcd#egg=exquisite_branch Flask==2.0.2 Flask-Mako==0.4 itsdangerous==2.0.1 diff --git a/setup.py b/setup.py index 3327655..b1104f8 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import find_packages, setup setup( - name='exquisite_branch', + name='exquisite_excerpts', version='1.0.0', packages=find_packages(), include_package_data=True,