2025 call django
parent
5cae3e2542
commit
a9a66fe27e
@ -0,0 +1,4 @@
|
|||||||
|
db/
|
||||||
|
**/__pycache__/
|
||||||
|
media/
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Creature
|
||||||
|
|
||||||
|
admin.site.register(Creature)
|
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CallConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'call'
|
@ -0,0 +1,14 @@
|
|||||||
|
from django.forms import ModelForm
|
||||||
|
from call.models import Creature
|
||||||
|
|
||||||
|
|
||||||
|
class CreatureForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Creature
|
||||||
|
fields = ["image", "caption", "message"]
|
||||||
|
|
||||||
|
class CreatureFormNoImage(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Creature
|
||||||
|
fields = ["caption", "message"]
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-21 07:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Creature',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('image', models.ImageField(upload_to='creatures')),
|
||||||
|
('caption', models.CharField(max_length=255)),
|
||||||
|
('created', models.DateTimeField(auto_now_add=True, verbose_name='date created')),
|
||||||
|
('updated', models.DateTimeField(auto_now=True, verbose_name='date updated')),
|
||||||
|
('message', models.TextField(max_length=512)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-01-21 07:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('call', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='creature',
|
||||||
|
name='message',
|
||||||
|
field=models.TextField(blank=True, max_length=512),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,10 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Creature(models.Model):
|
||||||
|
image = models.ImageField(upload_to="creatures")
|
||||||
|
caption = models.CharField(max_length=255)
|
||||||
|
created = models.DateTimeField("date created", auto_now_add=True)
|
||||||
|
updated = models.DateTimeField("date updated", auto_now=True)
|
||||||
|
message = models.TextField(max_length=512, blank=True)
|
||||||
|
|
@ -0,0 +1,394 @@
|
|||||||
|
var PARTS_MAX = {
|
||||||
|
eyes: 12,
|
||||||
|
mouth: 8,
|
||||||
|
ears: 6,
|
||||||
|
torso: 5,
|
||||||
|
hair: 22,
|
||||||
|
};
|
||||||
|
var gParts = {}
|
||||||
|
var gColor = 0;
|
||||||
|
var gColorMode = '012';
|
||||||
|
|
||||||
|
var showCanvas = document.getElementById('c');
|
||||||
|
|
||||||
|
var outCanvas = document.getElementById('outc');
|
||||||
|
outCanvas.width = 16 * 6;
|
||||||
|
outCanvas.height = 16 * 1;
|
||||||
|
|
||||||
|
|
||||||
|
var ctx = showCanvas.getContext('2d');
|
||||||
|
var outCtx = outCanvas.getContext('2d');
|
||||||
|
|
||||||
|
var outCanvas_gbs_s = document.getElementById("outc_gbs_s")
|
||||||
|
outCanvas_gbs_s.width = 48
|
||||||
|
outCanvas_gbs_s.height = 16
|
||||||
|
|
||||||
|
var outCanvas_gbs_a = document.getElementById("outc_gbs_a")
|
||||||
|
outCanvas_gbs_a.width = 96
|
||||||
|
outCanvas_gbs_a.height = 16
|
||||||
|
|
||||||
|
var outCtx_gbs_s = outCanvas_gbs_s.getContext('2d');
|
||||||
|
var outCtx_gbs_a = outCanvas_gbs_a.getContext('2d');
|
||||||
|
|
||||||
|
var a = function(n) {
|
||||||
|
return n
|
||||||
|
.split(',')
|
||||||
|
.map(function(k){ return { x: parseInt(k), f: !!k.match('f')} });
|
||||||
|
}
|
||||||
|
var ANIMS = {
|
||||||
|
rotate: a("0,2f,1,2"),
|
||||||
|
run_front: a("0,3,0f,3f"),
|
||||||
|
run_back: a("1,4,1f,4f"),
|
||||||
|
run_left: a("2,5"),
|
||||||
|
run_right: a("2f,5f"),
|
||||||
|
}
|
||||||
|
var ANIM_NAMES = Object.keys(ANIMS);
|
||||||
|
var currentAnimName = "run_front";
|
||||||
|
|
||||||
|
var gTextures = { loaded: 0, requested: 0 };
|
||||||
|
|
||||||
|
loadAllTextures();
|
||||||
|
|
||||||
|
var __appstarted = false;
|
||||||
|
function loadTexture(key) {
|
||||||
|
// var tex = new Image();
|
||||||
|
var tex = document.querySelector("#all_imgs").querySelector('#img_'+key);
|
||||||
|
|
||||||
|
// tex.src = "./" + key + ".png?v=" + Math.random();
|
||||||
|
gTextures.requested++;
|
||||||
|
gTextures[key] = tex;
|
||||||
|
|
||||||
|
var tex_onload = function() {
|
||||||
|
gTextures.loaded++;
|
||||||
|
if(gTextures.loaded === gTextures.requested){
|
||||||
|
if(__appstarted){
|
||||||
|
updateOutCanvas();
|
||||||
|
} else {
|
||||||
|
startApp();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.getElementById('loading').innerText =
|
||||||
|
"loading... " + gTextures.loaded + " / " + gTextures.requested;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex.complete) {
|
||||||
|
window.setTimeout(tex_onload, 10);
|
||||||
|
} else {
|
||||||
|
tex.onload = tex_onload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAllTextures() {
|
||||||
|
loadTexture("hair");
|
||||||
|
loadTexture("base");
|
||||||
|
loadTexture("eyes");
|
||||||
|
loadTexture("mouth");
|
||||||
|
loadTexture("ears");
|
||||||
|
loadTexture("torso");
|
||||||
|
loadTexture("hands");
|
||||||
|
}
|
||||||
|
|
||||||
|
function startApp() {
|
||||||
|
__appstarted = true;
|
||||||
|
setupInput("eyes")
|
||||||
|
setupInput("mouth")
|
||||||
|
setupInput("ears")
|
||||||
|
setupInput("torso")
|
||||||
|
setupInput("hair")
|
||||||
|
setupColorInput();
|
||||||
|
setupColorMode();
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
updateAnimBtnText();
|
||||||
|
window.setInterval(animate, 16);
|
||||||
|
|
||||||
|
document.getElementById('loading').innerText = '';
|
||||||
|
document.getElementById('root').className = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate(){
|
||||||
|
ctx.clearRect(0, 0, 16, 16);
|
||||||
|
var t = Date.now ? Date.now() : +(new Date());
|
||||||
|
|
||||||
|
var nt = parseInt(t / 200)
|
||||||
|
var anim = ANIMS[currentAnimName];
|
||||||
|
var len = anim.length;
|
||||||
|
|
||||||
|
var findex = nt % len;
|
||||||
|
var frame = anim[findex];
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
if(frame.f){
|
||||||
|
ctx.translate(16, 0);
|
||||||
|
ctx.scale(-1, 1);
|
||||||
|
}
|
||||||
|
ctx.drawImage(outCanvas, frame.x * 16, 0, 16, 16, 0, 0, 16, 16);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var animbtn = document.getElementById('animbtn');
|
||||||
|
function updateAnimBtnText(){
|
||||||
|
animbtn.innerText = currentAnimName.replace("_", " ");
|
||||||
|
}
|
||||||
|
animbtn.onclick = function() {
|
||||||
|
var index = ANIM_NAMES.indexOf(currentAnimName);
|
||||||
|
currentAnimName = ANIM_NAMES[index + 1] || ANIM_NAMES[0];
|
||||||
|
updateAnimBtnText();
|
||||||
|
}
|
||||||
|
showCanvas.onclick = animbtn.onclick;
|
||||||
|
|
||||||
|
// var randomizebtn = document.getElementById('randomizebtn');
|
||||||
|
// randomizebtn.onclick = function() {
|
||||||
|
// var inputs = document.getElementById('inputs').querySelectorAll('input');
|
||||||
|
|
||||||
|
// for(var i=0; i<inputs.length; i++){
|
||||||
|
// var input = inputs[i];
|
||||||
|
|
||||||
|
// var key = input.id.replace("Input", "");
|
||||||
|
// var max = PARTS_MAX[key];
|
||||||
|
// var randval = Math.floor(Math.random() * (max + 1));
|
||||||
|
// input.value = randval;
|
||||||
|
// gParts[key] = randval;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// updateOutCanvas();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 13 * 9 * 7 * 6 * 23 = 113'022
|
||||||
|
|
||||||
|
var COLORS = [
|
||||||
|
["#000000", "#787878", "#e8e8e8", "#ffffff", "Basic"],
|
||||||
|
["#071821", "#86c06c", "#e0f8cf", "#65ff00", "GBS"],
|
||||||
|
["#7c3f58", "#eb6b6f", "#f9a875", "#fff6d3", "ICE CREAM GB PALETTE by Kerrie Lake"],
|
||||||
|
["#2d1b00", "#1e606e", "#5ab9a8", "#c4f0c2", "MIST GB PALETTE by Kerrie Lake"],
|
||||||
|
["#2c2137", "#764462", "#edb4a1", "#a96868", "RUSTIC GB PALETTE by Kerrie Lake"],
|
||||||
|
["#20283d", "#426e5d", "#e5b083", "#fbf7f3", "EN4 PALETTE by ENDESGA"],
|
||||||
|
["#4c1c2d", "#d23c4e", "#5fb1f5", "#eaf5fa", "GRAND DAD 4 PALETTE by Starlane"],
|
||||||
|
[ "#181010", "#84739c", "#f7b58c", "#ffefff", "POKEMON (SGB) PALETTE" ],
|
||||||
|
[ "#2b2b26", "#706b66", "#a89f94", "#e0dbcd", "GRAFXKID GAMEBOY POCKET (GRAY) PALETTE by GrafxKid" ],
|
||||||
|
[ "#000000", "#ff55ff", "#55ffff", "#ffffff", "CGA PALETTE 1 (HIGH) PALETTE" ],
|
||||||
|
[ "#243137", "#3f503f", "#768448", "#acb56b", "NINTENDO GAMEBOY (ARNE) PALETTE by Arne" ],
|
||||||
|
[ "#260016", "#ed008c", "#00bff3", "#daf3ec", "JB4 PALETTE by Haretro for his game Jet Boy" ],
|
||||||
|
[ "#253b46", "#18865f", "#61d162", "#ebe7ad", "SWEET GUARANÁ PALETTE by MadPezkoh" ],
|
||||||
|
[ "#4c625a", "#7b9278", "#abc396", "#dbf4b4", "GRAFXKID GAMEBOY POCKET (GREEN) PALETTE by GrafxKid" ],
|
||||||
|
];
|
||||||
|
|
||||||
|
function drawPart(key, forceY, forceFrame){
|
||||||
|
var y = gParts[key] == null ? forceY : gParts[key]; // 0's falsy
|
||||||
|
if(y == null){ return }
|
||||||
|
var w = 16 * 6;
|
||||||
|
var h = 16;
|
||||||
|
|
||||||
|
|
||||||
|
if(forceFrame || forceFrame === 0){
|
||||||
|
outCtx.drawImage(gTextures[key], forceFrame*16, y*16, 16, 16, forceFrame*16, 0, 16, 16);
|
||||||
|
} else {
|
||||||
|
outCtx.drawImage(gTextures[key], 0, y*16, w, h, 0, 0, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function GBS_recolor_fn()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
dark: parseColorStr("#071821"),
|
||||||
|
mid: parseColorStr("#86c06c"),
|
||||||
|
light: parseColorStr("#e0f8cf"),
|
||||||
|
bg: parseColorStr("#65ff00"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function GBS_recolor(ctx, w)
|
||||||
|
{
|
||||||
|
var imageData = ctx.getImageData(0, 0, w || 96, 16);
|
||||||
|
recolor(imageData.data, GBS_recolor_fn);
|
||||||
|
ctx.putImageData(imageData,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ff(ctx, src, f, sx, sy, dx)
|
||||||
|
{
|
||||||
|
f && ctx.save();
|
||||||
|
f && ctx.scale(-1, 1);
|
||||||
|
ctx.drawImage(src, 16*sx, sy*16, 16, 16, dx*16, 0, 16, 16);
|
||||||
|
f && ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
var FLIP = true;
|
||||||
|
|
||||||
|
function updateGBS()
|
||||||
|
{
|
||||||
|
ff(outCtx_gbs_s, outCanvas, null, 0, 0, 0);
|
||||||
|
ff(outCtx_gbs_s, outCanvas, null, 1, 0, 1);
|
||||||
|
ff(outCtx_gbs_s, outCanvas, FLIP, 2, 0, -3);
|
||||||
|
|
||||||
|
GBS_recolor(outCtx_gbs_s, 48);
|
||||||
|
|
||||||
|
updateExportLink("export_gbs_static", outCanvas_gbs_s, "_gbs");
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, null, 3, 0, 0)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 3, 0, -2)
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, null, 4, 0, 3)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 4, 0, -3)
|
||||||
|
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 2, 0, -5)
|
||||||
|
ff(outCtx_gbs_a, outCanvas, FLIP, 5, 0, -6)
|
||||||
|
|
||||||
|
GBS_recolor(outCtx_gbs_a, 96);
|
||||||
|
updateExportLink("export_gbs_animated", outCanvas_gbs_a, "_gbs_anim");
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseColorStr(str){
|
||||||
|
return [
|
||||||
|
parseInt(str.substr(1, 2), 16),
|
||||||
|
parseInt(str.substr(3, 2), 16),
|
||||||
|
parseInt(str.substr(5, 2), 16),
|
||||||
|
255
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getColors()
|
||||||
|
{
|
||||||
|
function C(n){
|
||||||
|
return [
|
||||||
|
parseInt(COLORS[gColor][n].substr(1, 2), 16),
|
||||||
|
parseInt(COLORS[gColor][n].substr(3, 2), 16),
|
||||||
|
parseInt(COLORS[gColor][n].substr(5, 2), 16)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
var mode = gColorMode.split('').map(function(n){ return parseInt(n) });
|
||||||
|
var dark = C(mode[0]);
|
||||||
|
var mid = C(mode[1]);
|
||||||
|
var light = C(mode[2]);
|
||||||
|
|
||||||
|
var bg = C(3);
|
||||||
|
|
||||||
|
return { dark:dark, mid:mid, light:light, bg:bg };
|
||||||
|
}
|
||||||
|
|
||||||
|
function recolor(data, getColors)
|
||||||
|
{
|
||||||
|
var tmp = getColors();
|
||||||
|
var put1 = function(i, r, g, b, a) {
|
||||||
|
data[i+0] = r; data[i+1] = g; data[i+2] = b; data[i+3] = a;
|
||||||
|
}
|
||||||
|
for (var i=0; i<data.length; i+=4) {
|
||||||
|
var r = data[i];
|
||||||
|
if(r<50){
|
||||||
|
put1(i, tmp.dark[0], tmp.dark[1], tmp.dark[2], 255);
|
||||||
|
} else if(r<180){
|
||||||
|
put1(i, tmp.mid[0], tmp.mid[1], tmp.mid[2], 255);
|
||||||
|
} else if(r<245){
|
||||||
|
put1(i, tmp.light[0], tmp.light[1], tmp.light[2], 255);
|
||||||
|
} else {
|
||||||
|
put1(i, tmp.bg[0], tmp.bg[1], tmp.bg[2], tmp.bg[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExportLink(id, canvas, suffix)
|
||||||
|
{
|
||||||
|
// it's always a small file so this should be good enough:
|
||||||
|
var str = Object.keys(gParts).sort().map(function(k){
|
||||||
|
return ("00"+gParts[k]).slice(-2);
|
||||||
|
}).join('')
|
||||||
|
var exportlink = document.getElementById(id)
|
||||||
|
exportlink.href = canvas.toDataURL("image/png");
|
||||||
|
exportlink.download = str + suffix + '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOutCanvas() {
|
||||||
|
outCtx.clearRect(0, 0, outCanvas.width, outCanvas.height);
|
||||||
|
|
||||||
|
outCtx.drawImage(gTextures['base'], 0, 0); // base
|
||||||
|
|
||||||
|
drawPart("hair");
|
||||||
|
drawPart("torso");
|
||||||
|
drawPart("ears");
|
||||||
|
drawPart("mouth");
|
||||||
|
drawPart("eyes");
|
||||||
|
drawPart("hands", 0);
|
||||||
|
|
||||||
|
// back of the hair
|
||||||
|
drawPart("hair", null, 4);
|
||||||
|
drawPart("hair", null, 1);
|
||||||
|
|
||||||
|
updateGBS()
|
||||||
|
|
||||||
|
|
||||||
|
var imageData = outCtx.getImageData(0, 0, outCanvas.width, outCanvas.height);
|
||||||
|
var data = imageData.data
|
||||||
|
|
||||||
|
recolor(data, getColors);
|
||||||
|
|
||||||
|
outCtx.putImageData(imageData,0,0);
|
||||||
|
|
||||||
|
updateExportLink("exportlink", outCanvas, "_" + gColor + gColorMode)
|
||||||
|
// // it's always a small file so this should be good enough:
|
||||||
|
// var str = Object.keys(gParts).sort().map(function(k){
|
||||||
|
// return ("00"+gParts[k]).slice(-2);
|
||||||
|
// }).join('') + "_" + gColor + gColorMode;
|
||||||
|
// var exportlink = document.getElementById("exportlink")
|
||||||
|
// exportlink.href = outCanvas.toDataURL("image/png");
|
||||||
|
// exportlink.download = str + '.png';
|
||||||
|
// document.getElementById('serialized_input').value = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefixInputWithASpan(input, text){
|
||||||
|
var span = document.createElement("span");
|
||||||
|
span.innerText = text;
|
||||||
|
input.parentElement.prepend(span);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupInput(key){
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, key)
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', PARTS_MAX[key]);
|
||||||
|
input.value = parseInt(Math.random() * (PARTS_MAX[key] + 1));
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
gParts[key] = parseInt(e.target.value);
|
||||||
|
console.log("INPUT UPDATE", e.target.value, gParts);
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
function setupColorInput() {
|
||||||
|
var key = 'color';
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, 'colors')
|
||||||
|
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', COLORS.length - 1);
|
||||||
|
PARTS_MAX['color'] = COLORS.length;
|
||||||
|
input.value = 0;
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
gColor = parseInt(e.target.value);
|
||||||
|
console.log("COLOR UPDATE", e.target.value, gColor);
|
||||||
|
document.getElementById('colorinfo').innerText = COLORS[gColor][4];
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupColorMode() {
|
||||||
|
var btn = document.getElementById("colormode");
|
||||||
|
|
||||||
|
btn.onclick = function() {
|
||||||
|
if(gColorMode == '012'){ gColorMode = '023' }
|
||||||
|
else if(gColorMode == '023'){ gColorMode = '013' }
|
||||||
|
else if(gColorMode == '013'){ gColorMode = '123' }
|
||||||
|
else { gColorMode = '012' }
|
||||||
|
|
||||||
|
btn.innerText = gColorMode;
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
terms.json: terms.yaml
|
||||||
|
python3 update_terms_yaml_to_json.py $< $@
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,324 @@
|
|||||||
|
{
|
||||||
|
"action": [
|
||||||
|
"researching",
|
||||||
|
"studying",
|
||||||
|
"scanning",
|
||||||
|
"inflitrating",
|
||||||
|
"uploading",
|
||||||
|
"seeding",
|
||||||
|
"screening",
|
||||||
|
"spamming",
|
||||||
|
"tweeting",
|
||||||
|
"tooting",
|
||||||
|
"singing",
|
||||||
|
"feeling",
|
||||||
|
"listening to",
|
||||||
|
"playing",
|
||||||
|
"reading",
|
||||||
|
"disrupting",
|
||||||
|
"acting as",
|
||||||
|
"dancing",
|
||||||
|
"seeing",
|
||||||
|
"cooking",
|
||||||
|
"preaching",
|
||||||
|
"translating",
|
||||||
|
"yelling",
|
||||||
|
"screaming",
|
||||||
|
"running",
|
||||||
|
"whistleblowing",
|
||||||
|
"leaking",
|
||||||
|
"painting",
|
||||||
|
"writing",
|
||||||
|
"laughing at",
|
||||||
|
"dictating",
|
||||||
|
"designing",
|
||||||
|
"destroying",
|
||||||
|
"showing",
|
||||||
|
"debating",
|
||||||
|
"creating",
|
||||||
|
"performing",
|
||||||
|
"building",
|
||||||
|
"hiding",
|
||||||
|
"surveilling",
|
||||||
|
"faking",
|
||||||
|
"banning",
|
||||||
|
"watching",
|
||||||
|
"deciding",
|
||||||
|
"dealing",
|
||||||
|
"exchanging",
|
||||||
|
"mediating",
|
||||||
|
"fighting",
|
||||||
|
"vandalizing",
|
||||||
|
"parodying",
|
||||||
|
"questioning",
|
||||||
|
"criticizing",
|
||||||
|
"provoking",
|
||||||
|
"obscuring",
|
||||||
|
"shouting on",
|
||||||
|
"controlling",
|
||||||
|
"demanding",
|
||||||
|
"delivering",
|
||||||
|
"disclosing",
|
||||||
|
"developing",
|
||||||
|
"divulging",
|
||||||
|
"lying about",
|
||||||
|
"bragging about",
|
||||||
|
"echoing",
|
||||||
|
"portraying",
|
||||||
|
"helping",
|
||||||
|
"hiding",
|
||||||
|
"interrupting",
|
||||||
|
"conspiring",
|
||||||
|
"sending",
|
||||||
|
"repairing",
|
||||||
|
"disagreeing"
|
||||||
|
],
|
||||||
|
"actor": [
|
||||||
|
"hipster",
|
||||||
|
"scener",
|
||||||
|
"seeder",
|
||||||
|
"leecher",
|
||||||
|
"pirate",
|
||||||
|
"librarian",
|
||||||
|
"virus",
|
||||||
|
"AI",
|
||||||
|
"wizard",
|
||||||
|
"quant",
|
||||||
|
"CEO",
|
||||||
|
"shareholder",
|
||||||
|
"user",
|
||||||
|
"stenographer",
|
||||||
|
"maker",
|
||||||
|
"artist",
|
||||||
|
"professional",
|
||||||
|
"hobbyist",
|
||||||
|
"amateur",
|
||||||
|
"teacher",
|
||||||
|
"student",
|
||||||
|
"doctor",
|
||||||
|
"patient",
|
||||||
|
"public",
|
||||||
|
"criminal",
|
||||||
|
"cook",
|
||||||
|
"editor",
|
||||||
|
"programmer",
|
||||||
|
"preacher",
|
||||||
|
"livecoder",
|
||||||
|
"individual",
|
||||||
|
"visitor",
|
||||||
|
"hacker",
|
||||||
|
"reader",
|
||||||
|
"consumer",
|
||||||
|
"mediator",
|
||||||
|
"actor",
|
||||||
|
"builder",
|
||||||
|
"child",
|
||||||
|
"adult",
|
||||||
|
"architect",
|
||||||
|
"tourist",
|
||||||
|
"person",
|
||||||
|
"parent",
|
||||||
|
"photographer",
|
||||||
|
"musician",
|
||||||
|
"designer",
|
||||||
|
"chatbot",
|
||||||
|
"regulator",
|
||||||
|
"dancer",
|
||||||
|
"developer",
|
||||||
|
"author",
|
||||||
|
"robot",
|
||||||
|
"dog",
|
||||||
|
"cat",
|
||||||
|
"judge",
|
||||||
|
"celebrity",
|
||||||
|
"computer",
|
||||||
|
"politician",
|
||||||
|
"president",
|
||||||
|
"manager",
|
||||||
|
"entrepreneur",
|
||||||
|
"whistleblower",
|
||||||
|
"infiltrator",
|
||||||
|
"book binder",
|
||||||
|
"collective"
|
||||||
|
],
|
||||||
|
"media": [
|
||||||
|
"image boards",
|
||||||
|
"forums",
|
||||||
|
"warez",
|
||||||
|
"screens",
|
||||||
|
"galleries",
|
||||||
|
"screensavers",
|
||||||
|
"viruses",
|
||||||
|
"frequencies",
|
||||||
|
"files",
|
||||||
|
"operating systems",
|
||||||
|
"databases",
|
||||||
|
"privacy",
|
||||||
|
"posters",
|
||||||
|
"cybernetics",
|
||||||
|
"floppy disks",
|
||||||
|
"CD-ROMs",
|
||||||
|
"LaserDiscs",
|
||||||
|
"apps",
|
||||||
|
"spam",
|
||||||
|
"startups",
|
||||||
|
"manuscripts",
|
||||||
|
"carpets",
|
||||||
|
"markets",
|
||||||
|
"architectures",
|
||||||
|
"feels",
|
||||||
|
"books",
|
||||||
|
"games",
|
||||||
|
"radio",
|
||||||
|
"music",
|
||||||
|
"graffitis",
|
||||||
|
"blogs",
|
||||||
|
"theatre",
|
||||||
|
"woodblocks",
|
||||||
|
"dances",
|
||||||
|
"recycling",
|
||||||
|
"emails",
|
||||||
|
"food",
|
||||||
|
"migration",
|
||||||
|
"magazines",
|
||||||
|
"maps",
|
||||||
|
"comics",
|
||||||
|
"finance",
|
||||||
|
"teaching",
|
||||||
|
"memes",
|
||||||
|
"futures",
|
||||||
|
"traditions",
|
||||||
|
"corruption",
|
||||||
|
"regulation",
|
||||||
|
"porn",
|
||||||
|
"webpages",
|
||||||
|
"vandalism",
|
||||||
|
"samizdat",
|
||||||
|
"ethics",
|
||||||
|
"billboards",
|
||||||
|
"advertising",
|
||||||
|
"manifestos",
|
||||||
|
"leaflets",
|
||||||
|
"browsers",
|
||||||
|
"wikis",
|
||||||
|
"canvases",
|
||||||
|
"tapes",
|
||||||
|
"vinyls",
|
||||||
|
"records",
|
||||||
|
"synthesizers",
|
||||||
|
"feeds",
|
||||||
|
"newspapers",
|
||||||
|
"HTML pages",
|
||||||
|
"codex",
|
||||||
|
"software",
|
||||||
|
"codes of conduct",
|
||||||
|
"epubs",
|
||||||
|
"PDFs",
|
||||||
|
"NFTs",
|
||||||
|
"stories",
|
||||||
|
"dictionaries",
|
||||||
|
"libraries",
|
||||||
|
"bugs",
|
||||||
|
"disagreements"
|
||||||
|
],
|
||||||
|
"prefix": [
|
||||||
|
"proto",
|
||||||
|
"xeno",
|
||||||
|
"cyber",
|
||||||
|
"retro",
|
||||||
|
"pre",
|
||||||
|
"ante",
|
||||||
|
"proto",
|
||||||
|
"post",
|
||||||
|
"avant",
|
||||||
|
"neo",
|
||||||
|
"anti",
|
||||||
|
"co",
|
||||||
|
"epi",
|
||||||
|
"ex",
|
||||||
|
"extra",
|
||||||
|
"hyper",
|
||||||
|
"infra",
|
||||||
|
"inter",
|
||||||
|
"macro",
|
||||||
|
"micro",
|
||||||
|
"mid",
|
||||||
|
"mono",
|
||||||
|
"non",
|
||||||
|
"multi",
|
||||||
|
"omni",
|
||||||
|
"semi",
|
||||||
|
"sub",
|
||||||
|
"super",
|
||||||
|
"trans",
|
||||||
|
"cross",
|
||||||
|
"uni",
|
||||||
|
"minor"
|
||||||
|
],
|
||||||
|
"sort": [
|
||||||
|
"bootleg",
|
||||||
|
"capitalist",
|
||||||
|
"progressive",
|
||||||
|
"organic",
|
||||||
|
"industrial",
|
||||||
|
"homemade",
|
||||||
|
"craft",
|
||||||
|
"AI",
|
||||||
|
"encrypted",
|
||||||
|
"inclusive",
|
||||||
|
"fair",
|
||||||
|
"transparent",
|
||||||
|
"command line",
|
||||||
|
"granular",
|
||||||
|
"crypto",
|
||||||
|
"centralised",
|
||||||
|
"free",
|
||||||
|
"libre",
|
||||||
|
"open",
|
||||||
|
"proprietary",
|
||||||
|
"DIY",
|
||||||
|
"DIWO",
|
||||||
|
"homebrew",
|
||||||
|
"decentralised",
|
||||||
|
"closed source",
|
||||||
|
"binary",
|
||||||
|
"plaintext",
|
||||||
|
"federated",
|
||||||
|
"distributed",
|
||||||
|
"online",
|
||||||
|
"offline",
|
||||||
|
"raw",
|
||||||
|
"compressed",
|
||||||
|
"deep",
|
||||||
|
"dark",
|
||||||
|
"common",
|
||||||
|
"shared",
|
||||||
|
"liberal",
|
||||||
|
"anarcho-capitalist",
|
||||||
|
"anarcho-communist",
|
||||||
|
"anarcho-syndicalist",
|
||||||
|
"authoritarian",
|
||||||
|
"capitalist",
|
||||||
|
"communist",
|
||||||
|
"marxist",
|
||||||
|
"apolitical",
|
||||||
|
"syndicated",
|
||||||
|
"digital",
|
||||||
|
"analog",
|
||||||
|
"bottom-up",
|
||||||
|
"top-down",
|
||||||
|
"horizontal",
|
||||||
|
"vertical",
|
||||||
|
"agonistic",
|
||||||
|
"version-controlled",
|
||||||
|
"feminist",
|
||||||
|
"decolonial",
|
||||||
|
"contradictory",
|
||||||
|
"occasional",
|
||||||
|
"layered",
|
||||||
|
"entangled",
|
||||||
|
"collective",
|
||||||
|
"complex",
|
||||||
|
"artificial"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,317 @@
|
|||||||
|
action:
|
||||||
|
- researching
|
||||||
|
- studying
|
||||||
|
- scanning
|
||||||
|
- inflitrating
|
||||||
|
- uploading
|
||||||
|
- seeding
|
||||||
|
- screening
|
||||||
|
- spamming
|
||||||
|
- tweeting
|
||||||
|
- tooting
|
||||||
|
- singing
|
||||||
|
- feeling
|
||||||
|
- listening to
|
||||||
|
- playing
|
||||||
|
- reading
|
||||||
|
- disrupting
|
||||||
|
- acting as
|
||||||
|
- dancing
|
||||||
|
- seeing
|
||||||
|
- cooking
|
||||||
|
- preaching
|
||||||
|
- translating
|
||||||
|
- yelling
|
||||||
|
- screaming
|
||||||
|
- running
|
||||||
|
- whistleblowing
|
||||||
|
- leaking
|
||||||
|
- painting
|
||||||
|
- writing
|
||||||
|
- laughing at
|
||||||
|
- dictating
|
||||||
|
- designing
|
||||||
|
- destroying
|
||||||
|
- showing
|
||||||
|
- debating
|
||||||
|
- creating
|
||||||
|
- performing
|
||||||
|
- building
|
||||||
|
- hiding
|
||||||
|
- surveilling
|
||||||
|
- faking
|
||||||
|
- banning
|
||||||
|
- watching
|
||||||
|
- deciding
|
||||||
|
- dealing
|
||||||
|
- exchanging
|
||||||
|
- mediating
|
||||||
|
- fighting
|
||||||
|
- vandalizing
|
||||||
|
- parodying
|
||||||
|
- questioning
|
||||||
|
- criticizing
|
||||||
|
- provoking
|
||||||
|
- obscuring
|
||||||
|
- shouting on
|
||||||
|
- controlling
|
||||||
|
- demanding
|
||||||
|
- delivering
|
||||||
|
- disclosing
|
||||||
|
- developing
|
||||||
|
- divulging
|
||||||
|
- lying about
|
||||||
|
- bragging about
|
||||||
|
- echoing
|
||||||
|
- portraying
|
||||||
|
- helping
|
||||||
|
- hiding
|
||||||
|
- interrupting
|
||||||
|
- conspiring
|
||||||
|
- sending
|
||||||
|
- repairing
|
||||||
|
- disagreeing
|
||||||
|
actor:
|
||||||
|
- hipster
|
||||||
|
- scener
|
||||||
|
- seeder
|
||||||
|
- leecher
|
||||||
|
- pirate
|
||||||
|
- librarian
|
||||||
|
- virus
|
||||||
|
- AI
|
||||||
|
- wizard
|
||||||
|
- quant
|
||||||
|
- CEO
|
||||||
|
- shareholder
|
||||||
|
- user
|
||||||
|
- stenographer
|
||||||
|
- maker
|
||||||
|
- artist
|
||||||
|
- professional
|
||||||
|
- hobbyist
|
||||||
|
- amateur
|
||||||
|
- teacher
|
||||||
|
- student
|
||||||
|
- doctor
|
||||||
|
- patient
|
||||||
|
- public
|
||||||
|
- criminal
|
||||||
|
- cook
|
||||||
|
- editor
|
||||||
|
- programmer
|
||||||
|
- preacher
|
||||||
|
- livecoder
|
||||||
|
- individual
|
||||||
|
- visitor
|
||||||
|
- hacker
|
||||||
|
- reader
|
||||||
|
- consumer
|
||||||
|
- mediator
|
||||||
|
- actor
|
||||||
|
- builder
|
||||||
|
- child
|
||||||
|
- adult
|
||||||
|
- architect
|
||||||
|
- tourist
|
||||||
|
- person
|
||||||
|
- parent
|
||||||
|
- photographer
|
||||||
|
- musician
|
||||||
|
- designer
|
||||||
|
- chatbot
|
||||||
|
- regulator
|
||||||
|
- dancer
|
||||||
|
- developer
|
||||||
|
- author
|
||||||
|
- robot
|
||||||
|
- dog
|
||||||
|
- cat
|
||||||
|
- judge
|
||||||
|
- celebrity
|
||||||
|
- computer
|
||||||
|
- politician
|
||||||
|
- president
|
||||||
|
- manager
|
||||||
|
- entrepreneur
|
||||||
|
- whistleblower
|
||||||
|
- infiltrator
|
||||||
|
- book binder
|
||||||
|
- collective
|
||||||
|
media:
|
||||||
|
- image boards
|
||||||
|
- forums
|
||||||
|
- warez
|
||||||
|
- screens
|
||||||
|
- galleries
|
||||||
|
- screensavers
|
||||||
|
- viruses
|
||||||
|
- frequencies
|
||||||
|
- files
|
||||||
|
- operating systems
|
||||||
|
- databases
|
||||||
|
- privacy
|
||||||
|
- posters
|
||||||
|
- cybernetics
|
||||||
|
- floppy disks
|
||||||
|
- CD-ROMs
|
||||||
|
- LaserDiscs
|
||||||
|
- apps
|
||||||
|
- spam
|
||||||
|
- startups
|
||||||
|
- manuscripts
|
||||||
|
- carpets
|
||||||
|
- markets
|
||||||
|
- architectures
|
||||||
|
- feels
|
||||||
|
- books
|
||||||
|
- games
|
||||||
|
- radio
|
||||||
|
- music
|
||||||
|
- graffitis
|
||||||
|
- blogs
|
||||||
|
- theatre
|
||||||
|
- woodblocks
|
||||||
|
- dances
|
||||||
|
- recycling
|
||||||
|
- emails
|
||||||
|
- food
|
||||||
|
- migration
|
||||||
|
- magazines
|
||||||
|
- maps
|
||||||
|
- comics
|
||||||
|
- finance
|
||||||
|
- teaching
|
||||||
|
- memes
|
||||||
|
- futures
|
||||||
|
- traditions
|
||||||
|
- corruption
|
||||||
|
- regulation
|
||||||
|
- porn
|
||||||
|
- webpages
|
||||||
|
- vandalism
|
||||||
|
- samizdat
|
||||||
|
- ethics
|
||||||
|
- billboards
|
||||||
|
- advertising
|
||||||
|
- manifestos
|
||||||
|
- leaflets
|
||||||
|
- browsers
|
||||||
|
- wikis
|
||||||
|
- canvases
|
||||||
|
- tapes
|
||||||
|
- vinyls
|
||||||
|
- records
|
||||||
|
- synthesizers
|
||||||
|
- feeds
|
||||||
|
- newspapers
|
||||||
|
- HTML pages
|
||||||
|
- codex
|
||||||
|
- software
|
||||||
|
- codes of conduct
|
||||||
|
- epubs
|
||||||
|
- PDFs
|
||||||
|
- NFTs
|
||||||
|
- stories
|
||||||
|
- dictionaries
|
||||||
|
- libraries
|
||||||
|
- bugs
|
||||||
|
- disagreements
|
||||||
|
prefix:
|
||||||
|
- proto
|
||||||
|
- xeno
|
||||||
|
- cyber
|
||||||
|
- retro
|
||||||
|
- pre
|
||||||
|
- ante
|
||||||
|
- proto
|
||||||
|
- post
|
||||||
|
- avant
|
||||||
|
- neo
|
||||||
|
- anti
|
||||||
|
- co
|
||||||
|
- epi
|
||||||
|
- ex
|
||||||
|
- extra
|
||||||
|
- hyper
|
||||||
|
- infra
|
||||||
|
- inter
|
||||||
|
- macro
|
||||||
|
- micro
|
||||||
|
- mid
|
||||||
|
- mono
|
||||||
|
- non
|
||||||
|
- multi
|
||||||
|
- omni
|
||||||
|
- semi
|
||||||
|
- sub
|
||||||
|
- super
|
||||||
|
- trans
|
||||||
|
- cross
|
||||||
|
- uni
|
||||||
|
- minor
|
||||||
|
sort:
|
||||||
|
- bootleg
|
||||||
|
- capitalist
|
||||||
|
- progressive
|
||||||
|
- organic
|
||||||
|
- industrial
|
||||||
|
- homemade
|
||||||
|
- craft
|
||||||
|
- AI
|
||||||
|
- encrypted
|
||||||
|
- inclusive
|
||||||
|
- fair
|
||||||
|
- transparent
|
||||||
|
- command line
|
||||||
|
- granular
|
||||||
|
- crypto
|
||||||
|
- centralised
|
||||||
|
- free
|
||||||
|
- libre
|
||||||
|
- open
|
||||||
|
- proprietary
|
||||||
|
- DIY
|
||||||
|
- DIWO
|
||||||
|
- homebrew
|
||||||
|
- decentralised
|
||||||
|
- closed source
|
||||||
|
- binary
|
||||||
|
- plaintext
|
||||||
|
- federated
|
||||||
|
- distributed
|
||||||
|
- online
|
||||||
|
- offline
|
||||||
|
- raw
|
||||||
|
- compressed
|
||||||
|
- deep
|
||||||
|
- dark
|
||||||
|
- common
|
||||||
|
- shared
|
||||||
|
- liberal
|
||||||
|
- anarcho-capitalist
|
||||||
|
- anarcho-communist
|
||||||
|
- anarcho-syndicalist
|
||||||
|
- authoritarian
|
||||||
|
- capitalist
|
||||||
|
- communist
|
||||||
|
- marxist
|
||||||
|
- apolitical
|
||||||
|
- syndicated
|
||||||
|
- digital
|
||||||
|
- analog
|
||||||
|
- bottom-up
|
||||||
|
- top-down
|
||||||
|
- horizontal
|
||||||
|
- vertical
|
||||||
|
- agonistic
|
||||||
|
- version-controlled
|
||||||
|
- feminist
|
||||||
|
- decolonial
|
||||||
|
- contradictory
|
||||||
|
- occasional
|
||||||
|
- layered
|
||||||
|
- entangled
|
||||||
|
- collective
|
||||||
|
- complex
|
||||||
|
- artificial
|
@ -0,0 +1,16 @@
|
|||||||
|
import click
|
||||||
|
import yaml
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.argument('input', type=click.File('r'))
|
||||||
|
@click.argument('output', type=click.File('w'))
|
||||||
|
@click.argument('indent', type=int, default=2)
|
||||||
|
def yaml_to_json(input, output, indent):
|
||||||
|
"""Convert a YAML input to JSON output"""
|
||||||
|
d = yaml.safe_load(input)
|
||||||
|
json.dump(d, output, indent=indent)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
yaml_to_json()
|
@ -0,0 +1,102 @@
|
|||||||
|
// function prefixInputWithASpan(input, text){
|
||||||
|
// var span = document.createElement("span");
|
||||||
|
// span.innerText = text;
|
||||||
|
// input.parentElement.prepend(span);
|
||||||
|
// }
|
||||||
|
|
||||||
|
let terms;
|
||||||
|
let cParts = {};
|
||||||
|
|
||||||
|
function setupTextInput(key){
|
||||||
|
var input = document.getElementById(key + "Input");
|
||||||
|
prefixInputWithASpan(input, key)
|
||||||
|
input.setAttribute('min', 0);
|
||||||
|
input.setAttribute('max', terms[key].length - 1);
|
||||||
|
input.value = parseInt(Math.random() * (terms[key].length + 1));
|
||||||
|
var inputUpdate = function(e){
|
||||||
|
// gParts[key] = parseInt(e.target.value);
|
||||||
|
// console.log("INPUT UPDATE", e.target.value, gParts);
|
||||||
|
// updateOutCanvas();
|
||||||
|
console.log("INPUT UPDATE", e.target.value);
|
||||||
|
cParts[key] = parseInt(e.target.value);
|
||||||
|
updateCaption();
|
||||||
|
}
|
||||||
|
inputUpdate({ target: input });
|
||||||
|
input.onchange = inputUpdate;
|
||||||
|
input.oninput = inputUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
let grammar = ["actor", "action", "prefix", "sort", "media"];
|
||||||
|
function updateCaption () {
|
||||||
|
let caption = "";
|
||||||
|
grammar.forEach(key => {
|
||||||
|
caption += (caption ? " " : "") + terms[key][cParts[key]];
|
||||||
|
})
|
||||||
|
document.querySelector("#caption").innerHTML = caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start () {
|
||||||
|
const src = document.querySelector("a#terms-data-source").href;
|
||||||
|
terms = await (await fetch(src)).json();
|
||||||
|
console.log("terms", terms);
|
||||||
|
setupTextInput("action");
|
||||||
|
setupTextInput("actor");
|
||||||
|
setupTextInput("media");
|
||||||
|
setupTextInput("prefix");
|
||||||
|
setupTextInput("sort");
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomizebtn = document.getElementById('randomizebtn');
|
||||||
|
randomizebtn.onclick = function() {
|
||||||
|
let inputs = document.getElementById('inputs').querySelectorAll('input.g');
|
||||||
|
|
||||||
|
for(var i=0; i<inputs.length; i++){
|
||||||
|
var input = inputs[i];
|
||||||
|
var key = input.id.replace("Input", "");
|
||||||
|
var max = PARTS_MAX[key];
|
||||||
|
var randval = Math.floor(Math.random() * (max + 1));
|
||||||
|
input.value = randval;
|
||||||
|
gParts[key] = randval;
|
||||||
|
if (key == 'color') {
|
||||||
|
// gColor = randval;
|
||||||
|
input.dispatchEvent(new Event('input', { 'bubbles': true }));
|
||||||
|
}
|
||||||
|
console.log("randomizing", input, randval);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOutCanvas();
|
||||||
|
|
||||||
|
inputs = document.getElementById('inputs').querySelectorAll('input.c');
|
||||||
|
for(var i=0; i<inputs.length; i++){
|
||||||
|
var input = inputs[i];
|
||||||
|
var key = input.id.replace("Input", "");
|
||||||
|
var max = terms[key].length;
|
||||||
|
var randval = Math.floor(Math.random() * (max + 0));
|
||||||
|
input.value = randval;
|
||||||
|
cParts[key] = randval;
|
||||||
|
}
|
||||||
|
updateCaption();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
|
function send (canvas, form) {
|
||||||
|
canvas.toBlob(blob => {
|
||||||
|
if (blob) {
|
||||||
|
const formdata = new FormData();
|
||||||
|
const filename = new Date().toISOString() + ".png";
|
||||||
|
formdata.append("image", blob, filename);
|
||||||
|
formdata.append("caption", document.querySelector("#caption").textContent);
|
||||||
|
formdata.append("message", form.message.value);
|
||||||
|
formdata.append("csrfmiddlewaretoken", form.csrfmiddlewaretoken.value);
|
||||||
|
fetch(form.action, { method:"POST", body: formdata });
|
||||||
|
}
|
||||||
|
}, "image/png");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector("button#send").addEventListener("click", () => {
|
||||||
|
console.log("SEND");
|
||||||
|
const form = document.querySelector("form");
|
||||||
|
send(outCanvas, form);
|
||||||
|
})
|
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||||
|
<title>{% block title %}xpub call 2025{% endblock %}</title>
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{%block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,19 @@
|
|||||||
|
{% load static %}
|
||||||
|
<!doctype html>
|
||||||
|
<html lang=en>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||||
|
<title>xpub call 2025</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<img src="{{creature.image.url}}">
|
||||||
|
<p>{{creature.caption}}</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,6 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<img src="{{object.image.url}}">
|
||||||
|
<p>{{object.caption}}</p>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,30 @@
|
|||||||
|
{% extends "call/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Creatures</h2>
|
||||||
|
<ul>
|
||||||
|
{% for creature in page_obj %}
|
||||||
|
<li><a href="{% url 'creature_detail' creature.id %}">{{ creature.caption }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="pagination">
|
||||||
|
<span class="step-links">
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<a href="?page=1">« first</a>
|
||||||
|
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<span class="current">
|
||||||
|
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<a href="?page={{ page_obj.next_page_number }}">next</a>
|
||||||
|
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
@ -0,0 +1,27 @@
|
|||||||
|
"""
|
||||||
|
URL configuration for call2025 project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from call import views
|
||||||
|
from .views import CreatureIndex, CreatureDetail
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("creatures/", CreatureIndex.as_view(), name="creature_list"),
|
||||||
|
path("creatures/<int:pk>/", CreatureDetail.as_view(), name="creature_detail"),
|
||||||
|
path('', views.index)
|
||||||
|
]
|
@ -0,0 +1,29 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
from call.forms import CreatureForm
|
||||||
|
from django.views import generic
|
||||||
|
from .models import Creature
|
||||||
|
|
||||||
|
# Create your views here.
|
||||||
|
def index(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
print ("post", request.POST)
|
||||||
|
print ("files", request.FILES)
|
||||||
|
form = CreatureForm(request.POST, request.FILES)
|
||||||
|
# form = CreatureFormNo(request.POST, request.FILES)
|
||||||
|
# formset = AuthorFormSet(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
print ("FORM IS VALID")
|
||||||
|
form.save()
|
||||||
|
# do something.
|
||||||
|
else:
|
||||||
|
print ("FORM NOT VALID")
|
||||||
|
else:
|
||||||
|
form = CreatureForm()
|
||||||
|
return render(request, "call/index.html", {"form": form})
|
||||||
|
|
||||||
|
class CreatureIndex(generic.ListView):
|
||||||
|
paginate_by = 20
|
||||||
|
model=Creature
|
||||||
|
|
||||||
|
class CreatureDetail(generic.DetailView):
|
||||||
|
model = Creature
|
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
ASGI config for call2025 project.
|
||||||
|
|
||||||
|
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
@ -0,0 +1,127 @@
|
|||||||
|
"""
|
||||||
|
Django settings for call2025 project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 5.1.5.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = 'django-insecure-nn7mvrgu6de^%z&6t1usgaji_*59z*v+230tluec-h4fw*n(%i'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'call',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'call2025.urls'
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'call2025.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': BASE_DIR / 'db' / 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/5.1/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/5.1/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = 'static/'
|
||||||
|
|
||||||
|
# Default primary key field type
|
||||||
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
MEDIA_ROOT = 'media/'
|
||||||
|
MEDIA_URL = 'media/'
|
@ -0,0 +1,26 @@
|
|||||||
|
"""
|
||||||
|
URL configuration for call2025 project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/5.1/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('', include('call.urls'))
|
||||||
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
WSGI config for call2025 project.
|
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run administrative tasks."""
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'call2025.settings')
|
||||||
|
try:
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError(
|
||||||
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
|
"forget to activate a virtual environment?"
|
||||||
|
) from exc
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue