commit 31f801f706405d717c0d6ab7f6637e9794b413ab Author: boyska Date: Wed Jan 1 20:46:23 2025 +0100 copia da https://0xacab.org/hackit/sito-hackit-24 diff --git a/.agignore b/.agignore new file mode 100644 index 0000000..9a74aa5 --- /dev/null +++ b/.agignore @@ -0,0 +1,4 @@ +*/*.min.css +*/*.min.js +themes/*/static/*/*.min.* +output diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2011cfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +output +output/* +.*.sw. +cache +*.pid +*.pyc +.*.swp +public/ +/*.ics diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..22f09ec --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,61 @@ +stages: + - build + - deploy + +variables: + GIT_SUBMODULE_STRATEGY: recursive + +build: + stage: build + image: python:alpine3.18 + script: + - apk add build-base python3-dev + - pip3 install -r requirements.txt + - pelican --version + - env TZ=Europe/Rome pelican ./content/ --ignore-cache -o public/ -s publishconf.py -v + - echo -e "commit=${CI_COMMIT_SHA}\nbuildDate=$(date -Iseconds)\n" > public/buildinfo.txt + - find public -type f + artifacts: + paths: + - public + + + +.deploys: + needs: ["build"] + variables: + GIT_STRATEGY: none + stage: deploy + + + +deploy-testing: + extends: .deploys + image: amd64/debian:bullseye + before_script: + - mkdir -p ~/.ssh + - apt-get update -qq && apt-get install -y -qq rsync openssh-client + - cp ${TESTDEPLOY_SSH_PRIVATE_KEY} ~/.ssh/id_ed25519 + - chmod 600 ~/.ssh/id_ed25519 + script: + - rsync -avz -e "ssh -o StrictHostKeyChecking=no -p ${TESTDEPLOY_PORT} -i ~/.ssh/id_ed25519" public/ ${TESTDEPLOY_USERNAME}@"${TESTDEPLOY_SERVER}":${TESTDEPLOY_PATH}${CI_COMMIT_BRANCH:-} + + + +# deploy-production: +# extends: .deploys +# only: +# - master +# image: tubia/webdav-upload +# script: +# - webdav-upload --verbose --user="$WEBDAV_USER" --password="$WEBDAV_PASSWORD" --url "${WEBDAV_HOST}/${WEBDAV_USER}/" public $WEBDAV_HOST_FOLDER + +deploy-production: + extends: .deploys + only: + - master + image: + name: rclone/rclone:latest + entrypoint: [""] + script: + - "rclone sync -P -v -u --webdav-url ${WEBDAV_HOST}/${WEBDAV_USER}/ --webdav-user ${WEBDAV_USER} --webdav-pass $(echo -n \"${WEBDAV_PASSWORD}\" | rclone obscure -) ./public/ :webdav:${WEBDAV_HOST_FOLDER}/" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5cf5443 --- /dev/null +++ b/Makefile @@ -0,0 +1,74 @@ +PY?=python +PELICAN?=pelican +PELICANOPTS= + +BASEDIR=$(CURDIR) +INPUTDIR=$(BASEDIR)/content +OUTPUTDIR=$(BASEDIR)/output +CONFFILE=$(BASEDIR)/pelicanconf.py +PUBLISHCONF=$(BASEDIR)/publishconf.py + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + PELICANOPTS += -D +endif +VERBOSE ?= 0 +ifeq ($(VERBOSE), 1) + PELICANOPTS += -v +endif + +all: publish + +help: + @echo 'Makefile for a pelican Web site ' + @echo ' ' + @echo 'Usage: ' + @echo ' make html (re)generate the web site ' + @echo ' make clean remove the generated files ' + @echo ' make regenerate regenerate files upon modification ' + @echo ' make publish generate using production settings ' + @echo ' make serve [PORT=8000] serve site at http://localhost:8000' + @echo ' make devserver [PORT=8000] start/restart develop_server.sh ' + @echo ' make stopserver stop local server ' + @echo ' ' + @echo 'Set the VERBOSE variable to 1 for some more messages, e.g. make VERBOSE=1 html' + @echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html' + @echo ' ' + +html: + $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) + +clean: + [ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR) + +regenerate: + $(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) + +serve: +ifdef PORT + @echo http://localhost:$(PORT)/ + pelican --ignore-cache -lr -p $(PORT) +else + @echo http://localhost:8000/ + pelican --ignore-cache -lr +endif + +devserver: +ifdef PORT + $(BASEDIR)/develop_server.sh restart $(PORT) +else + $(BASEDIR)/develop_server.sh restart +endif + +stopserver: + kill -9 `cat pelican.pid` + kill -9 `cat srv.pid` + @echo 'Stopped Pelican and SimpleHTTPServer processes running in background.' + +publish: + $(PELICAN) $(INPUTDIR) --ignore-cache -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS) + +autopublish: + while true; do inotifywait -r content pelicanconf.py publishconf.py Makefile themes -e modify -e create -e delete; make clean publish; sleep 0.1; done + +.PHONY: html help clean regenerate serve devserver publish diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c5eeb2 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +Hackmeeting 2025 +================== + +Sources for Italian Hackmeeting 0x1C (2025) website. + +Il sito viene gestito - in massima parte - dalla commissione comunicazione di hackmeeting. Se vuoi metterti in +contatto con loro, scrivi nella [mailing list](https://hackmeeting.org/hackit24/contact.html) per coordinarti +con loro. Se vuoi provare lo stesso a metterci le mani, fai pure... noi ti abbiamo avvertito! + +Schema di massima +-------------------- + +Questo repository git viene automaticamente "sincronizzato" (continous deployment) e il risultato va a finire +su https://hackmeeting.org/hackit25/ + +Per fare modifiche al sito: + + - fatti un account personale su git.lattuga.net + - fai una modifica al sito + - apri una pull request + - quando la pull request viene approvata, e il tutto finisce in "master", la modifica è online + + +HowTo +------- + +So you want to contribute, nice! You'll need a UNIX (Linux, BSD...) system and some proficiency with the terminal and with +[Git-based workflows](https://git-scm.com/book/en/v2). + +### Setup your development environment + +Clona questo repository sul tuo computer + +Installa mkvirtualenv (`apt install virtualenvwrapper`, su sistemi Debian-based) + +``` +mkvirtualenv -p `which python3` hackmeeting-website +pip install -r requirements.txt +make all serve +firefox http://localhost:8000/ +``` + +Also, `make help` is your friend. + +For debug, `make DEBUG=1` + +### Change content + +Most content is in `content/pages/`. Just go there, find the relevant file, change it. + +Now, `make all serve`, see the result in your browser + +repeat until you like it + +### Commit and push + +usual git workflow + +Griglia dei seminari +---------------------- + +I talk compaiono in questo repository come cartelle all'interno della cartella `talks/`. Tuttavia, la cosa +corretta da fare **NON** è modificare i contenuti direttamente lì, ma modificare un calendario nextcloud da cui +queste informazioni provengono. +Infatti il calendario viene gestito dalla commissione griglia: [coordinati con +loro](https://hackmeeting.org/hackit24/contact.html) se vuoi toccare questa parte del sito. + +Altre modifiche al sito +------------------------- + +Il sito è un'istanza di [pelican](https://docs.getpelican.com/en/latest/), più alcuni plugin custom: + - `langmenu`, per avere un menu che punta alle versioni localizzate della pagina + - `talks`, per gestire i talk in modo "speciale" per hackmeeting + +Puoi quindi riferirti alla documentazione di pelican per fare delle prove e capire come modificare il sito. diff --git a/content/images/.keepme b/content/images/.keepme new file mode 100644 index 0000000..e69de29 diff --git a/content/images/locandina24_color2_stampa.png b/content/images/locandina24_color2_stampa.png new file mode 100644 index 0000000..e8fd806 Binary files /dev/null and b/content/images/locandina24_color2_stampa.png differ diff --git a/content/images/locandina24_color2_web.jpg b/content/images/locandina24_color2_web.jpg new file mode 100644 index 0000000..e61a7a1 Binary files /dev/null and b/content/images/locandina24_color2_web.jpg differ diff --git a/content/images/locandina24_color_stampa.png b/content/images/locandina24_color_stampa.png new file mode 100644 index 0000000..46144bd Binary files /dev/null and b/content/images/locandina24_color_stampa.png differ diff --git a/content/images/locandina24_color_web.jpg b/content/images/locandina24_color_web.jpg new file mode 100644 index 0000000..3349f15 Binary files /dev/null and b/content/images/locandina24_color_web.jpg differ diff --git a/content/images/locandina24_stampa.jpg b/content/images/locandina24_stampa.jpg new file mode 100644 index 0000000..150dc4c Binary files /dev/null and b/content/images/locandina24_stampa.jpg differ diff --git a/content/images/locandina24_web.jpg b/content/images/locandina24_web.jpg new file mode 100644 index 0000000..822ca06 Binary files /dev/null and b/content/images/locandina24_web.jpg differ diff --git a/content/images/logo_color2_hires.png b/content/images/logo_color2_hires.png new file mode 100644 index 0000000..5046005 Binary files /dev/null and b/content/images/logo_color2_hires.png differ diff --git a/content/images/logo_color_hires.png b/content/images/logo_color_hires.png new file mode 100644 index 0000000..aeb5018 Binary files /dev/null and b/content/images/logo_color_hires.png differ diff --git a/content/images/logo_hires.png b/content/images/logo_hires.png new file mode 100644 index 0000000..ef656e5 Binary files /dev/null and b/content/images/logo_hires.png differ diff --git a/content/images/map.png b/content/images/map.png new file mode 100644 index 0000000..a60b306 Binary files /dev/null and b/content/images/map.png differ diff --git a/content/images/press/2016-IMG_0574.jpg b/content/images/press/2016-IMG_0574.jpg new file mode 100644 index 0000000..583bad0 Binary files /dev/null and b/content/images/press/2016-IMG_0574.jpg differ diff --git a/content/images/press/2016-IMG_0578.jpg b/content/images/press/2016-IMG_0578.jpg new file mode 100644 index 0000000..50b4b24 Binary files /dev/null and b/content/images/press/2016-IMG_0578.jpg differ diff --git a/content/images/press/2016-IMG_0581.jpg b/content/images/press/2016-IMG_0581.jpg new file mode 100644 index 0000000..bedbb37 Binary files /dev/null and b/content/images/press/2016-IMG_0581.jpg differ diff --git a/content/images/press/2016-IMG_0584.jpg b/content/images/press/2016-IMG_0584.jpg new file mode 100644 index 0000000..d77957f Binary files /dev/null and b/content/images/press/2016-IMG_0584.jpg differ diff --git a/content/images/press/2016-IMG_0586.jpg b/content/images/press/2016-IMG_0586.jpg new file mode 100644 index 0000000..526ce03 Binary files /dev/null and b/content/images/press/2016-IMG_0586.jpg differ diff --git a/content/images/press/2016-IMG_0589.jpg b/content/images/press/2016-IMG_0589.jpg new file mode 100644 index 0000000..d9a69e1 Binary files /dev/null and b/content/images/press/2016-IMG_0589.jpg differ diff --git a/content/pages/accessibilita.md b/content/pages/accessibilita.md new file mode 100644 index 0000000..bde94b9 --- /dev/null +++ b/content/pages/accessibilita.md @@ -0,0 +1,65 @@ +Title: Accessibilità +slug: accessibility +navbar_sort: 2 + +Hackmeeting è uno spazio e una comunità autogestita: tutto quello che +troverai è autocostruito con povertà di mezzi, generalmente recuperando +strutture abbandonate e riadeguandole il più possibile ai nostri bisogni. +Abbiamo cercato di rendere Hackmeeting più accessibile che potevamo, ma +ci sono sicuramente ancora tante cose che non ci sono riuscite e altre +che dovremmo migliorare. Abbi pazienza e aiutaci segnalandoci cosa non +va, in modo da fare meglio il prossimo anno! + +## Lo spazio + +Hackit {{ hm.year }} si svolgerà al {{ hm.location.name }} a {{ hm.location.city }} + +Il Magazzino47 è dislocato interamente al piano terra, tutte le aree sono accessibili anche tramite delle apposite rampe, il cortile è dotato di passaggio in asfalto per facilitare il passaggio per persone a mobilità ridotta. + +## Aule seminari + +Saranno allestiti 3 spazi seminari + un'eventuale spazio laboratorio (ma un po' piccolo) + +## Dormire + +Gli spazi tende e dormitorio sono senza gradini e raggiungibili tramite apposite rampe. +Il tendone può ospitare all'incirca 80-100 persone munite di materassino, stuoia o brandina. Il tendone non può ospitare tende. Non ci sono letti a disposizione o stanze singole. +Lo spazio esterno è molto risicato e può ospitare all'incirca 20 tende o poco più. Si invita chi ne ha la possibilità a trovare sistemazioni esterne allo spazio. +Sarà disponibile uno spazio tende esterno all'evento raggiungibile a 15 min di auto. + +## Bagni + +Sono presenti tre turche e 1 bagno con doccia per persone a mobilità ridotta. Verranno allestite delle doccie esterne. + +## Modalità aereo + +C'è una piccola saletta che va sistemata (è il backstage artisti) ed è utilizzabile come sala modalità aereo. + +## Clima + +A giugno il clima è abbastanza variabile, si può passare da giornate di pioggia a giornate molto calde. Uno spazio seminario è al chiuso gli altri sono esterni ma comunque coperti da tendone o tettoia. + +## Linguaggi + +Non siamo ancora in grado di garantire un servizio di traduzioni in +simultanea, ma Hackmeeting è frequentato da persone che parlano diverse +lingue, compresa la LIS. Se hai bisogno, o se vuoi offrirti per +tradurre, rivolgiti all'info point. + +## Cani da assistenza + +Se hai un cane che ti accompagna è il benvenuto. Troverà acqua e +probabilmente altri cani con cui giocare. Se quest'ultima cosa dovesse +essere un problema segnalacelo all'info point all'ingresso e cercheremo +di limitare l'eventuale invadenza degli altri cani. + +## Altre info + +Nello spazio saranno presenti un po' ovunque prese per ricaricare +qualunque dispositivo. +La musica ad alto volume sarà presente in modo continuativo solo venerdì +sera e in un luogo lontano dagli altri spazi comuni. +Per qualsiasi altra informazione o necessità che non stiamo +considerando, puoi rivolgerti all'info point all'ingresso. + +Torna alla pagina delle [informazioni principali]({filename}info.md) diff --git a/content/pages/call.en.md b/content/pages/call.en.md new file mode 100644 index 0000000..e9927de --- /dev/null +++ b/content/pages/call.en.md @@ -0,0 +1,51 @@ +Title: Call for contents +slug: call +navbar_sort: 4 +lang: en + + +Hackmeeting is the yearly meeting of the Italian countercultures related to +hacking, communities which have a critical relationship with technology. + +Our idea of hacking touches every aspect of our lives and it doesn't stop at +the digital realm: we believe in the use of knowledge and technology to +understand, modify and re-create what is around us. + +It's not a vague idea, generic guidelines or aspiration, it's a pragmatic +organization effort based on solidarity, complicity and sharing of knowledge, +methods and tools to take back everything and take it back together, one piece +at a time. + +Hackmeeting will be held in {{hm.location.city}} from Friday 14 June to Sunday 16 June at {{hm.location.name}} + +If you think you can enrich the event with a contribution, send your proposal +joining the [hackmeeting mailing list](https://www.autistici.org/mailman/listinfo/hackmeeting) with subject `[talk] title` or `[lab] +lab_title` and this info: + +* Length (multiple of 30 minutes, max 2 hours) +* (optional) day/time of the day requirements +* Abstract, optional links and references +* Nickname +* Language +* Projector +* Can we record you? (audio only) +* Anything else you might need + +#### More concretely + +We will set up three outdoor locations (indoor in case of +rain), with microphone/speakers and projector. +If you think your presentation will not need this much time, you can propose +something directly at hackmeeting: a `ten minute talk` of a maximum of 10 +minutes. +These talks will be held in the largest available space at the end of of the +day on Saturday. There will be someone who will warn you if you are about to +exceed the allocated time. + +If you want to share your discoveries or curiosities in an even more informal +and chaotic way, you will be able to to get a place with your hardware on the +shared tables in the `LAN space`. You will find morbid curiosity, power and +wired connection (bring a power strip, network cables and whatever you might +find useful). + +Have any questions or you are shy? Write us at [infohackit@tracciabi.li](mailto:infohackit@tracciabi.li) diff --git a/content/pages/call.md b/content/pages/call.md new file mode 100644 index 0000000..702d4fa --- /dev/null +++ b/content/pages/call.md @@ -0,0 +1,36 @@ +Title: Call for contents +slug: call +navbar_sort: 4 +lang: it + +Hackmeeting è l’incontro annuale delle controculture digitali legate all’hacking e hacktivismo, rivolto a tutte le comunità e persone che vivono in maniera critica il rapporto con la tecnologia, i mass-media, i social e ogni aspetto della vita imposta. + +Hackmeeting investe ogni ambito delle nostre vite e non si limita al digitale: crediamo nella diffusione del sapere e della tecnologia per conoscere, modificare e ricreare quanto ci sta attorno. Crediamo fortemente nelle pratiche di autogestione e DIY. Crediamo che la tecnologia debba rispettare le nostre volontà e non le logiche del profitto. + +Hackmeeting non è un idea vaga, una generica linea guida o aspirazione. E' una reale capacità organizzativa basata sulla solidarietà, sull'inclusività e sulla condivisione delle conoscenze e degli strumenti per riprenderci tutto e riprendercelo insieme. + +Hackmeeting è il contributo di ogni singola persona, non ci sono partecipantɜ ma solo organizzatorɜ. + +Hackmeeting quest’anno si svolgerà a {{hm.location.city}} da venerdì 14 giugno a domenica 16 giugno presso il {{hm.location.name}}. + +Se pensi di poter arricchire l’evento con un tuo contributo: +iscriviti alla mailing list di Hackmeeting + +Manda una mail a hackmeeting@inventati.org con: + +- oggetto [Talk e titolo del talk oppure Laboratorio e titolo del laboratorio] +- durata [un multiplo di 30 minuti per un massimo di due ore] +- eventuali esigenze di giorno/ora +- breve spiegazione, eventuali link e/o riferimenti utili +- Nickname +- lingua +- necessità di proiettore e/o particolari tecnologie +- eventuale disponibilità a farti registrare [solo audio] +- altre necessità o particolari indicazioni. + +Allestiremo spazi all’aperto (al coperto in caso di pioggia) muniti di amplificazione e proiettore. +Se pensi che la tua presentazione non abbia bisogno di tempi così lunghi, puoi proporre direttamente ad Hackmeeting un Ten Minute Talk dalla durata di massimo 10 minuti. Questi talk si terranno al termine delle giornate di venerdì e sabato durante la sera. + +Se invece vuoi condividere le tue scoperte e curiosità in modo ancora più informale e caotico, potrai sistemarti sui tavoli collettivi dell'area LAN Space. Troverai curiosità, corrente alternata e rete via cavo. Ricordati di portare una presa multipla, un cavo di rete e quel che vorresti trovare e che ti serve. + +Hai una domanda? Scrivi a [infohackit@tracciabi.li](mailto:infohackit@tracciabi.li) diff --git a/content/pages/come_arrivare.en.md b/content/pages/come_arrivare.en.md new file mode 100644 index 0000000..afb20a4 --- /dev/null +++ b/content/pages/come_arrivare.en.md @@ -0,0 +1,26 @@ +Title: How to get there +slug: come-arrivare +lang: en + +Hackit {{hm.year}} will be held at [{{hm.location.name}}]({{hm.location.website}}) - [{{hm.location.address}}, {{hm.location.city}}](https://www.openstreetmap.org/#map=16/{{hm.location.geo.lat}}/{{hm.location.geo.lon}}) + +
View Map + +Hackmeeting it's easy to reach. If you get lost just search for Brescia's monumental cemetery that's next to Magazzino 47. + +## By train or autobus + +Hackmeeting is 20 minutes walking from the train and the autobus stations. +Out of the train station is possible to take the autobus number 3 direction **Mandolossa** and the number 9 direction **Violino** that stops in via Milano, just after the cemetery. + +## By car + +Hackmeeting it's easy to reach from highway A4, exit Brescia Ovest. +Around the space it's possible to park for free, also for camper and vans. + + +## By Airplane + +The closest airport is Milano Bergamo (BGY), 40km from Brescia. There are fast autobus linking the airport with Brescia train station in about 1 hour, the price for the ticket is 12€. +Another option to reach Brescia is to take an urban bus to Bergamo (3€) and then the train (5.20€) but it'll take 30 minutes more. + diff --git a/content/pages/come_arrivare.md b/content/pages/come_arrivare.md new file mode 100644 index 0000000..6e7d6a6 --- /dev/null +++ b/content/pages/come_arrivare.md @@ -0,0 +1,31 @@ +Title: Come arrivare +slug: come-arrivare +navbar_sort: 2 +lang: it + +Hackit {{hm.year}} si svolgerà al [{{hm.location.name}}]({{hm.location.website}}), in [{{hm.location.address}}, {{hm.location.city}}](https://www.openstreetmap.org/#map=16/{{hm.location.geo.lat}}/{{hm.location.geo.lon}}) + +
Visualizza Mappa + +Il centro sociale è facilmente raggiungibile. Se vi disorientate cercate il cimitero monumentale di Brescia che è a fianco del Magazzino 47. + +## Con i piedi +Saprai come fare, ne siamo certi. Da dove parti parti. + +## Con il treno e l'autobus + +Lo spazio dista circa 20 min a piedi dalla stazione dei treni e dei bus di Brescia. +Fuori dalla stazione dei treni è possibile prendere l'autobus numero 3 direzione Mandolossa e il 9 in direzione Violino con fermata in via Milano subito dopo il cimitero. + + +## Con veicoli a motore + +Il Magazzino 47 è facilmente raggiungibile dall'autostrada A4, uscita Brescia Ovest. +Intorno allo spazio sono presenti diversi parcheggi gratuiti con possibilità di posteggiare camper e furgoni in diverse aree e vie adiacenti anche se siamo in città. + + +## Con l'aereo + +L'aeroporto più servito e più vicino è quello di Milano Bergamo (BGY), distante circa 40km da Brescia. +Sono disponibili autobus autostradali che collegano l'aeroporto con la stazione di Brescia in circa un'ora al costo di 12€. +Per raggiungere Brescia, è anche possibile passare prima per Bergamo con gli autobus urbani (3€) e poi prendere il treno (5.20€), ma i tempi si allungano di altri trenta minuti. diff --git a/content/pages/contatti.en.rst b/content/pages/contatti.en.rst new file mode 100644 index 0000000..00c1d13 --- /dev/null +++ b/content/pages/contatti.en.rst @@ -0,0 +1,17 @@ +Contact +########### + +:slug: contact +:navbar_sort: 6 +:lang: en + +**Mailing List** + +There is a `mailing list `_ where you can ask for info and follow the discussions about the meeting. It is mostly in italian but feel free to ask questions in english. + +**IRC** + +There is also an IRC (Internet Relay Chat) channel where discuss and chat with other participants: connect to server ``irc.autistici.org`` and join channel ``#hackit99`` (again, it will be mostly in italian, but english speakers are welcome). + +If you prefer XMPP/Jabber, you can reach the same channel as room ``#hackit99@mufhd0.esiliati.org`` (please +include the hash) diff --git a/content/pages/contatti.rst b/content/pages/contatti.rst new file mode 100644 index 0000000..6842eaf --- /dev/null +++ b/content/pages/contatti.rst @@ -0,0 +1,22 @@ +Contatti +########### + +:slug: contact +:navbar_sort: 6 +:lang: it + +**Mailing List** + +La comunità Hackmeeting ha una `lista di discussione `_ dove poter chiedere informazioni e seguire le attività della comunità. La lista ha un `archivio pubblico `_, quindi puoi leggerla anche senza iscriverti. L'iscrizione è invece necessaria per scrivere. + +**IRC** + +Esiste anche un canale IRC (Internet Relay Chat) dove poter discutere e chiacchierare con tutti i membri della comunità: collegati al server ``irc.autistici.org`` ed entra nel canale ``#hackit99``. + +Se preferisci XMPP/Jabber, puoi raggiungere lo stesso canale come ``#hackit99@mufhd0.esiliati.org`` (includi il cancelletto). + + +Sito +--------- + +Se vuoi modificare il sito, vedi le info su https://0xacab.org/hackit/sito-hackit-{{hm.year - 2000}}#user-content-hackmeeting-{{hm.year}} diff --git a/content/pages/index.en.rst b/content/pages/index.en.rst new file mode 100644 index 0000000..1e03bdc --- /dev/null +++ b/content/pages/index.en.rst @@ -0,0 +1,30 @@ +About +##### + +:navbar_sort: 1 +:lang: en +:slug: index + +.. raw:: html + +
+
+ +
+
+




+ {{ hm.when }}
+ {{ hm.location.name }}
{{ hm.location.city }} +




+ +
+
+ + + Hackmeeting is the yearly Italian digital counter-cultures meeting; it gathers those communities that take a hard look at how technologies work in our society. And that's not all. We tell you, just you, in a whisper (don't even tell anybody!): Hack-it is just for real hackers, that is to say for those people who want to manage their own lives as they want and are ready to fight for this right, even though they haven't ever seen a computer in their life. + + Three days of lessons, games, parties, debates, crossfires and collective learning, analyzing together those technologies that we use everyday, the way they change and how they can impact on our real or virtual lives; which role we can play in order to redirect these changes and set us free of control from those who want to monopolize their development, letting society crumble and relegating us in even tighter virtual spaces. + + **The event is totally self-managed: there are neither promoters nor users, just participants.** + + diff --git a/content/pages/index.es.rst b/content/pages/index.es.rst new file mode 100644 index 0000000..30fc665 --- /dev/null +++ b/content/pages/index.es.rst @@ -0,0 +1,28 @@ +About +################### + +:slug: index +:navbar_sort: 1 +:lang: es + +.. raw:: html + +
+
+ +
+
+




+ {{ hm.when }}
+ {{ hm.location.name }}
{{ hm.location.city }} +




+ +
+
+ + +Hackmeeting es el encuentro anual de las contraculturas digitales italianas, de aquellas comunidades que analizan de manera crítica los mecanismos de desarollo de las tecnologías en nuestra sociedad. Pero hackmeeting no es sólo esto, es mucho más. Te lo contamos al oído, no se lo digas a nadie, el hackmeeting es solamente para verdaderos hackers, para quienes quieran gestionarse la vida como quieran y luchan por eso, aunque no hayan visto un ordenador en su vida. + +Tres días de charlas, juegos, fiestas, debates, intercambios de ideas y aprendizaje colectivo, para analizar juntxs las tecnologías que usamos todos los días, cómo cambian y cómo pueden impactar en nuestras vidas, tanto reales como virtuales. Un encuentro para indagar qué papel podemos jugar en este cambio y liberarnos del control de aquellos que quieren monopolizar su desarrollo, rompiendo nuestras estructuras sociales y relegándonos a espacios virtuales cada vez más limitados. + +**El evento es totalmente autogestionado: no hay ni organizador@s ni asistentes, solamente participantes!** diff --git a/content/pages/index.fr.md b/content/pages/index.fr.md new file mode 100644 index 0000000..cbb8287 --- /dev/null +++ b/content/pages/index.fr.md @@ -0,0 +1,38 @@ +Title: About +Date: 2016-04-17 +Slug: index +navbar_sort: 1 +lang: fr + +
+
+ +
+
+




+ {{ hm.when }}
+ {{ hm.location.name }}
{{ hm.location.city }} +




+ +
+
+ + +*Hackmeeting* est la rencontre annuel des cultures numériques alternatives +italiennes, des communautés qui agissent de façon critique face aux mécanismes +de développement des technologies dans notre société. Mais c'est pas seulement +ça: on y trouve bien plus. On te le chuchote à l'oreille, ne le dis à personne: +hackit est seulement pour les vrais hackers, c'est à dire pour ceux/celles qui +veulent conduire leur vie comme ils/elles préfèrent, et qui savent comment se +battre pour accomplir leur objectif; même s'ils/elles n'ont jamais vu un ordi. + + +Trois jours entre talk techniques, jeux, fêtes, débats, discussions et +apprentissage collectif, tout ça pour étudier tous ensemble les technologies +qu'on utilise tous les jours, leur développement et les changements qu'elles +provoquent dans le réel et le virtuel des nos vies; pour comprendre quel soit +le rôle qu'on puisse jouer pour adresser ces changement vers la libération à +las fois des technologies elles-mêmes et des nos vies. + +**L'événement est complètement autogéré: il n'y a que des participants, pas +d'organisateurs, pas d'entrepreneurs.** diff --git a/content/pages/index.md b/content/pages/index.md new file mode 100644 index 0000000..08b306f --- /dev/null +++ b/content/pages/index.md @@ -0,0 +1,23 @@ +Title: About +Slug: index +navbar_sort: 1 +lang: it + +
+
+ +
+
+




+ {{ hm.when }}
+ {{ hm.location.name }}
{{ hm.location.city }} +




+
Informazioni ospitalità

+
+
+ +L'*hackmeeting* è l'[incontro]({filename}/pages/info.md) annuale delle controculture digitali italiane, di quelle comunità che si pongono in maniera critica rispetto ai meccanismi di sviluppo delle tecnologie all'interno della nostra società. Ma non solo, molto di più. Lo sussuriamo nel tuo orecchio e soltanto nel tuo, non devi dirlo a nessuno: l'hackit è solo per hackers, ovvero per chi vuole gestirsi la vita come preferisce e sa s/battersi per farlo. Anche se non ha mai visto un computer in vita sua. + +Tre giorni di [seminari, giochi, dibattiti]({filename}/pages/programma.rst), scambi di idee e apprendimento collettivo, per analizzare assieme le tecnologie che utilizziamo quotidianamente, come cambiano e che stravolgimenti inducono sulle nostre vite reali e virtuali, quale ruolo possiamo rivestire nell'indirizzare questo cambiamento per liberarlo dal controllo di chi vuole monopolizzarne lo sviluppo, sgretolando i tessuti sociali e relegandoci in spazi virtuali sempre più stretti. + +**L'evento è totalmente autogestito: non esiste chi organizza o fruisce, esiste solo chi partecipa.** diff --git a/content/pages/index.pt.rst b/content/pages/index.pt.rst new file mode 100644 index 0000000..c58d659 --- /dev/null +++ b/content/pages/index.pt.rst @@ -0,0 +1,27 @@ +About +################### + +:slug: index +:navbar_sort: 1 +:lang: pt + +.. raw:: html + +
+
+ +
+
+




+ {{ hm.when }}
+ {{ hm.location.name }}, {{ hm.location.city }} +




+ +
+
+ + +Hackmeeting é o encontro anual das contro-culturas digitais italianas, quer dizer daquelas comunidades que se colocam criticamente ao respeito dos mecanismos de desenvolvimento das tecnologías nas nossas sociedades. Mais não simplesmente isso, é muito mais. A gente sussurra no seu ouvido e só no seu, você não precisa contar para ninguém: o hackit é só para hackers de verdade, ou seja, para quem quer administrar sua vida como prefere e sabe comprometer-se a lutar por isso. Mesmo que nunca tenha visto um computador na sua vida. + +Três dias de seminários, jogos, debates, trocas de ideias e aprendizagem coletivo, para analisarmos juntos as tecnologías que usamos todos os dias, como elas mudam e quais profundas mudanças induzem em nossas vidas reais e virtuais, que papel podemos desempenhar no direcionamento dessas mudanças para libertá-las do controle daqueles que querem monopolizar seu desenvolvimento, desintegrando o tecido social e nos relegando a espaços virtuais cada vez mais estreitos. +O evento é totalmente autogerido: não há organizador@s e usuári@s, só participantes. diff --git a/content/pages/info.en.md b/content/pages/info.en.md new file mode 100644 index 0000000..dacde97 --- /dev/null +++ b/content/pages/info.en.md @@ -0,0 +1,112 @@ +Title: Info +slug: info +navbar_sort: 1 +lang: en + + +#### Where + +{{hm.location.name}}, {{hm.location.address}}, {{hm.location.city}}, Italia + +[Here is how to arrive]({filename}/pages/come_arrivare.en.md) + +#### When + +From Friday 14 June to Sunday 16 June 2024 + +#### Sleeping + +TBD_EN + +#### Map + +TBD + +##### Can I arrive before Friday 14? + +TBD_EN + +##### Can I stay even beyond Sunday 16? + +TBD_EN + +#### Eating + +TBD_EN + +#### Who is organizing? + +Hackmeeting is a yearly meeting of a community that communicates +through +[a mailing list](https://www.autistici.org/mailman/listinfo/hackmeeting). There +is no distinction between organizers and users. Everyone can subscribe +and partecipate in the organization by visiting the site +[it.hackmeeting.org](https://it.hackmeeting.org) and entering the community. + +#### What is an hacker? + +Hackers are curious people, always eager to discover how things are +done. Whether it is technology or not, hackers reclaim freedom to +experiment, disassemble and reassemble things or concepts, to +understand how are they made, to improve them, and then to share how +to do it again. Hackers solve problems and build things, believing in +freedom and sharing. They do not like closed systems. Hackers' forma +mentis is not restricted to the field of software hacking: there are +people that keep the hacker mentality in every existing field, driven +by their creative impulse. + +#### Who holds the talks? + +Whoever wants to. If someone wants to propose a talk, they just has to +propose it on the mailing list. If the proposal is well received, it +gets on calendar. If there are some problems, the community will be +happy to help improve the proposal. + +### What’s in there, besides talks? + +There is a LAN space, as to say an area dedicated to the net: everyone +can plug their laptop, forming a network with the other participants. In +general, this is the right place to meet other attendees, to ask for +help in installing Linux, to solve a doubt, or just to have a chat. +Hackmeeting is an open-air festival, a meeting, an hacking party, a +moment of consideration, an occasion to learn something together, an act +of rebellion, an exhange of ideas, experiences, dreams, utopias. + +#### How much does it cost? + +Traditionally, entrance in Hackmeeting is totally free: always keep in +mind that organizing the event has a cost. Expenses are sustained +through voluntary contributions, selling shirts and other gadgets and +sometimes through the earnings of the bar. +Please donate whatever you can, every small donation counts. + +#### What shall I bring? + +If you want to bring a computer, take a power +strip too. Do not forget networking hardware (like Ethernet cables, +switches, WiFi access points). Remember to bring the hardware that +you will want to hack in company. We will try to get some internet +connection for everybody to share, but we can't really guarantee anything. +If you think that you need it, bring a 3G/4G stick with you +and the necessary to share it with friends! Try to be as independent +as possible regarding your hardware. + +#### May I take photos, make videos, post, tag, share, upload? + +We think that the freedom to choose the dimensions of one’s own private +sphere and public profile must be guaranteed to every participant: in +this spirit, photos and/or videos are admitted only if explicitly +authorized by every person that appears in the media. Nobody should be +photographed without knowing. +Many people at Hackmeeting really care about their privacy, please ask +before taking a picture. + +#### How are people expected to behave? + +Hackmeeting is a self-managed space, a temporary independent space and +whoever passes through is expected to behave according to the principles +of antisexism, antiracism and antifascism. If you are victim or witness +of an act of oppression, aggression, brute force, port scan, ping flood +and other non-consensual DOS and you do not know how to react, always +count on the community’s support and do not hesitate to attract +attention and ask for help. diff --git a/content/pages/info.md b/content/pages/info.md new file mode 100644 index 0000000..af81cf4 --- /dev/null +++ b/content/pages/info.md @@ -0,0 +1,128 @@ +Title: Info +slug: info +navbar_sort: 1 + +#### Dove + +{{hm.location.name}}, {{hm.location.address}}, {{hm.location.city}}, Italia + +[Qui trovi tutte le informazioni su come arrivare]({filename}/pages/come_arrivare.md) + +#### Quando + +Da Venerdì 14 Giugno a Domenica 16 Giugno 2024 + +#### Dormire + +All'interno dello spazio l'area tendone è stata adibita a spazio dormitorio (al coperto), all'interno del tendone sarà possibile pernottare con brandine, stuoie e materassini (niente tende). La disponibilità del tendone è di circa 100 posti letto. +Nelle poche aree verdi del centro sociale sarà possibile campeggiare per un max di 20 tende piccole. +Vista la scarsa capienza del magazzino47 per il pernottamento chiediamo a chi ne ha le possibilità di trovare una sistemazione alternativa nelle vicinanze (ostello, b&b, appartementi, amici e parenti). + +Per chi comunque volesse dormire nello spazio si consiglia di munirsi di: +- tappetino,stuoia, materassino (suolo in cemento) +- tappi per le orecchie (lo spazio è piccolo ed è facile essere disturbati) +- antizanzare +- brandine e maschere per dormire (per i più attrezzati) + + +Sarà possibile campeggiare in uno spazio diverso dal Magazzino47 per chi non dovesse trovare una sistemazione all'interno del centro sociale e per chi non ha la possibilità di una sistemazione alternativa indipendente. Il luogo individuato si trova a 15min di macchina dal Magazzino47 in località: LAGO PONTE MELLA. +Ricordiamo che è un prato rencintato con possibilità di campeggio (non c'è sorveglianza): munirsi di antizanzare - INDISPENSABILE, tappi per orecchie, mascherine oscuranti (pochi alberi presenti), frontalino/luci e tutto il necessario per pernottare. In loco è presente solamente 1 bagno e no doccia. Non sono presenti prese per l'elettricità. + +#### Mappa + +[Clicca qui per aprire la mappa]({static}/images/map.png) + +#### Posso arrivare prima di Venerdì 14? + +E' possibile arrivare ad hackmeeting anche nei giorni precedenti all'evento per dare una mano. Per chi ha intenzione di arrivare durante la settimana può segnarsi sul seguente pad: + +#### Posso rimanere anche oltre Domenica 16? + +E' possibile rimanere fino a lunedì all'interno degli spazi del Magazzino47. + +#### Mangiare + +Saranno garantite anche colazioni/pranzi/cene a un prezzo popolare. +La cucina sarà vegana, con alternative celiache se avete delle necessità particolari (allergie o altro) segnalatecelo. + +#### Lavarsi + +C'è una doccia nel bagno per mobilità ridotta e verranno allestite delle doccie esterne. Lavatevi poco che fa male. + +#### Hackmeeting è accessibile? + +Speriamo di sì! Trovi tutte le informazioni nella [pagina dedicata +all'accessibilità]({filename}accessibilita.md) + +#### Chi organizza l'hackmeeting? + +L’hackmeeting è un momento annuale di incontro di una comunità che si riunisce +intorno a [una mailing list](https://www.autistici.org/mailman/listinfo/hackmeeting). +Non esistono chi organizza e chi fruisce. Tutte le persone possono iscriversi e partecipare +all’organizzazione dell'evento, semplicemente visitando il sito [hackmeeting.org](https://hackmeeting.org) ed entrando nella comunità. + +#### Chi è un@ hacker? + +Le persone cosiddette hacker sono persone curiose, che non accettano di non poter mettere le mani +sulle cose. Che si tratti di tecnologia o meno chi è hackers reclama la libertà +di sperimentare. Smontare tutto, e per poi rifarlo o semplicemente capire come +funziona. Sono persone che risolvono problemi e costruiscono le cose, credono nella +libertà e nella condivisione. Non amano i sistemi chiusi. La forma mentis +di chi è hacker non è ristretta all’ambito del software-hacking: ci sono persone +che mantengono un attitudine all'hacking in ogni campo dell’esistente, sono persone curiose spinte +da un istinto creativo. + +#### Chi tiene i seminari? + +Chi ne ha voglia. Se qualche persona vuole proporre un seminario, non deve fare altro +che proporlo in lista. Se la proposta piace, si calendarizza. Se non piace, si +danno utili consigli per farla piacere. + +#### Ma cosa si fa, a parte seguire i seminari? + +Esiste un “LAN-space”, vale a dire un’area dedicata alla rete: ogni persona arriva +col proprio portatile e si può mettere in rete con altre persone. In genere in +questa zona è facile conoscere altre creature curiose, magari disponibili per farsi aiutare a +installare Linux, per risolvere un dubbio, o anche solo per scambiare quattro +chiacchiere. L’hackmeeting è un open-air festival, un meeting, un hacking +party, un momento di riflessione, un’occasione di apprendimento collettivo, un +atto di ribellione, uno scambio di idee, esperienze, sogni, utopie. + +#### Quanto costa l’ingresso? + +Come ogni anno, l’ingresso all’Hackmeeting è del tutto libero; ricordati però +che organizzare l’Hackmeeting ha un costo. Le spese sono sostenute grazie ai +contributi volontari, alla vendita di magliette e altri gadget e in alcuni casi +all’introito del bar e della cucina. + +#### Cosa devo portare? + +Se hai intenzione di utilizzare un computer, portalo accompagnato da una +ciabatta elettrica. Non dimenticare una periferica di rete di qualche tipo +(cavi ethernet, switch, access point). Ricordati inoltre di portare tutto +l’hardware su cui vorrai smanettare con gli altri. Durante l’evento la +connessione internet sarà limitata quindi, se vuoi avere la certezza +organizzati portando il necessario per te e per chi ne avra' bisogno. +In generale ogni persona organizza e partecipa cercando di essere autosufficiente +sul lato tecnologico portandosi l'hardware o costruendoselo al hackmeeting! + +#### Posso scattare foto, girare video, postare, taggare, condividere, uploadare? + +Pensiamo che ad ogni partecipante debba essere garantita la libertà di +scegliere in autonomia l’ampiezza della propria sfera privata e dei propri +profili pubblici; per questo all’interno di hackmeeting sono ammessi fotografie +o video SOLO SE CHIARAMENTE SEGNALATI E PRECEDENTEMENTE AUTORIZZATI da tutte e +tutti quanti vi compaiano. + +Le persone che attraversano hackmeeting hanno particolarmente a cuore il concetto di privacy: prima di fare +una foto, esplicitalo! + +#### Come ci si aspetta che si comportino tutte e tutti? + +Hackmeeting è uno spazio autogestito, una zona temporaneamente autonoma e chi +ci transita è responsabile che le giornate di hackit si svolgano nel rispetto +dell’antisessismo, antirazzismo e antifascimo. Se subisci o assisti a episodi +di oppressione, aggressione, brute force, port scan, ping flood e altri DoS non +consensuali e non sai come reagire o mitigare l’attacco, conta sul sostegno di +tutta la comunità e non esitare a richiamare pubblicamente l’attenzione e +chiedere aiuto. diff --git a/content/pages/programma.en.rst b/content/pages/programma.en.rst new file mode 100644 index 0000000..425520c --- /dev/null +++ b/content/pages/programma.en.rst @@ -0,0 +1,42 @@ +Schedule +=========== + +:slug: schedule +:navbar_sort: 3 +:lang: en + +.. `Add the schedule `_ |ics| as a calendar + +.. |ics| image:: {attach}/images/ics.png + :height: 2em + :target: webcals://it.hackmeeting.org/schedule.ics + +To track the schedule, you might want to: + + * `add it to Android `_ + * `add it to your desktop calendar `_ (ie: Thunderbird) + * `raw URL `_ + +The schedule is still work in progress: a large part of hackmeeting +contents are scheduled last-minute! We will **stop** updating this page on Thursday, 23:00. From that time, +the only authoritative source will be the paper-made schedule in the LAN space. + +Read the `call for contents <{filename}call.en.md>`_ and propose yours in `mailing list <{filename}contatti.rst>`_. + + +Contents in a language other than Italian are not only accepted, but +appreciated! + +Hackmeeting (still) hasn't a proper translation system, but you can +find a bunch of people to ask to do translations when you need it. + +.. raw:: html + + To see the map,
click here + + +.. talkgrid:: + :lang: en + +.. talklist:: + :lang: en diff --git a/content/pages/programma.rst b/content/pages/programma.rst new file mode 100644 index 0000000..e5813ad --- /dev/null +++ b/content/pages/programma.rst @@ -0,0 +1,34 @@ +Programma +=========== + +:slug: schedule +:navbar_sort: 3 +:lang: it + +.. + Gli audio dell'hackmeeting sono disponibili `qui + `_. + +Per seguire il calendario con più comodità: + + * `aggiungilo ad android `_ + * `aggiungilo al tuo calendario desktop `_ (ad esempio Thunderbird) + * `URL grezzo `_ + +Il programma è soggetto a variazioni continue: vieni ad hackmeeting e vivitelo! In particolare, questa pagina **non** verrà più aggiornata con regolarità a partire da giovedì alle 23. Da quel momento, vale solo il tabellone di carta che si trova nel LAN space. + +Fatti coraggio, `rispondi alla call for contents <{filename}call.md>`_, proponi il tuo contenuto in `mailing list <{filename}contatti.rst>`_: crea un nuovo thread +dedicato alla tua proposta. Nel subject inserisci ``[TALK]`` +(ad esempio ``[TALK] come sbucciare le mele con un cluster di GPU``) così che sia facile ritrovarlo per chi è +interessato. + +.. raw:: html + + Per consultare la mappa, clicca qui + + +.. talkgrid:: + :lang: it + +.. talklist:: + :lang: it diff --git a/content/pages/propaganda.md b/content/pages/propaganda.md new file mode 100644 index 0000000..f4388d3 --- /dev/null +++ b/content/pages/propaganda.md @@ -0,0 +1,130 @@ +Title: Propaganda +slug: propaganda +lang: it +navbar_sort: 10 + + + + +#### Logo Hackmeeting + + + +[download png color alta risoluzione]({static}/images/logo_color2_hires.png) - +[download png color web]({static}/theme/images/logoHM24_color2_sito.png) + + + + +[download jpg n/n alta risoluzione]({static}/images/logo_hires.jpg) - +[download png b/n web]({static}/theme/images/logoHM24_sito.png) + +#### Locandine + +Realizzate da ouch_bruh e judaskisss + +locandina color web + +[download color png da stampare]({static}/images/locandina24_color2_stampa.png) - +[download color jpg web]({static}/images/locandina24_color2_web.jpg) + + +locandina web + +[download b/n jpg da stampare]({static}/images/locandina24_stampa.jpg) - +[download b/n jpg web]({static}/images/locandina24_web.jpg) + + + + + + + + + diff --git a/content/pages/stampa.rst b/content/pages/stampa.rst new file mode 100644 index 0000000..8956be5 --- /dev/null +++ b/content/pages/stampa.rst @@ -0,0 +1,76 @@ +Stampa +######### + +:slug: press +:navbar_sort: 9 +:lang: it + +Cartella stampa +"""""""""""""""""""""""""""""""""""""" + + +Propaganda +""""""""""""""""""""""""""""""""""""""" + +I materiali utili per la diffusione di hackmeeting {{hm.year}} sono nell'apposita pagina `Propaganda +<{filename}propaganda.md>`_ + + +Foto +""""""""""""""""""""""""""""""""""""""" + + +.. image:: images/press/2016-IMG_0578.jpg + :height: 200px + :alt: La bacheca dei seminari dell'hackmeeting 2016, a Pisa + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0578.jpg + +.. image:: images/press/2016-IMG_0581.jpg + :height: 200px + :alt: Sessione di elettronica digitale + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0581.jpg + +.. image:: images/press/2016-IMG_0584.jpg + :height: 200px + :alt: Programmazione + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0584.jpg + +.. image:: images/press/2016-IMG_0586.jpg + :height: 200px + :alt: Computer + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0586.jpg + +.. image:: images/press/2016-IMG_0589.jpg + :height: 200px + :alt: Il LAN party: un posto dove sperimentare insieme + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0589.jpg + +.. image:: images/press/2016-IMG_0574.jpg + :height: 200px + :alt: Un hack su Emilio: il famoso robottino degli anni '90 è stato riprogrammato + :target: https://hackmeeting.org/hackit16/images/photos/IMG_0574.jpg + + +Comunicati stampa +""""""""""""""""""""""""""""""""""""""" + + + + +Comunicato Stampa 13 Giugno +================================= + + +| HACKMEETING +| 14-16 giugno 2024 +| Centro Sociale Autogestito Magazzino 47 +| Via Industriale 10, BRESCIA +| + + +Strumenti per la programmazione dei robot, scoprire i segreti dell'intelligenza artificiale, viaggiare nel cuore di un motore di ricerca, conoscere la storia della Radio antagonista bresciana, cucinare e conoscere la cucina vegana e palestinese, cantare sulle note dell' HTTPS. Sono solo alcuni dei temi al centro dell'Hackmeeting, incontro annuale delle controculture digitali che giunge nel 2024 alla sua ventisettesima edizione e che si svolge quest’anno a Brescia, al CSA Magazzino 47, in via Industriale 10, dal 14 al 16 giugno. Il Magazzino 47, sede del movimento antagonista dal 1985, e' strettamente legato all’emittente Radio Onda d’Urto, punto di riferimento della galassia antagonista bresciana, uno spazio autogestito dove l’impegno politico si intreccia con l’attività sociale, la cultura e la musica. Un festival (il programma è disponibile su www.hackmeeting.org) dell’insegnamento reciproco e dello scambio libero e gratuito, per scoprire come configurare server autogestiti a prova di privacy, con approfondimenti dal punto di vista tecnico e legale, ma anche reti digitali in assenza di internet o sistemi anticollisione per droni. Obiettivo: riportare la tecnologia sotto il controllo delle persone in un mondo in cui sempre di più sono le persone a finire sotto il dominio dei dispositivi, e cioè delle grandi aziende che ci stanno dietro. L’HackIT è solo per "hackers" con un' eccezzione diversa da quella comune, ovvero per chi vuole gestirsi la vita come preferisce e sa mettersi in gioco per farlo. Anche se non ha mai visto un computer in vita sua. + + +Si parte dalle basi - l'utilizzo di un tester elettrico o l'installazione di Linux sul proprio computer - per lanciarsi verso la conquista del controllo della propria indipendenza digitale. Seminari aperti a tutte le persone e gratuiti, per mettere insieme idee e competenze. Una formula consolidata, figlia di un'idea che precorse i tempi. La prima edizione risale al 1998, in oltre un quarto di secolo, l'Hackmeeting ha accompagnato tutte le fasi della rete. Lanciando l'allarme con anni di anticipo su quello che sarebbe successo in Italia e nel mondo. La voracità di Google sui dati delle persone, la pervasività dei social e le dipendenze che hanno provocato, il controllo sociale attraverso i dispositivi, le bolle digitali fatte di propaganda personalizzata, la trasformazione delle criptovalute da strumenti di libertà a mezzi speculativi, la fine della neutralità della rete, le insidie del telefonino nei rapporti di lavoro o come strumento di sorveglianza. + +Ogni anno, la comunità dell'Hackmeeting si riunisce in una città diversa e, tenacemente, continua a interrogarsi sulle trasformazioni che la tecnologia sta impoendo al mondo, alla ricerca di strade alternative. Fatte di meno dominio e controllo; e di più autonomia, condivisione e consapevolezza. diff --git a/content/pages/storia.md b/content/pages/storia.md new file mode 100644 index 0000000..b6875e1 --- /dev/null +++ b/content/pages/storia.md @@ -0,0 +1,217 @@ +Title: Storia +slug: storia +navbar_sort: 8 + +####La storia dell'HackMeeting + +* **1998 - Firenze - CPA Firenze Sud** + +Viene organizzato il primo hackmeeting al Cpa di Firenze. [Strano Network](http://strano.net/), [Avana BBS](http://avana.forteprenestino.net/), [Ecn](http://www.ecn.org), [Freaknet](http://www.freaknet.org), Decoder, Metro Olografix e la rete +Cybernet decidono di fare un meeting perché quattro anni prima c’era stato un primo giro di vite contro gli hacker italiani. Il problema era +che i media iniziavano ad accorgersi che c’era il fenomeno digitale e identificavano il tentativo di capire la logica delle nuove tecnologie +come fenomeno “criminali”. La comunità hacker invece voleva sottolineare che il computer era uno strumento di massa, domestico e non solo +tecnico-universitario o militare, di controllo o di mercato. +L’informazione che su quella rete di pc passava, doveva essere libera. Radio Cybernet strimmava i seminari su web, prima webradio italiana. Da +allora, la radio ci sarà praticamente ogni anno. I tre giorni di Firenze sono quelli in cui e’ nato l’impianto dell’hackmeeting attuale. Il +messaggio era: usciamo dal digitale e portiamo nel reale e alla portata di tutti questioni tecniche e opportunità di comunicazione diretta; +siamo noi a dirtelo senza mediazioni (”don’t hate the media, become the media” da lì a qualche anno avrebbe affiancato “information wants to be +free”). Quell’anno per esempio esce Kryptonite, un libro che raccoglie how-to su strumenti specifici, legati alla privacy e all’anonimato +(anonimous remailer, gpg, packet radio). L’intenzione divulgativa dell’hackmeeting è chiara. All’hackmeeting partecipa tutta la scena più +rappresentativa dell’underground italiano. La prima generazione di hacker che si riconosce nel termine non nel senso più comunemente +attribuito dai media. Strumenti tecnici: corsi di linux per principianti e workshop sulla accessibilità delle tecnologie e dei siti. + +* **1999 - Milano - Deposito Bulk** + +Viene deciso collettivamente di uscire dalla dimensione dei tre giorni per darsi spazi tutto l’anno, e dare origine agli hacklab dove +incontrarsi, avere un laboratorio, condividere il lavoro, divulgare tematiche. Ospite di rilievo è Wau Holland, un hacker libertario +cofondatore del Chaos Computer Club, che senza carta di identità arrivò in Italia in modi rocamboleschi. Connessioni internazionali vengono +fatte conoscere alla comunità italiana. Strumenti tecnici: si ricorda il seminario su attaccare i protocolli di comunicazione (ip icmp tcp udp + +servizi), per capire/spiegare un po’ meglio come funzionano i protocolli di rete e quindi dove e perché sono vulnerabili. Un altro tema che +diventerà ricorrente negli hackmeting. + +* **2000 - Roma - Forte Prenestino** + +Sede di Avana BBS, primo hackmeeting organizzato con gli hacklab, diventati ormai realtà concrete. Jaromil si presenta con asciicam, +costruendo le relazioni declinate in altri ambiti come la net art, aspetto artistico, giocoso e capace di critica dell’hacking. È anche un +hackmeeting dedicato ai diritti in rete, alla cooperazione sociale, all’accessibilità in rete. Molti i seminari su etica e web. + +* **2001 - Catania - Freaknet media lab** + +Un posto particolare, visto che era nato prima degli hacklab e già si apriva al pubblico con i bollettini meteo per i pescatori, via internet, +e le tastiere in arabo per gli immigrati. È l’hackmeeting più forte dal punto di vista del numero di ore passato sul codice. Viene presentato il +progetto autistici.org/inventati.org come server autogestito che si affiancava a ecn. Viene presentato anche Bolic1, che diventerà poi +Dynebolic (the media hacktivist tool). Il Freaknet propone nell’università scientifica di Catania che si adotti il software libero +come software di base e all’hackmeeting viene proposto di estenderlo anche ad altre città. Passeranno per questo meeting anche quelli che poi +creeranno il media center del G8. Vengono proposti strumenti e persone che poi si coaguleranno per dare vita a media come Indymedia. Si inizia +a parlare di reddito e lavoro nella net economy. Strumenti tecnici: si tiene un seminario di reverse engineering, ovvero +modificare il comportamento di un programma senza conoscere il codice sorgente. + +* **2002 - Bologna - TPO** + +Hackmeeting mondano. la parola mediattivismo è uscita e diffusa, Indymedia è un media consolidato, NGvision rappresenta un archivio video +su web consistente, ci sono le telestreet, l’hackmeeeting diventa non più solo da hacker ma da attivismo media, e non a caso compaiono le +donne. Viene Richard Stallman. Strumenti tecnici: viene presentato il Retrocomputing ovvero la passione per il recupero dell’hardware. + +* **2003 - Torino - Barrio** + +Viene fatto il mitico seminario di stiraggio acrobatico e la questione genere/tecnologie viene proposta dal Sexy shock di Bologna, collettivo +di donne, sottolineando che ci sono questioni di genere anche tra hacker e che sarebbe il caso di occuparsene. Alle aule vengono dati nomi +storici dell’anarchismo. Strumenti tecnici: Honeypots, sicurezza informatica sul web sono tra gli argomenti trattati. Wireless diffuso. + +* **2004 - Genova - Buridda** + +Si apre ulteriormente l’ambito, vengono presentati seminari di robotica, ma anche sulla prostituzione. E sopratutto a partire da Reload di Milano +viene lanciato il concetto di reality hacking, hacking della vita quotidiana e della politica, chiedendo agli hacklab di uscire dagli +stretti ambiti nerd per entrare in quelli più allargati dell’agire politico. Strumenti tecnici: Bluetooth security uno dei seminari. + +* **2005 - Napoli - TerraTerra** + +Viene presentato Open non è free, il secondo libro che esce dalla comunità di hackmeeting. Visto che nella società iniziano a circolare i +concetti di open source e di free software, la comunità sente la necessità di sottolineare la necessità di approcciare in maniera critica +queste tematiche che sono comunque ormai assorbite anche dal mercato. Strumenti tecnici: introduzione al Phreaking, ovvero come telefonare +gratis, dal fischietto di Captain Crunch al vOIP. + +* **2006 - Parma - Collettivo Mario Lupo** + +Gli hacklab non sono più l’elemento principale di organizzazione ma c’è una percezione più comunitaria che permette l’occupazione di uno spazio +per la durata dell’hackmeeting. L’occupazione avviene in un momento ambiguo e cosparso di sgomberi nel territorio parmense e prende la forma +politica di una TAZ, anche se c’era la speranza di fare molto di più (tenere il posto, che poi invece verrà sgomberato). Nell’ambito dei +seminari si apre ulteriormente l’applicazione della filosofia hack in ambiti vari, per esempio, serpicanaro e la licenza open per la +produzione materiale, bucare un sistema che non è solo informatico ma reale e di mercato. Viene presentato The darkside of Google, altro libro +scritto da persone della comunità su aspetti ancora (allora) poco noti di Google. Strumenti tecnici: Web Semantico e Ontologie informatiche; si discute di Copyleft e fightsharing. + +* **2007 - Pisa - Rebeldia** + +Rispetto all’anno precedente si recupera di nuovo sul profilo internazionale, vengono Emmanuel Goldstein, parte della scena americana storica dei phreakers e media hacktivist. Andy Muller Maghun, membro del CCC, esordisce dicendo “il CCC nasce come progetto politico”, segno di come in Europa sin dall’82 si considerava il potenziale politico dell’hacking come concetto, Armin Medosh, che fa una ricostruzione storica in chiave marxista dell’evoluzione tecnologica. Appaiono seminari che impongono una presa di coscienza collettiva ecologica: viene fatto il seminario “hack the bread”, che riporta l’accento su pratiche politiche anche a livello personale. Viene introdotto lo spazio capanne dei suchi, uno spazio diverso dal workshop, di discussione libera e lavoro in comune. Strumenti tecnici: metodi di compromissione dell’anonimato, come difendersi. Voip Security, necessità di attenzione anche su Voip. IPSec, Meccanismi per proteggersi da attacchi basati sull’analisi statistica del traffico (Web site fingerprinting, etc ). + +* **2008 - Palermo - AsK 191** + +Hackmeeting importante per il luogo, l’incontro con le persone dell’Ask ha prodotto un momento di autogestione in comune molto forte. Conferma +spirito forte comunitario, non molto aperto perché non c’era risposta da parte del pubblico palermitano. L’impronta ecologica continua, si parla +di compost, di rifiuti, di energia solare e onde radio. Sharing not exploiting: Prosumer vs. Corporation, riflessione su social network e +web 2.0, ritorni economici delle corporation. Dal punto di vista dell’immaginario compare il workshop sullo steampunk, il dopo cyberpunk. +Strumenti tecnici: Web semantico, come approccio al web 3.0 + +* **2009 - Rho - Fornace** + +Di nuovo l’hackmeeting va a supportare un’autogestione in difficoltà. Lo scenario è Rho, hinterland milanese devastato dalla speculazione Expo, +un enorme capannone vuoto occupato da pochi giorni. Si parla di paura, di creazione della paura, di come uscire da questo modello sociale di +persone spaventate, che si guardano in cagnesco. L’icona dell’hackit è il babau, il cattivo delle favole. Si stabilizza all’interno delle +tematiche l’interesse per la questione precariato e modelli di vita conseguenti. Si inaugura la pratica dei warm up, seminari che introducono nelle settimane precedenti sia nella città ospite, che nel resto d’Italia l’evento principale. A livello di immaginario si parla di fantascienza, di retrocomputing e restauro, videogiochi per cellulari. Strumenti tecnici: streaming audio/video giss, sniffjoke, reti gsm, reti mesh + +* **2010 - Roma - La Torre** + +Hackmeeting tra gli ulivi nel caldo romano, tutti in tenda, ci si riprende dall’hinterland milanese dell’anno prima. Si parla di controllo, di quanto ne abbiamo intorno, di quali strumenti utilizza. Le tematiche ecologiste rientrano dalla porta principale con il seminario sulle pale eoliche, la presentazione della rete per l’autocostruzione e il seminario sugli orti urbani. Nel lan space presenti sempre più arduini, e un modello di elicottero radiocomandato. Ospite dell’hackit Margaret killjoy, un buffo personaggio dello Steampunk Magazine, un rivista autoprodotta americana, presentata assieme a Ruggine, una rivista autoprodotta italiana di racconti e disegni. Affollatissimo il seminario di pr0n, misterisca e intrigante estensione di firefox. Strumenti tecnici: ipv6 e reti mesh, opencv, arduino. + +* **2011 - Firenze - csa nExt Emerson** + +Il tema di questa edizione è stato quello dell’apocalisse. Dalle nuvole dei disastri nucleari alle nuvole del cloud computing: la tecnologia e la conoscenza quando centralizzate per interessi economici e politici e in contrasto con le aspirazioni individuali e collettive di autonomia portano inevitabilmente alla… apocalisse. + +* **2012 - L’Aquila - Asilo Occupato** + +Una presenza significativa in una città come L’Aquila che non assomiglia più ad una città. Hack the town!! Se non è più possibile riparare i danni, dare un senso a ciò che è andato distrutto, hackmeeting prova a capire se è possibile farla funzionare in un altro modo, partendo dalla ricostruzione dei tessuti sociali e relazionali, delle connessioni vitali della città. + +* **2013 - Cosenza - Ex-Officine** + +Si è tenuto nell’area occupata delle ex officine Ferrovie della Calabria ed ha avuto come tema la “iattura del controllo”. L’idea dell’Hackmeeting 2013 era quello di stimolare una nuova saggezza popolare 2.0 per far fronte alle forze avverse che minacciano le libertà di espressione e di condivisione nella rete. Neanche a farlo apposta, fra iatture e superstizioni, proprio nei giorni di quest’hackmeeting escono le prime rivelazioni di Snowden. +L’attività di chi controlla i movimenti in rete, per affari, o per controllo è il tema chiave, ma gli argomenti trattati sono stati molteplici: dalla privacy alle tecnologie di comunicazione, dalla contrasessualità alle relazioni di inchiesta sui software spia utilizzati da governi e non. Degno di nota è anche l’esperimento di media trolling che porta hackmeeting sulle pagine dei più importanti quotidiani nazionali attraverso un divertente e totalmente infondato “scoop”. + +* **2014 - Bologna - XM24** + +Xm24 ospita gli ultimi 3 giorni di un hackmeeting durato molto più a lungo: +l'articolato percorso di warmup cittadino, coordinato dall'hacklabbo ma che +vede la partecipazione di molte realtà, antagoniste e non, porta ad un'edizione +particolarmente partecipata. + +Grazie alla lunga storia mediattivista di Xm24, la visibilità e il carattere +universitario di Bologna e alla rete di comunità che si intrecciano nella lista +hackmeeting prende vita un evento che dimostra alla sua stessa comunità come la +scena sia tutt'altro che morta, ma anzi particolarmente attenta e attiva. +Durante le tre giornate la necessità e la centralita' di un evento costruito +dal basso viene riaffermato con forza non soltato dalla partecipazione della +comunità storica, ma anche dalle assemblee di comunita' trasversali ad +hackmeeting(eg. quella delle WCN italiane), l'affacciarsi di molti volti nuovi +e i moltissimi talk di grande attualità (eg. Citizen Lab con il lavoro sulla +sorveglianza digitale). + +PS: il logo è un non morto, non un gorilla, non un fattone ;) + +* **2015 - Napoli - Mensa occupata** + +Dopo dieci anni Hackmeeting torna a Napoli e si riprende il centro della città. + +La collocazione centralissima della Mensa Occupata favorisce lo svolgimento di un hackmeeting di livello non esclusivamentetecnico e molto divulgativo. A meno di due mesi del primo maggio e delle lotte contro Expo, la riflessione sul lato più politico e militante dell'hacking si impone: tecniche di autodifesa neuro-digitali, studio delle legislazioni in materia di intercettazioni, Tor, crittografia e resistenza digitale. Alla comunità si è aggiunta tanta gente nuova e questa diventa l'occasione per reinventarsi. Si scopre che i fritti favoriscono la concentrazione. + +* **2016 - Pisa - Polo Fibonacci** + +Polo Fibonacci, l'hackmeeting si ritrova a Pisa il 3-5 Giugno e occupa un polo +universitario riempiendolo di giochi, feste, workshop e dibattiti. Per parlare di +tecnologia, di privacy, di sicurezza, ma anche di differenze, di gender e di +piu' inclusione all'interno del hackmeeting. + +Si analizzano malware, si discute di crittografia quantistica e +ci si ritrova a giocare a retrogame alle 3 di mattina tra musica punk e la +birra che ormai e' finita da un po' + +I bagni non divisi per genere si chiamano come gli editor: VIM, NANO o EMACS, mentre +alcune faccie internazionali e non rispondo ad email e scrivono pezzi di python nel mezzo del Lan Space +mentre altri cercano per la prima volta di installare Linux. + +L'attenzione si sposta parecchio sui malware, anche detti captatori informatici +si prova ad analizzarli e vedere la demo di hacking-team, poi Ippolita presenta [Anime Elettriche](http://www.vita.it/it/interview/2016/04/27/anime-elettriche-corpi-digitali-linee-di-fuga-e-tattiche-di-resistenza/52/) e la sera +alcuni propongono giochi sulla comprensione del consenso, tavole rotonde sulle +discussioni di genere e tentativi di migliorare la comunita' +Poi all'improvviso e' gia' domenica e abbracci e baci, si accolla il prossimo +hackit ai Torinesi, ci vediamo in Val Susa. + +* **2017 - Venaus, Val di Susa - Borgata 8 Dicembre e Presidio permanente** + +E' il ventesimo hackmeeting e per celebrare l'occasione, si pensa di +farlo in un posto diverso. L'idea gira in lista, piace subito e così si parte. +Si impara a saldare, a fare il dado vegetale, a costruire un'antenna, a +farsi il formaggio con il latte di capra. +Si parla di sicurezza digitale, di anonimato, di fisica quantistica, di +cyberspionaggio, di pokemon, di controllo, di radio e di reti mesh. +Ci si mischia con i resistenti valsusini, ci si contagia, si scambiano +racconti, esperienze, sogni.La comunità condivide con la valle, la valle si racconta alla comunità. +Si dorme in tenda si cucina e ci si lava all'aperto, si cena al cantiere +di Chiomonte, si cammina in montagna. + +Tagliare le reti, insomma, ci sta! + +* **2018 - Buridda Genova** + +Dopo 14 anni hackmeeting torna a Genova, nelle stanze del Buridda. +L'impronta del luogo è sicuramente l'attenzione all'autocostruzione, ma +non mancano dibattiti storici come la presentazione del numero di +Zapruder (numero dedicato all'hacking), una spiegazione pratica degli +avanzamenti crittografici negli ultimi anni, un workshop con pc e USB +alla mano come quello su Tails ed anche confronti interessanti e +contraddittori sui temi tecnici e politici come quello sul voto elettronico. +Viene presentato Stop al Panico, una raccolta di suggermenti tecnici e +legali da affrontare in caso di sequestro, si parla di sistemi operativi +alternativi per cellulari. +Si discute di social, di nolike e dell'uso tossico di questi strumenti, +riflettendo su come riappropriarci delle tecnologie "social" anche +presentando l'esperimento Bolognese di mastodon.bida.im +Dopo 3 giorni intensi, l'assemblea della domenica è molto partecipata: +scopriamo che i posti che hanno ospitato l'hackmeeting riprendono +energie mentre in varie città stanno nascendo vari hacklab mossi non +solo dalla volonta di smontare e comprendere la tecnologia come un tempo +o dalla mancanza di internet in casa, ma dal desiderio di incontrarsi, +discutere e condividere le impressioni su questi strumenti che oggi +abbiamo intorno e cercare alternative comuni insieme. +Ultimo giro al bar, dove quest'anno la birra non e' ancora finita, poi +una tuffo al mare per chi riesce, saluti sparsi a tutte le creature di +questo hackmeeting con la promessa di rivederci presto a sud a nord +online o offline, non fa differenza, l'importante e' che ci siamo. + +* **2019 - Firenze - csa nExt Emerson** + +* **2020 - Roma - C.S.O.A Forte Prenestino** + +* **2021 - Bologna - Casona di Ponticelli** + +* **2022 - Torino - C.S.O.A Gabrio** + +* **2023 - Gallico Marina, Reggio Calabria - CSOA Angelina Cartella** diff --git a/content/pages/warmup.rst b/content/pages/warmup.rst new file mode 100644 index 0000000..1ccb157 --- /dev/null +++ b/content/pages/warmup.rst @@ -0,0 +1,245 @@ +Warmup +====== + +:slug: warmup +:navbar_sort: 5 +:lang: it + +Cosa sono +""""""""""""""""""""""""""""""""""""""" + +I warmup sono eventi "preparatori" ad hackmeeting. Avvengono in giro per l'Italia, e possono trattare gli argomenti più disparati. + +Proporre un warmup +""""""""""""""""""""""""""""""""""""""" + +Vuoi fare un warmup? ottimo! + +* iscriviti alla `mailing list di hackmeeting `_. +* scrivi in mailing list riguardo al tuo warmup: non c'è bisogno di alcuna "approvazione ufficiale", ma segnalarlo in lista è comunque un passaggio utile per favorire dibattito e comunicazione. + + +Elenco +""""""""""""""""""""""""""""""""""""""" +.. contents:: :local: + +========================== + +Fighting Technologies of Domination: From decentralised event platforms to the right to analogue +------------------------------------------------------------------------------------------------- + +Domenica 9 giugno @ Disruption Network Lab (Berlino) + +https://www.disruptionlab.org/event/fighting-technologies-of-domination + +Si discuterà del diritto a vivere senza smartphone e di software fuori dal radar GAFAM con il collettivo Balotta.org di Bologna che condurrà un laboratorio su Gancio. Oltre a balotta ci sarà Agnese del collettivo [C.I.R.C.E.](https://circex.org) a moderare e Roberta Barone che approfondirà il tema del diritto a non avere uno smartphone mostrando alcune clip dal documentario ["Digital Dissidents"](https://digitalnisvobody.cz/wp-content/uploads/2022/09/Digitalni-disidenti_ABOUT-FILM.pdf). [Qui il trailer](https://iteroni.com/watch?v=qd9VGM4Q3WI). + +* 15:00-16:30: Open discussion – From decentralised platforms to the right to analogue. + +The first part of the meetup will be dedicated to an open discussion, on the one hand to name the contradictions of the acritical adoption of smartphones and to give a voice and a framework to doubts, questions and demands that remain largely unspoken, and on the other hand to explore the possibilities of grassroots technologies and decentralised open-source software to share events and collect experiences beyond the use of social media platforms. + +* 16:45-18:15: Gancio and Balotta.org – Exploring open-source software for event publishing. + +After a short break, the second part of the meetup will be hosted by the Balotta Collective (Italy) and we will delve deeper into the exploration of Gancio. + +Born in Turin (Italy) out of political hacking movements, Gancio is a free open-source software designed for event publishing. + + + +Oooh issaa! ...ooooh issaaa! il MIAI salpa! +-------------------------------------------- + +Naviganti! dal primo marzo scioglieremo le vele e tireremo su l’ancora. Si riparte con l’allestimento del MIAI! Fino ad ora abbiamo pulito, ristrutturato, ammobiliato, allestito parte della Biblioteca e realizzato un affresco :) Si è fatta ora di affrontare la massa. La quantità di materia informatica che attende ormai da troppo tempo di essere liberata dal suo involucro di plastica e cartone per ritornare alla luce nel pieno del suo splendore. I pallet sono lì...intombati...aspettano soltanto noi! + +Grazie anche ad Hackmeeting abbiamo resistito. +Questo museo è frutto anche di questa comunità. + +per chiarezza, i primi fine settimana dei prossimi mesi sono piccoli Warm Up di costruzione del MIAI in attesa dell'appuntamento Hackmeeting a Brescia :) + +E' l'occasione per scoprire i reperti, familiarizzare, prendersene cura, riaccenderli. + +* Ecco le date dei venerdì-sabato-domenica: + +1-2-3 marzo + +5-6-7 aprile + +3-4-5 maggio + +31 maggio 1-2 giugno + +5-6-7 luglio inizia il Cool Down con sessione di restauro del GE-120 da tenersi il 26-27-28 ultimo fine settimana di luglio. + +Questi sono appuntamenti fissi, ma se qualcun in transito volesse fermarsi in date diverse, male non fa! + +Per informazioni su ospitalità e altro scrivete a info@verdebinario.org + +Ti invitiamo a salire a bordo e a dare una mano in questa impresa! + +Obiettivo? + +Allestire il Museo Interattivo di Archeologia Informatica - MIAI. + +Quando? + +Ogni primo fine settimana del mese da marzo a luglio, qui al MIAI, in Calabria, a Rende (CS) -Via C.B.Cavour 4. + +Ospitalità? + +Provate a organizzarvi e nel caso vogliate un supporto contattateci in privato. + +E se non posso venire? + +Siamo liet* anche di un piccolo/grande contributo monetario che è utile per affrontare gli imprevisti di un allestimento di questo genere + +E alla fine? + +Cool Down! Dopo Hackmeeting 2024, una sessione di restauro del GE-120 da tenersi il 26-27-28 ultimo fine settimana di luglio! + +E alla fine fine? + +Arrivare in porto, attraccare e vivere il MIAI funzionante! + + +Museo Interattivo di Archeologia Informatica - MIAI https://miai.musif.eu/ + + + +Questo titolo non è autogenerato +--------------------------------- + +Martedì 28 maggio @ via Mascarella 59A ZEM GARDEN (Bologna) + +https://balotta.org/event/questo-titolo-non-e-autogenerato + +Tranquillu il tuo lavoro da titolista sopravviverà alle AI. + +Una serata dedicata al futuro dell'intelligenza artificiale insieme al collettivo Hacklabbo. + + + +RADIO EUSTACHIO: due giorni di incontri, costruzioni, accrocchi e musica! +-------------------------------------------------------------------------- + +Sabartolomenica 25 e 26 maggio @ Gigi Piccoli (Verona) + +https://lasitua.org/event/radio-eustachio-due-giorni-di-incontri-costruzioni-accrocchi-e-musica + + +**sabato 25/05** + +* ore 11.00: Come funziona lo strumento radio: onde medie e corte + +* ore 15.00: Calendari condivisi. Presentazione di Gancio e le istanze gancio.cisti.org, balotta.org e lasitua.org + +* ore 17.00: Autocostruzione di un ricevitore AM (o qualcosa di simile) + +* ore 19.00: Concerto con i Kani Sholty e a seguire selecta musicale con djset eustachiani! + +**domenica 26/05** + +* ore 11.00: Mercato autoproduzioni del Gigi Piccoli con diretta a microfono aperto + +* ore 15.00: Chiacchiera su Gancio: una proposta per un calendario condiviso locale + +* ore 17.00: Concerto e streaming di DucalicRock! con The Slurmies e Maybe Wonders + +Radio Eustachio ha un blog: https://eustachio.indivia.net/blog + +Il tutto si svolgerà al Gigi Piccoli, in via Caroto 1, Verona + + + +Presentazione A-K-M-E, astro cyber crypto bluff +------------------------------------------------ + +Sabato 25 maggio @ Piano Terra Lab (Milano) + +* ore 19.30 cibo per tutti i palati + +* ore 20.30 presentazione dei libri Cyber bluff e Crypto bluff con l’autore ginox + +Cyber bluff, Collana BookBlock, Eris edizioni + +Sono poche le persone che si interrogano sulla rete a cui questi servizi si appoggiano per capire da dove viene, com’è nata e da chi è controllata. Sappiamo come funziona questo strumento, questa rete che è onnipresente nelle nostre vite? Sappiamo dove vanno i nostri dati e chi ne trae profitto? Abbiamo davvero bisogno di comunicazioni istantanee? Internet è davvero democratico? Il libro descrive i servizi online più diffusi, raccontandone la genesi, il funzionamento, e fornendo alcuni consigli utili per utilizzarli in maniera più consapevole. + +Crypto bluff, Collana BookBlock, Eris edizioni + +Bitcoin e NFT, blockchain e miner: questi termini provocano reazioni contrastanti. Da un lato suscitano un forte hype, dall’altro appaiono come l’ennesima bolla finanziaria speculativa, neppure troppo raffinata. Non si tratta di un libro su come svoltare. L’obiettivo è spogliare le criptovalute dal glamour che le circonda e spiegare come la componente rivoluzionaria e libertaria di cui si fregiano sia solo una strategia di marketing. + +* ore 22:00 Acaroroscopo, ovvero l’oroscopo che non ti aspettavi! Musica live e testi a cura di Lobo + +Cosa accade quando un hacker decide di darsi all’astrologia? Vieni a scoprire finalmente cosa dicono le stelle del tuo benessere digitale e della tua privacy. Con l’Acaroroscopo, la tua guida all’hacking astrale, i misteri informatici del tuo destino non avranno piu’ segreti! + +* ore 23:00 Low-tech live di Pablito el drito + +25 maggio a partire dalle 19:30 + +https://akme.vado.li + +https://www.pianoterralab.org/events/a-k-m-e-astro-cyber/ + + + +Assemblea di istanza mastodon bida.im e pranzo di autofinanziamento +------------------------------------------------------------------- + +Domenica 19 maggio 2020 dalle 12.00 @ Spazio Libero Autogestito @Vag61 (in via Paolo Fabbri 110 a Bologna) + +https://bida.im/news/quarta-assemblea-generale-distanza-mastodon-bida-im/ + + + +Presentazione del libro Cyber Bluff (Catania) +---------------------------------------------- + +Sabato 18 maggio @ Laboratorio Urbano Popolare Occupato (in Piazza Pietro Lupo 25, Catania) + +Presentazione del libro Cyber Bluff: storie rischi e vantaggi della rete per navigare consapevolmente (2021, eris). Discuteremo e approfondiremo insieme all'autore Ginox dei temi trattati nel libro. + +https://www.attoppa.it/event/presentazione-di-cyber-bluff + + + +Presentazione Antennine/Ninux in appennino + cena benefit +---------------------------------------------------------- + +Lunedì 13 Maggio @ Circolo Anarchico Berneri, Bologna (BO) + +https://circoloberneri.indivia.net/events/event/presentazione-del-progetto-antennine-in-appennino-bolognese-e-cena-di-autofinanziamento + + + +Brugole e merletti +------------------- + +10-11-12 maggio @ NextEmerson Via di Bellagio 15 - Firenze + +https://doityourtrash.noblogs.org/ + + + +Instant Messaging e sicurezza +------------------------------ + +10 maggio a partire dalle 21:00 @ Pianoterra Lab, Milano +https://www.pianoterralab.org/events/a-k-m-e-instant-messaging/ + +Sono cambiati i mezzi con i quali comunichiamo: sempre meno si usano email, sempre di più le app da cellulare, in particolare, per la messaggistica istantanea. L’Instant Messaging è diventato il sistema di comunicazione più diffuso, anche nell’organizzazione del lavoro. Usati spesso da attivist* e agitator* a causa della loro enorme diffusione, questi sistemi immediatamente disponibili sono diventati un obbiettivo appetibile. La vulnerabilità di queste applicazioni può così mettere a rischio la libertà, la privacy e la sicurezza delle persone. Crittografia asimmetrica, metadati, immagini, backup, codice sorgente, ne discutiamo in una tavola rotonda allargata sulla base di strategie e alternative disponibili. + +con samba – underscore hacklab (Torino) + +10 maggio a partire dalle 21:00 + +A-K-M-E + +https://akme.vado.li + + + +Workshop mappe dalla carta al digitale +--------------------------------------- + +Martedì 9 aprile @ Vag 61, via Paolo Fabbri 110, Bologna (BO) + +https://ciemmona.noblogs.org/workshop-mappe-dalla-carta-al-digitale/ diff --git a/dev-utils/ics2yaml.py b/dev-utils/ics2yaml.py new file mode 100755 index 0000000..97e48eb --- /dev/null +++ b/dev-utils/ics2yaml.py @@ -0,0 +1,222 @@ +#!/usr/bin/python3 + +import logging +import argparse +import os.path +from typing import Iterable +from pathlib import Path +from datetime import timedelta +import json + +import yaml +from icalendar import Calendar, Event + + +def get_parser(): + p = argparse.ArgumentParser() + p.add_argument("files", nargs="+", type=str) + p.add_argument("--hm-json", default='./hackmeeting.json', type=Path) + p.add_argument( + "--out-talks-dir", + help="Output directory for markdown files", + default="talks/", + type=Path, + ) + p.add_argument("--trust-location", type=str, nargs="*", default=[]) + p.add_argument( + "--slot-size", + type=int, + metavar="MINUTES", + default=15, + help="Round times to the nearest */MINUTES", + ) + p.add_argument("--night-threshold", metavar="HOUR", default=5, type=int) + p.add_argument("--mode", choices=["pelican"], default="pelican") + return p + + +def round_down(num, divisor): + """ + >>> round_down(1000, 10) + 1000 + >>> round_down(1001, 10) + 1000 + >>> round_down(1009, 10) + 1000 + """ + return num - (num % divisor) + + +def round_down_time(hhmm: str, divisor: int): + hh = hhmm[:-2] + mm = hhmm[-2:] + mm = round_down(int(mm, base=10), divisor) + return int('%s%02d' % (hh,mm) , base=10) + + +class Converter: + """ + This class takes care of everything converter-related. + + Objects are used to enable multiple output formats to be added pretty easily by subclassing + """ + + def __init__(self, args): + self.args = args + self.rooms = [] + self.talks = {} + self.talk_room = {} # map talk uid to room name + self.talk_location = {} # same, but see --trust-location + self.changed_files = [] + + def _fname_to_room(self, fpath: str) -> str: + return os.path.splitext(os.path.basename(fpath))[0] + + def get_vevents_from_calendar(self, cal: Calendar) -> Iterable[Event]: + for subc in cal.subcomponents: + if type(subc) is Event: + yield subc + + def load_input(self): + with self.args.hm_json.open() as buf: + self.hackmeeting_metadata = json.load(buf) + for fpath in self.args.files: + room = self._fname_to_room(fpath) + with open(fpath) as buf: + file_content = buf.read() + cal = Calendar.from_ical(file_content, multiple=True) + for subcal in cal: + for ev in self.get_vevents_from_calendar(subcal): + if ev.decoded('DTSTART').year != self.hackmeeting_metadata['year']: + continue + uid = ev.decoded("uid").decode("ascii") + self.talks[uid] = ev + self.talk_room[uid] = room + self.talk_location[uid] = room + if fpath in self.args.trust_location: + try: + self.talk_location[uid] = ev.decoded("location").decode( + "utf8" + ) + except: + pass + + def run(self): + self.rooms = [self._fname_to_room(fpath) for fpath in self.args.files] + self.load_input() + self.output() + for fpath in self.changed_files: + print(fpath) + + +class PelicanConverter(Converter): + """ + add relevant output features to the base converter + """ + + def load_input(self): + super().load_input() + talks_meta = self.args.out_talks_dir / 'meta.yaml' + with talks_meta.open() as buf: + self.talks_metadata = yaml.safe_load(buf) + + def output_markdown(self): + for uid in sorted(self.talks): + talk = self.talks[uid] + fname = 'meta.yaml' + talkdir = self.args.out_talks_dir / uid + talkdir.mkdir(exist_ok=True) + fpath = talkdir / fname + self.changed_files.append(fpath) + day = (talk.decoded('DTSTART').date() - self.talks_metadata['startdate']).days + frontmatter = dict( + key=uid, + title=talk.decoded("SUMMARY").decode("utf8"), + format="conference", + start=talk.decoded("DTSTART"), + time=talk.decoded("DTSTART").strftime('%H:%M'), + day=day, + end=talk.decoded("DTEND"), + room=self.talk_location[uid], + duration=int( + (talk.decoded("DTEND") - talk.decoded("DTSTART")).total_seconds() + // 60 + ), + tags=[], + ) + if "CATEGORIES" in talk: + try: + vobject = talk.get("CATEGORIES") + if hasattr(vobject, "cats"): + vobject = vobject.cats + frontmatter["tags"] = [str(t) for t in vobject] + else: + frontmatter["tags"] = [str(vobject)] + except Exception as exc: + logging.warning("Error parsing categories: %s", str(exc)) + if "base" in frontmatter["tags"]: + frontmatter["level"] = "beginner" + if "DESCRIPTION" in talk: + frontmatter['text'] = talk.decoded("DESCRIPTION").decode("utf8") + else: + frontmatter['text'] = '' + with open(str(fpath), "w") as buf: + yaml.safe_dump(frontmatter, buf) + # body + + def output_schedule(self): + days = {} + for uid in sorted(self.talks): + talk = self.talks[uid] + # TODO: talk just after midnight should belong to the preceding day + dt = talk.decoded("dtstart") + after_midnight = dt.time().hour < self.args.night_threshold + if after_midnight: + dt = dt - timedelta(days=1) + day = dt.strftime("%Y-%m-%d") + + hour = talk.decoded("dtstart").time().hour + minute = talk.decoded("dtstart").time().minute + if after_midnight: + hour += 24 + + start = "%02d:%02d" % (hour, minute) + if day not in days: + days[day] = dict(day=day, start=start, rooms={}) + if days[day]["start"] > start: + days[day]["start"] = start + + room = self.talk_room[uid] + days[day]["rooms"].setdefault(room, dict(room=room, slots=[])) + + talkstart = round_down_time('%02d%02d' % (hour, minute), self.args.slot_size) + duration = talk.decoded("dtend") - talk.decoded("dtstart") + duration_minutes = int(duration.total_seconds() // 60) + duration_minutes = round_down(duration_minutes, self.args.slot_size) + slot = "%04d-%dmin" % (talkstart, duration_minutes) + days[day]["rooms"][room]["slots"].append(dict(slot=slot, talk=uid)) + + # convert from our intermediate format to the correct one + for d in sorted(days): + # vanity: let's sort + for room in sorted(days[d]["rooms"]): + days[d]["rooms"][room]["slots"].sort(key=lambda x: x["slot"]) + # convert dict to list + days[d]["rooms"] = [days[d]["rooms"][k] for k in sorted(days[d]["rooms"])] + out = {"schedule": [days[k] for k in sorted(days)]} + + # XXX: dump, finally + + def output(self): + self.output_markdown() + + +def main(): + converter_register = {"pelican": PelicanConverter} + args = get_parser().parse_args() + c = converter_register[args.mode](args) + c.run() + + +if __name__ == "__main__": + main() diff --git a/dev-utils/sincronizza.sh b/dev-utils/sincronizza.sh new file mode 100755 index 0000000..34633c7 --- /dev/null +++ b/dev-utils/sincronizza.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -eu + +git reset --hard HEAD +git ls-files | grep -E '^talks/.*/meta\.yaml$' | xargs -r git rm -f + +curl -s 'https://files.esiliati.org/remote.php/dav/public-calendars/2w2meG65B4p9yfLD?export' > room1.ics +curl -s 'https://files.esiliati.org/remote.php/dav/public-calendars/YpCMj9qgnWjHtAyd?export' > room2.ics +curl -s 'https://files.esiliati.org/remote.php/dav/public-calendars/grWX9kAXpyxiBTDG?export' > room3.ics +curl -s 'https://files.esiliati.org/remote.php/dav/public-calendars/RYWGzPpr2eYdXPX9?export' > extra.ics + +mkdir -p content/talks/ +"$(dirname "$0")/ics2yaml.py" room1.ics room2.ics room3.ics extra.ics | stest -f | xargs -r git add + +git commit --author='calendarioBot ' -m 'update calendar from remote ICS file' diff --git a/hackmeeting.json b/hackmeeting.json new file mode 100644 index 0000000..8ab7e4b --- /dev/null +++ b/hackmeeting.json @@ -0,0 +1,12 @@ +{ + "year": 2025, + "location": { + "name": "Sa domu", + "website": "", + "city": "Cagliari", + "address": "", + "geo": { + } + }, + "when": "30 Maggio - 1 Giugno 2025" +} diff --git a/new-year.md b/new-year.md new file mode 100644 index 0000000..58dae6f --- /dev/null +++ b/new-year.md @@ -0,0 +1,12 @@ +Anno nuovo sito nuovo +========================= + +Come fare un sito per l'anno nuovo, abbastanza simile a quello vecchio? + +copia ed aggiorna le date. Dove? + +* `README.md` +* `content/pages/index.*` ci sono le date/luogo +* `content/pages/info*` c'è sicuramente roba da cambiare +* `hackmeeting.json` cambia il campo `year` +* `talks/meta.yaml`: cambia la startdate: deve essere quella del primo giorno da mettere in programma. Siccome a volte ci sono anche cose dal mercoledì, per prudenza indica il mercoledì come giorno di inizio. diff --git a/pelicanconf.py b/pelicanconf.py new file mode 100644 index 0000000..b627848 --- /dev/null +++ b/pelicanconf.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- # +from __future__ import unicode_literals + +import json +import math +with open('hackmeeting.json') as buf: + hm_metadata = json.load(buf) + + +# Non so dove metterla quindi le metto qui, poi vediamo + +def geo_to_bbox(lat, lon, zoom): + width = 425 + height = 350 + # m/pixel at zoom level + # see https://wiki.openstreetmap.org/wiki/Zoom_levels to change + meters_pixel = 156543/(2**zoom) + r_earth = 6371000 + + dy = (width/2)*meters_pixel + dx = (height/2)*meters_pixel + latitude = lat + longitude = lon + lat_s = latitude + (dy / r_earth) * (180 / math.pi) + lon_s = longitude + (dx / r_earth) * (180 / math.pi) / math.cos(latitude * math.pi/180) + lat_e = latitude - (dy / r_earth) * (180 / math.pi) + lon_e = longitude - (dx / r_earth) * (180 / math.pi) / math.cos(latitude * math.pi/180) + bbox = f"{lon_s}%2C{lat_s}%2C{lon_e}%2C{lat_e}" + + return bbox + + +# da un anno all'altro cambiare solo la variabile YEAR è sufficiente per le operazioni più base! +YEAR = hm_metadata['year'] + +EDITION = hex(YEAR - 1997) +AUTHOR = "Hackmeeting" +SITENAME = "Hackmeeting %s" % EDITION +CC_LICENSE = "by-nc-sa" +SITEURL = "/hackit%d" % (YEAR - 2000) + +JINJA_GLOBALS = { 'hm': { 'edition': EDITION, **hm_metadata, 'osm': { 'bbox': geo_to_bbox(hm_metadata['location']['geo']['lat'], hm_metadata['location']['geo']['lon'], 18) } } } + +PATH = "content" +PAGE_PATHS = ["pages"] +ARTICLE_PATHS = ["news"] +STATIC_PATHS = ["images", "talks", "extra"] +# DIRECT_TEMPLATES = ('search',) # tipue search + +TIMEZONE = "Europe/Paris" + +DEFAULT_LANG = "it" + +# Feed generation is usually not desired when developing +INDEX_SAVE_AS = "news.html" +ARTICLE_URL = "news/{slug}.html" +ARTICLE_SAVE_AS = "news/{slug}.html" +FEED_DOMAIN = "https://it.hackmeeting.org" +FEED_ALL_ATOM = "news.xml" +CATEGORY_FEED_ATOM = None +TRANSLATION_FEED_ATOM = None +AUTHOR_FEED_ATOM = None +AUTHOR_FEED_RSS = None + +# Blogroll +LINKS = None +# Social widget +SOCIAL = None +DEFAULT_PAGINATION = 10 +USE_OPEN_GRAPH = False # COL CAZZO + +# Uncomment following line if you want document-relative URLs when developing +RELATIVE_URLS = True + +DEFAULT_DATE = (YEAR, 3, 1) +TYPOGRIFY = True + +PAGE_ORDER_BY = "navbar_sort" +PAGE_URL = "{slug}.html" +PAGE_SAVE_AS = "{slug}.html" +PAGE_LANG_URL = "{slug}.{lang}.html" +PAGE_LANG_SAVE_AS = "{slug}.{lang}.html" +BANNER = True +BANNER_ALL_PAGES = True +SITELOGO = "logo/logo.png" +# PAGE_BACKGROUND = 'images/background.jpg' +# THEME = 'themes/hackit0x15/' +THEME = "themes/to0x19/" +FAVICON = "images/cyberrights.png" +FONT_URL = "theme/css/anaheim.css" + +# Custom css by sticazzi. +# CUSTOM_CSS = 'theme/css/hackit.css' +EXTRA_PATH_METADATA = { + # 'extra/main.css': {'path': 'themes/pelican-bootstrap3/static/css/main.css' }, + "extra/favicon.png": {"path": "images/favicon.png"}, + "images/locandina.jpg": {"path": "images/locandina.jpg"}, +} + +# Pelican bootstrap 3 theme settings +BOOTSTRAP_THEME = "darkly" +HIDE_SITENAME = True +HIDE_SIDEBAR = True +PLUGIN_PATHS = ["plugins"] +PLUGINS = ["langmenu", "talks", "tipue_search", "pelican_webassets", "pelican.plugins.jinja2content"] + +# plugin/talks.py +SCHEDULEURL = "https://hackmeeting.org" + SITEURL + "/schedule.html" +TALKS_GRID_STEP = 15 + +MARKDOWN = {"extension_configs": {"markdown.extensions.toc": {}}} + diff --git a/plugins/langmenu.py b/plugins/langmenu.py new file mode 100644 index 0000000..6637719 --- /dev/null +++ b/plugins/langmenu.py @@ -0,0 +1,39 @@ +''' +This plugin attemps to create something similar to menuitems, +but more meaningful with respect to l10n +''' +from __future__ import print_function + +from pelican import signals + + +def add_localmenuitems(generator): + menu = {} # lang: list of pages + for page in generator.context['pages']: + menu.setdefault(page.lang, []) + for tr in page.translations: + menu.setdefault(tr.lang, []) + print('we have langs ' + ','.join(menu.keys())) + for page in sorted(generator.context['pages'], + key=lambda x: int(x.navbar_sort)): + defined_langs = [] + menu[page.lang].append(page) + defined_langs.append(page.lang) + for tr in page.translations: + menu[tr.lang].append(tr) + defined_langs.append(tr.lang) + for lang in menu.keys(): + if lang not in defined_langs: + menu[lang].append(page) + + menuitems = {} + for lang in menu: + menuitems[lang] = [] + for page in menu[lang]: + menuitems[lang].append((page.title, page.url)) + + generator.context['LOCALMENUITEMS'] = menuitems + + +def register(): + signals.page_generator_finalized.connect(add_localmenuitems) diff --git a/plugins/pelican_webassets/__init__.py b/plugins/pelican_webassets/__init__.py new file mode 100644 index 0000000..8d86dde --- /dev/null +++ b/plugins/pelican_webassets/__init__.py @@ -0,0 +1 @@ +from .assets import register diff --git a/plugins/pelican_webassets/assets.py b/plugins/pelican_webassets/assets.py new file mode 100644 index 0000000..e11751d --- /dev/null +++ b/plugins/pelican_webassets/assets.py @@ -0,0 +1,64 @@ + +from pelican import signals +import os + +from webassets import Environment +from webassets.ext.jinja2 import AssetsExtension + +import logging +logger = logging.getLogger(__name__) + + +def add_extension(pelican): + """add webassets' jinja2 extension to pelican""" + jinja_env = pelican.settings['JINJA_ENVIRONMENT'] + if type(jinja_env) == dict: # pelican 3.7+ + jinja_env = jinja_env['extensions'] + jinja_env.append(AssetsExtension) + logger.debug("'pelican-webassets' added to jinja2 environment") + + +def create_environment(generator): + """define the webassets environment for the generator""" + + theme_static_dir = generator.settings['THEME_STATIC_DIR'] + assets_destination = os.path.join(generator.output_path, theme_static_dir) + generator.env.assets_environment = Environment( + assets_destination, theme_static_dir) + + # are we in debug mode? + in_debug = generator.settings.get( + 'WEBASSETS_DEBUG', logger.getEffectiveLevel() <= logging.DEBUG + ) + if in_debug: + logger.info("'webassets' running in DEBUG mode") + generator.env.assets_environment.debug = in_debug + + # pass along the additional congiuration options + for item in generator.settings.get('WEBASSETS_CONFIG', []): + generator.env.assets_environment.config[item[0]] = item[1] + logger.debug( + "'webassets' adding config: '%s' -> %s", + item[0], item[1] + ) + + # pass along the named bundles + for name, args, kwargs in generator.settings.get('WEBASSETS_BUNDLES', []): + generator.env.assets_environment.register(name, *args, **kwargs) + logger.debug("'webassets' registered bundle: '%s'", name) + + # pass along the additional directories for webassets + paths = ( + generator.settings['THEME_STATIC_PATHS'] + + generator.settings.get('WEBASSETS_SOURCE_PATHS', []) + ) + logger.debug("'webassets' looding for files in: %s", paths) + for path in (paths): + generator.env.assets_environment.append_path( + os.path.join(generator.theme, path) + ) + + +def register(): + signals.initialized.connect(add_extension) + signals.generator_init.connect(create_environment) diff --git a/plugins/talks/__init__.py b/plugins/talks/__init__.py new file mode 100644 index 0000000..64e7f13 --- /dev/null +++ b/plugins/talks/__init__.py @@ -0,0 +1,3 @@ +from .talks import * + +# flake8: noqa diff --git a/plugins/talks/style.css b/plugins/talks/style.css new file mode 100644 index 0000000..bca9fb5 --- /dev/null +++ b/plugins/talks/style.css @@ -0,0 +1,104 @@ + +.talk-resources { + word-break: break-all; +} + +.talk-grid { + table-layout: auto; + min-width: 100%; + border-collapse: separate; + text-align: center; +} + +.talk-grid > thead th:first-child { + max-width: 5em; +} + +.talk-grid > thead th { + text-align: center; +} + +.talk-grid tr { + height: 1.5em; +} + + +.rooms-4 .talk { + width: 25%; +} + +.rooms-3 .talk { + width: 33%; +} + +.rooms-2 .talk { + width: 50%; +} + +.rooms-1 .talk { + width: 100%; +} + +td.talk { + border: 1px solid #444; + padding: 4px; + vertical-align: middle; +} + +td.talk > a { + text-decoration: none; + border: none; +} + +.talk-grid tr { + line-height: 1em; +} + +.talk-title a, +.talk-title a:hover, +.talk-title a:focus { + border-bottom: none; +} + +.talk-description strong { + background: inherit; + color: inherit; +} + +/* tag speciali nei talk {{{ */ +/* generati guardando i tag di glypicon come glyphicon-pushpin e copiandone il campo content */ +td.talk::before { + font-family: 'Glyphicons Halflings'; + float: right; +} +td.tag-presentazione_libro::before { + content: "\e043"; +} +td.tag-percorso_base::before { + content: "\e146"; +} +/* tag speciali nei talk }}} */ + +/* END TALK }}} */ + +/* Pagine speciali */ +.body-info .entry-content > ul { + list-style: none; +} + +/*media query min dal piccolo, max dal grande*/ + +@media all and (max-width: 770px) { + .talk-grid { + font-size: 0.8em; + } + .talk-grid td { + hyphens: auto; + } +} +@media all and (max-width: 450px) { + .talk-grid { + font-size: 0.5em; + } +} + diff --git a/plugins/talks/talks.py b/plugins/talks/talks.py new file mode 100644 index 0000000..9f3730b --- /dev/null +++ b/plugins/talks/talks.py @@ -0,0 +1,607 @@ +# -*- coding: utf-8 -*- +""" +Manage talks scheduling in a semantic way +""" + + +from __future__ import print_function +import os +import io +from functools import wraps +import logging +import re +import datetime +import shutil +from copy import copy +import locale +from contextlib import contextmanager +import inspect + +from babel.dates import format_date, format_datetime, format_time, get_timezone +from markdown import markdown +from docutils import nodes +from docutils.parsers.rst import directives, Directive +import six + +from pelican import signals, generators +import jinja2 + +try: + import ics +except ImportError: + ICS_ENABLED = False +else: + ICS_ENABLED = True +try: + import unidecode +except ImportError: + logging.warning("unidecode not available") + UNIDECODE_ENABLED = False +else: + UNIDECODE_ENABLED = True +import dateutil + +try: + Markup = jinja2.Markup +except AttributeError: + from markupsafe import Markup + +pelican = None # This will be set during register() +if 'TZ' not in os.environ: + os.environ['TZ'] = 'Europe/Rome' + + +def memoize(function): + """decorators to cache""" + memo = {} + + @wraps(function) + def wrapper(*args): + if args in memo: + return memo[args] + else: + rv = function(*args) + memo[args] = rv + return rv + + return wrapper + + +@contextmanager +def setlocale(name): + saved = locale.setlocale(locale.LC_ALL) + try: + yield locale.setlocale(locale.LC_ALL, name) + finally: + locale.setlocale(locale.LC_ALL, saved) + + +@memoize +def get_talk_names(): + names = [ + name + for name in os.listdir(pelican.settings["TALKS_PATH"]) + if not name.startswith("_") and get_talk_data(name) is not None + ] + names.sort() + return names + + +def all_talks(): + return [get_talk_data(tn) for tn in get_talk_names()] + + +def unique_attr(iterable, attr): + return {x[attr] for x in iterable if attr in x} + + +@memoize +def get_global_data(): + fname = os.path.join(pelican.settings["TALKS_PATH"], "meta.yaml") + if not os.path.isfile(fname): + return None + with io.open(fname, encoding="utf8") as buf: + try: + data = yaml.safe_load(buf) + except Exception: + logging.exception("Syntax error reading %s; skipping", fname) + return None + if data is None: + return None + if "startdate" not in data: + logging.error("Missing startdate in global data") + data["startdate"] = datetime.datetime.now() + if "rooms" not in data: + data["rooms"] = {} + if "names" not in data["rooms"]: + data["rooms"]["names"] = {} + if "order" not in data["rooms"]: + data["rooms"]["order"] = [] + return data + + +def _get_time_shift(timestring): + """Il problema che abbiamo è che vogliamo dire che le 2 di notte del sabato sono in realtà "parte" del + venerdì. Per farlo accettiamo orari che superano le 24, ad esempio 25.30 vuol dire 1.30. + + Questa funzione ritorna una timedelta in base alla stringa passata + """ + timeparts = re.findall(r"\d+", timestring) + if not timeparts or len(timeparts) > 2: + raise ValueError("Malformed time %s" % timestring) + timeparts += [0, 0] # "padding" per essere sicuro ci siano anche [1] e [2] + duration = datetime.timedelta( + hours=int(timeparts[0]), + minutes=int(timeparts[1]), + seconds=int(timeparts[2]), + ) + if duration.total_seconds() > 3600 * 31 or duration.total_seconds() < 0: + raise ValueError("Sforamento eccessivo: %d" % duration.hours) + return duration + + +@memoize +def get_talk_data(talkname): + fname = os.path.join(pelican.settings["TALKS_PATH"], talkname, "meta.yaml") + if not os.path.isfile(fname): + return None + with io.open(fname, encoding="utf8") as buf: + try: + data = yaml.safe_load(buf) + except Exception: + logging.exception("Syntax error reading %s; skipping", fname) + return None + if data is None: + return None + try: + gridstep = pelican.settings["TALKS_GRID_STEP"] + data.setdefault("nooverlap", []) + if "title" not in data: + logging.warn("Talk <{}> has no `title` field".format(talkname)) + data["title"] = six.text_type(talkname) + else: + data["title"] = six.text_type(data["title"]) + if "text" not in data: + logging.warn("Talk <{}> has no `text` field".format(talkname)) + data["text"] = "" + else: + data["text"] = six.text_type(data["text"]) + if "duration" not in data: + logging.info( + "Talk <{}> has no `duration` field (50min used)".format( + talkname + ) + ) + data["duration"] = 50 + data["duration"] = int(data["duration"]) + if data["duration"] < gridstep: + logging.info( + "Talk <{}> lasts only {} minutes; changing to {}".format( + talkname, data["duration"], gridstep + ) + ) + data["duration"] = gridstep + if "links" not in data or not data["links"]: + data["links"] = [] + if "contacts" not in data or not data["contacts"]: + data["contacts"] = [] + if "needs" not in data or not data["needs"]: + data["needs"] = [] + if "room" not in data: + logging.warn("Talk <{}> has no `room` field".format(talkname)) + else: + if data["room"] in get_global_data()["rooms"]["names"]: + data["room"] = get_global_data()["rooms"]["names"][ + data["room"] + ] + if "time" not in data or "day" not in data: + logging.warn("Talk <{}> has no `time` or `day`".format(talkname)) + if "time" in data: + del data["time"] + if "day" in data: + del data["day"] + else: + data["day"] = get_global_data()["startdate"] + datetime.timedelta( + days=data["day"] + ) + del data["time"] + + logging.debug("parsed: %s - %s" % (data["title"], data.get('start', None))) + data["id"] = talkname + resdir = os.path.join( + pelican.settings["TALKS_PATH"], + talkname, + pelican.settings["TALKS_ATTACHMENT_PATH"], + ) + if os.path.isdir(resdir) and os.listdir(resdir): + data["resources"] = resdir + return data + except Exception: + logging.exception("Error on talk %s", talkname) + raise + + +def overlap(interval_a, interval_b): + """how many minutes do they overlap?""" + return max( + 0, + min(interval_a[1], interval_b[1]) - max(interval_a[0], interval_b[0]), + ) + + +def get_talk_overlaps(name): + data = get_talk_data(name) + overlapping_talks = set() + if "time" not in data: + return overlapping_talks + start = int(data["start"].strftime("%s")) + end = start + data["duration"] * 60 + for other in get_talk_names(): + if other == name: + continue + if "time" not in get_talk_data(other): + continue + other_start = int(get_talk_data(other)["time"].strftime("%s")) + other_end = other_start + get_talk_data(other)["duration"] * 60 + + minutes = overlap((start, end), (other_start, other_end)) + if minutes > 0: + overlapping_talks.add(other) + return overlapping_talks + + +@memoize +def check_overlaps(): + for t in get_talk_names(): + over = get_talk_overlaps(t) + noover = get_talk_data(t)["nooverlap"] + contacts = set(get_talk_data(t)["contacts"]) + for overlapping in over: + if overlapping in noover or set( + get_talk_data(overlapping)["contacts"] + ).intersection(contacts): + logging.warning("Talk %s overlaps with %s" % (t, overlapping)) + + +@memoize +def jinja_env(): + env = jinja2.Environment( + loader=jinja2.FileSystemLoader( + os.path.join(pelican.settings["TALKS_PATH"], "_templates") + ), + autoescape=True, + ) + env.filters["markdown"] = lambda text: Markup(markdown(text)) + env.filters["dateformat"] = format_date + env.filters["datetimeformat"] = format_datetime + env.filters["timeformat"] = format_time + env.filters["parsetime"] = lambda iso: datetime.datetime.fromisoformat(iso).time() + return env + + +@memoize +def get_css(): + plugindir = os.path.dirname( + os.path.abspath(inspect.getfile(inspect.currentframe())) + ) + with open(os.path.join(plugindir, "style.css")) as buf: + return buf.read() + + +class TalkListDirective(Directive): + final_argument_whitespace = True + has_content = True + option_spec = {"lang": directives.unchanged} + + def run(self): + lang = self.options.get("lang", "C") + tmpl = jinja_env().get_template("talk.html") + + def _sort_date(name): + """ + This function is a helper to sort talks by start date + + When no date is available, put at the beginning + """ + d = get_talk_data(name) + room = d.get("room", "") + time = d.get( + "start", + datetime.datetime(1, 1, 1).replace( + tzinfo=dateutil.tz.gettz(os.environ['TZ']) + ), + ) + title = d.get("title", "") + return (time, room, title) + + return [ + nodes.raw( + "", tmpl.render(lang=lang, + local_tz=get_timezone(os.environ['TZ']), + **get_talk_data(n)), format="html" + ) + for n in sorted(get_talk_names(), key=_sort_date) + ] + + +class TalkDirective(Directive): + required_arguments = 1 + final_argument_whitespace = True + has_content = True + option_spec = {"lang": directives.unchanged} + + def run(self): + lang = self.options.get("lang", "C") + tmpl = jinja_env().get_template("talk.html") + data = get_talk_data(self.arguments[0]) + if data is None: + return [] + return [nodes.raw("", tmpl.render(lang=lang, + local_tz=get_timezone(os.environ['TZ']), + **data), format="html")] + + +def _approx_time(time: datetime.datetime) -> datetime.datetime: + gridstep = pelican.settings["TALKS_GRID_STEP"] + minutes = time.minute + new_minutes = minutes // gridstep * gridstep + diff = new_minutes - minutes + if diff != 0: + new_dt = time + datetime.timedelta(minutes=diff) + return new_dt + else: + return time + + +class TalkGridDirective(Directive): + """A complete grid""" + + final_argument_whitespace = True + has_content = True + option_spec = {"lang": directives.unchanged} + + def run(self): + try: + lang = self.options.get("lang", "C") + tmpl = jinja_env().get_template("grid.html") + output = [] + days = unique_attr(all_talks(), "day") + gridstep = pelican.settings["TALKS_GRID_STEP"] + for day in sorted(days): + talks = { + talk["id"] + for talk in all_talks() + if talk.get("day", None) == day + and "start" in talk + and "room" in talk + } + if not talks: + continue + talks = [get_talk_data(t) for t in talks] + rooms = set() + for t in talks: + if type(t["room"]) is list: + for r in t["room"]: + rooms.add(r) + else: + rooms.add(t["room"]) + + def _room_sort_key(r): + order = get_global_data()["rooms"]["order"] + base = None + for k, v in get_global_data()["rooms"]["names"].items(): + if v == r: + base = k + break + else: + if type(r) is str: + return ord(r[0]) + # int? + return r + return order.index(base) + + rooms = list(sorted(rooms, key=_room_sort_key)) + + # room=* is not a real room. + # Remove it unless that day only has special rooms + if "*" in rooms and len(rooms) > 1: + del rooms[rooms.index("*")] + mintime = min({talk["start"] for talk in talks}) + maxtime = max( + { + (talk["start"] + + datetime.timedelta(minutes=talk["duration"]) + ) + for talk in talks + } + ) + times = {} + + t = mintime + while t <= maxtime: + times[t.isoformat('T', timespec="minutes")] = [None] * len(rooms) + t += datetime.timedelta(minutes=gridstep) + for talk in sorted(talks, key=lambda x: x["start"]): + try: + position = _approx_time(talk["start"]).isoformat('T', timespec="minutes") + if talk["room"] == "*": + roomnums = range(len(rooms)) + elif type(talk["room"]) is list: + roomnums = [rooms.index(r) for r in talk["room"]] + else: + roomnums = [rooms.index(talk["room"])] + for roomnum in roomnums: + if times[position][roomnum] is not None: + logging.error( + "Talk %s and %s overlap! (room %s)", + times[position][roomnum]["id"], + talk["id"], + rooms[roomnum], + ) + continue + times[position][roomnum] = copy(talk) + times[position][roomnum]["skip"] = False + for i in range(1, talk["duration"] // gridstep): + p = _approx_time(talk["start"] + i * + datetime.timedelta(minutes=pelican.settings["TALKS_GRID_STEP"])).isoformat('T', timespec="minutes") + times[p][roomnum] = copy(talk) + times[p][roomnum]["skip"] = True + except Exception: + logging.exception( + "Error on talk %s", talk.get("title", "?") + ) + + render = tmpl.render( + local_tz=get_timezone(os.environ['TZ']), + times=times, + rooms=rooms, + mintime=mintime, + maxtime=maxtime, + timestep=gridstep, + lang=lang, + ) + date_formatted = format_date(day, format="full", locale=lang) + output.append( + nodes.raw( + "", + f'
' + f'

{date_formatted}

' + f'{render}' + f'
', + format="html", + ) + ) + except: + logging.exception("Error on talk grid") + import traceback + + traceback.print_exc() + return [] + css = get_css() + if css: + output.insert( + 0, + nodes.raw( + "", + '' % css, + format="html", + ), + ) + return output + + +def talks_to_ics(): + c = ics.Calendar() + c.creator = "pelican" + for t in all_talks(): + e = talk_to_ics(t) + if e is not None: + c.events.add(e) + else: + logging.warning("Event '%s' not added to ICS" % t.get('title', '')) + return six.text_type(c) + + +def talk_to_ics(talk): + def _decode(s): + if UNIDECODE_ENABLED: + return unidecode.unidecode(s) + else: + return s + + if "start" not in talk or "duration" not in talk: + return None + e = ics.Event( + uid="%s@%d.hackmeeting.org" + % (talk["id"], get_global_data()["startdate"].year), + name=_decode(talk["title"]), + begin=talk["start"], + duration=datetime.timedelta(minutes=talk["duration"]), + transparent=True, + ) + # ics.py has some problems with unicode + # unidecode replaces letters with their most similar ASCII counterparts + # (ie: accents get stripped) + if "text" in talk: + e.description = _decode(talk["text"]) + e.url = pelican.settings["SCHEDULEURL"] + "#talk-" + talk["id"] + if "room" in talk: + e.location = talk["room"] + + return e + + +class TalksGenerator(generators.Generator): + def __init__(self, *args, **kwargs): + self.talks = [] + super(TalksGenerator, self).__init__(*args, **kwargs) + + def generate_context(self): + self.talks = {n: get_talk_data(n) for n in get_talk_names()} + self._update_context(("talks",)) + check_overlaps() + + def generate_output(self, writer=None): + for talkname in sorted(self.talks): + if "resources" in self.talks[talkname]: + outdir = os.path.join( + self.output_path, + pelican.settings["TALKS_PATH"], + talkname, + pelican.settings["TALKS_ATTACHMENT_PATH"], + ) + if os.path.isdir(outdir): + shutil.rmtree(outdir) + shutil.copytree(self.talks[talkname]["resources"], outdir) + if ICS_ENABLED: + logging.info("Generating ics...") + with io.open( + os.path.join( + self.output_path, pelican.settings.get("TALKS_ICS") + ), + "w", + encoding="utf8", + ) as buf: + content = talks_to_ics() + logging.info("ics is %d characters" % len(content)) + buf.write(content) + else: + logging.warning( + "module `ics` not found. " "ICS calendar will not be generated" + ) + + +def add_talks_option_defaults(pelican): + pelican.settings.setdefault("TALKS_PATH", "talks") + pelican.settings.setdefault("TALKS_ATTACHMENT_PATH", "res") + pelican.settings.setdefault("TALKS_ICS", "schedule.ics") + pelican.settings.setdefault("TALKS_GRID_STEP", 30) + + +def get_generators(gen): + return TalksGenerator + + +def pelican_init(pelicanobj): + global pelican + pelican = pelicanobj + + +try: + import yaml +except ImportError: + print("ERROR: yaml not found. Talks plugins will be disabled") + + def register(): + pass + +else: + + def register(): + signals.initialized.connect(pelican_init) + signals.get_generators.connect(get_generators) + signals.initialized.connect(add_talks_option_defaults) + directives.register_directive("talklist", TalkListDirective) + directives.register_directive("talk", TalkDirective) + directives.register_directive("talkgrid", TalkGridDirective) diff --git a/plugins/tipue_search/README.md b/plugins/tipue_search/README.md new file mode 100644 index 0000000..1a2d615 --- /dev/null +++ b/plugins/tipue_search/README.md @@ -0,0 +1,67 @@ +Tipue Search +============ + +A Pelican plugin to serialize generated HTML to JSON that can be used by jQuery plugin - Tipue Search. + +Copyright (c) Talha Mansoor + +Author | Talha Mansoor +----------------|----- +Author Email | talha131@gmail.com +Author Homepage | http://onCrashReboot.com +Github Account | https://github.com/talha131 + +Why do you need it? +=================== + +Static sites do not offer search feature out of the box. [Tipue Search](http://www.tipue.com/search/) +is a jQuery plugin that search the static site without using any third party service, like DuckDuckGo or Google. + +Tipue Search offers 4 search modes. Its [JSON search mode](http://www.tipue.com/search/docs/json/) is the best search mode +especially for large sites. + +Tipue's JSON search mode requires the textual content of site in JSON format. + +Requirements +============ + +Tipue Search requires BeautifulSoup. + +```bash +pip install beautifulsoup4 +``` + +How Tipue Search works +========================= + +Tipue Search serializes the generated HTML into JSON. Format of JSON is as follows + +```python +{ + "pages": [ + { + "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero.", + "tags": "Example Category", + "url" : "http://oncrashreboot.com/plugin-example.html", + "title": "Everything you want to know about Lorem Ipsum" + }, + { + "text": "Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa. Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh.", + "tags": "Example Category", + "url" : "http://oncrashreboot.com/plugin-example-2.html", + "title": "Review of the book Lorem Ipsum" + } + ] +} +``` + +JSON is written to file `tipuesearch_content.json` which is created in the root of `output` directory. + +How to use +========== + +To utilize JSON Search mode, your theme needs to have Tipue Search properly configured in it. [Official documentation](http://www.tipue.com/search/docs/#json) has the required details. + +Pelican [Elegant Theme](https://github.com/talha131/pelican-elegant) and [Plumage +theme](https://github.com/kdeldycke/plumage) have Tipue Search configured. You can view their +code to understand the configuration. diff --git a/plugins/tipue_search/__init__.py b/plugins/tipue_search/__init__.py new file mode 100644 index 0000000..ebd6c06 --- /dev/null +++ b/plugins/tipue_search/__init__.py @@ -0,0 +1 @@ +from .tipue_search import * diff --git a/plugins/tipue_search/tipue_search.py b/plugins/tipue_search/tipue_search.py new file mode 100644 index 0000000..ff5a4f5 --- /dev/null +++ b/plugins/tipue_search/tipue_search.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +""" +Tipue Search +============ + +A Pelican plugin to serialize generated HTML to JSON +that can be used by jQuery plugin - Tipue Search. + +Copyright (c) Talha Mansoor +""" + +from __future__ import unicode_literals + +import os.path +import json +from bs4 import BeautifulSoup +from codecs import open +try: + from urlparse import urljoin +except ImportError: + from urllib.parse import urljoin + +from pelican import signals + + +class Tipue_Search_JSON_Generator(object): + + def __init__(self, context, settings, path, theme, output_path, *null): + + self.output_path = output_path + self.context = context + self.siteurl = settings.get('SITEURL') + self.relative_urls = settings.get('RELATIVE_URLS') + self.tpages = settings.get('TEMPLATE_PAGES') + self.output_path = output_path + self.json_nodes = [] + + def create_json_node(self, page): + if getattr(page, 'status', 'published') != 'published': + return + + soup_title = BeautifulSoup(page.title.replace(' ', ' '), 'html.parser') + page_title = soup_title.get_text(' ', strip=True).replace('“', '"').replace('”', '"').replace('’', "'").replace('^', '^') + + soup_text = BeautifulSoup(page.content, 'html.parser') + page_text = soup_text.get_text(' ', strip=True).replace('“', '"').replace('”', '"').replace('’', "'").replace('¶', ' ').replace('^', '^') + page_text = ' '.join(page_text.split()) + + page_category = page.category.name if getattr(page, 'category', 'None') != 'None' else '' + + page_url = '.' + if page.url: + page_url = page.url if self.relative_urls else (self.siteurl + '/' + page.url) + + node = {'title': page_title, + 'text': page_text, + 'tags': page_category, + 'loc': page_url} + + self.json_nodes.append(node) + + def create_tpage_node(self, srclink): + with open(os.path.join(self.output_path, self.tpages[srclink]), + encoding='utf-8') as srcfile: + soup = BeautifulSoup(srcfile, 'html.parser') + page_title = soup.title.string if soup.title is not None else '' + page_text = soup.get_text() + + # Should set default category? + page_category = '' + page_url = urljoin(self.siteurl, self.tpages[srclink]) + + node = {'title': page_title, + 'text': page_text, + 'tags': page_category, + 'url': page_url} + + self.json_nodes.append(node) + + def generate_output(self, writer): + # bisognerebbe cambiare usando questo coso + # for p in self.context['PAGES']: + # print 'U', p.url + path = os.path.join(self.output_path, 'tipuesearch_content.json') + + pages = self.context['pages'] + self.context['articles'] + + for article in self.context['articles']: + pages += article.translations + + for srclink in self.tpages: + self.create_tpage_node(srclink) + + for page in pages: + self.create_json_node(page) + root_node = {'pages': self.json_nodes} + + with open(path, 'w', encoding='utf-8') as fd: + json.dump(root_node, fd, separators=(',', ':'), ensure_ascii=False) + + +def get_generators(generators): + return Tipue_Search_JSON_Generator + + +def register(): + signals.get_generators.connect(get_generators) diff --git a/publishconf.py b/publishconf.py new file mode 100644 index 0000000..3b339b5 --- /dev/null +++ b/publishconf.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# This file is only used if you use `make publish` or +# explicitly specify it as your config file. +# -*- coding: utf-8 -*- # +from __future__ import unicode_literals + +import os +import sys + +sys.path.append(os.curdir) # isort:skip +from pelicanconf import * # isort:skip +from pelicanconf import YEAR # isort:skip + +SITEURL = "https://hackmeeting.org/hackit%d/" % (YEAR - 2000) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..93721f8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length=79 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..baea419 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,34 @@ +anyio==4.3.0 +arrow==1.3.0 +attrs==23.2.0 +Babel==2.14.0 +beautifulsoup4==4.12.3 +blinker==1.7.0 +docutils==0.20.1 +feedgenerator==2.1.0 +ics==0.7.2 +idna==3.6 +Jinja2==3.1.3 +libsass==0.23.0 +Markdown==3.6 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdurl==0.1.2 +ordered-set==4.1.0 +pelican==4.9.1 +pelican-jinja2content==1.0.1 +Pygments==2.17.2 +python-dateutil==2.9.0.post0 +pytz==2024.1 +PyYAML==6.0.1 +rich==13.7.1 +six==1.16.0 +smartypants==2.0.1 +sniffio==1.3.1 +soupsieve==2.5 +TatSu==5.12.0 +types-python-dateutil==2.9.0.20240316 +typogrify==2.0.7 +Unidecode==1.3.8 +watchfiles==0.21.0 +webassets==2.0 diff --git a/talks/README.md b/talks/README.md new file mode 100644 index 0000000..b1603b9 --- /dev/null +++ b/talks/README.md @@ -0,0 +1,5 @@ +Per aggiungere un talk, copia la directory `_talk_example` in una nuova +directory che contenga **solo caratteri alfabetici**, quindi +cambia il file ``meta.yaml`` a tuo piacimento. +Usa UTF-8 o morirai. +**NOTA BENE**: in realta' abbiamo usato il calendario di nextcloud con uno script magico che autopusha diff --git a/talks/_templates/grid.html b/talks/_templates/grid.html new file mode 100644 index 0000000..ee5f887 --- /dev/null +++ b/talks/_templates/grid.html @@ -0,0 +1,40 @@ + + + + + {% for room in rooms %} + + {% endfor %} + + + + {% for time in times|sort %} + + + {% for talk in times[time] %} + {% if not loop.first and talk.room == '*' %} + {# skip: covered by colspan #} + {% elif talk == None %} + + {% elif not talk.skip %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
{{room}}
+ + + {{talk.title}} +
+{# vim: set ft=jinja: #} diff --git a/talks/_templates/talk.html b/talks/_templates/talk.html new file mode 100644 index 0000000..a1debb3 --- /dev/null +++ b/talks/_templates/talk.html @@ -0,0 +1,63 @@ +{% macro durata_human(d) %} +{%- if d >= 60 -%}{{d//60}}h{%- endif -%} +{%- if d % 60 != 0 -%}{{d%60}}m {%- endif -%} +{% endmacro %} +{% macro durata_html(d) %} +PT{%- if d >= 60 -%}{{d//60}}H{%- endif -%} +{%- if d % 60 != 0 -%}{{d%60}}M{%- endif -%} +{% endmacro %} +
+

{{title.strip()}}

+
+

+ {% if start is defined and day is defined %} + {# Vedi http://babel.pocoo.org/en/latest/dates.html #} + + {% else %} + L'orario non è ancora stato fissato + {% if duration %}

Durata: {{durata_human(duration)}}

{% endif %} + {% endif %} {# date-time #} + {% if room is defined %} + Stanza {{ room }} + {% endif %} +

+ + {% if needs: %} +
+Materiale necessario: +{{needs|join(", ")}} +
+{% endif %} +
+
{{text | markdown}} + {% if contacts: %} +

A cura di {{contacts|join(', ')}}

+ {% endif %} +
+ {% if links or resources or mail: %} +
+

Link utili:

+
    + {% if links is defined: %} + {% for link in links %} +
  • {{link|urlize}}
  • + {% endfor %} + {% endif %} + {% if resources is defined: %} +
  • Materiali
  • + {% endif %} + {% if mail is defined and mail: %} +
  • Mail
  • + {% endif %} +
+
+ {% endif %} +
+ +{# vim: set ft=jinja: #} diff --git a/talks/meta.yaml b/talks/meta.yaml new file mode 100644 index 0000000..d1a416c --- /dev/null +++ b/talks/meta.yaml @@ -0,0 +1,8 @@ +startdate: 2025-05-30 +rooms: + names: + room1: "a" + room2: "b" + room3: "c" + arena: "xyz" + order: [room1, room2, room3, arena, extra] diff --git a/themes/hackit0x16/static/css/main.css b/themes/hackit0x16/static/css/main.css new file mode 100644 index 0000000..76a1292 --- /dev/null +++ b/themes/hackit0x16/static/css/main.css @@ -0,0 +1,458 @@ +/* + Name: Smashing HTML5 + Date: July 2009 + Description: Sample layout for HTML5 and CSS3 goodness. + Version: 1.0 + License: MIT + Licensed by: Smashing Media GmbH + Original author: Enrique Ramírez +*/ + +/* Imports */ +@import url("reset.css"); +@import url("pygment.css"); +@import url("typogrify.css"); +@import url("fonts.css"); +/***** Global *****/ +/* Body */ +body * { + box-sizing: border-box; +} +body { + background: #000; /*#FFF;*/ + color: #FFF; + /*font-size: 87.5%; /* Base font size: 14px *** + font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;*/ + font-size:18px; + font-family: 'Typo'; + line-height: 1.429; + margin: 0; + padding: 0; + text-align: left; +} + +/* Headings */ +h1 {font-size: 2em } +h2 {font-size: 1.571em} /* 22px */ +h3 {font-size: 1.429em} /* 20px */ +h4 {font-size: 1.286em} /* 18px */ +h5 {font-size: 1.143em} /* 16px */ +h6 {font-size: 1em} /* 14px */ + +h1, h2, h3, h4, h5, h6 { + font-weight: 400; + line-height: 1.1; + margin-bottom: .8em; + font-family: 'Typo', arial, serif; + color: #e85520; +} + +h3, h4, h5, h6 { margin-top: .8em; } + +hr { border: 2px solid #EEEEEE; } + +/* Anchors */ +a {outline: 0;} +a img {border: 0px; text-decoration: none;} +a:link, a:visited { + color: #FFF; + padding: 0 1px; + text-decoration: underline; +} +a:hover, a:active { + background-color: #000; + color: #fff; + text-decoration: none; + text-shadow: 1px 1px 1px #333; +} + +h1 a:hover { + background-color: inherit +} + +/* Paragraphs */ +div.line-block, +p { margin-top: 1em; + margin-bottom: 1em;} + +strong, b {font-weight: bold;} +em, i {font-style: italic;} + +/* Lists */ +ul { + list-style: outside disc; + margin: 0em 0 0 1.5em; +} + +ol { + list-style: outside decimal; + margin: 0em 0 0 1.5em; +} + +li { margin-top: 0.5em;} + +.post-info { + float:right; + margin:10px; + padding:5px; +} + +.post-info p{ + margin-top: 1px; + margin-bottom: 1px; +} + +.readmore { float: right } + +dl {margin: 0 0 1.5em 0;} +dt {font-weight: bold;} +dd {margin-left: 1.5em;} + +pre{ padding: 10px; margin: 10px; overflow: auto;} + +/* Quotes */ +blockquote { + margin: 20px; + font-style: italic; +} +cite {} + +q {} + +div.note { + float: right; + margin: 5px; + font-size: 85%; + max-width: 300px; +} + +.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +/* Tables */ +table {margin: .5em auto 1.5em auto; width: 98%;} + + /* Thead */ + thead th {padding: .5em .4em; text-align: left;} + thead td {} + + /* Tbody */ + tbody td {padding: .5em .4em;} + tbody th {} + + tbody .alt td {} + tbody .alt th {} + + /* Tfoot */ + tfoot th {} + tfoot td {} + +/* HTML5 tags */ +header, section, +aside, nav, article, figure { + display: block; +} +footer {display:none} + +/***** Layout *****/ +.body {clear: both; margin: 0 auto; width: 100%;} +img.right, figure.right {float: right; margin: 0 0 2em 2em;} +img.left, figure.left {float: left; margin: 0 2em 2em 0;} + +/* + Header +*****************/ +#banner { + margin: 0 auto; + padding: 2.5em 0 0 0; + display: flex; + flex-direction: column; + align-items: center; +} + + /* Banner */ + #banner h1 {font-size: 3.571em; line-height: 1;} + #banner h1 a:link, #banner h1 a:visited { + color: #e85520; + display: block; + font-weight: bold; + margin: 0 0 .6em .2em; + text-decoration: none; + } + #banner h1 a:hover, #banner h1 a:active { + background: none; + color: #FFF; + text-shadow: none; + } + + #banner h1 strong {font-size: 0.36em; font-weight: normal;} + + /* Main Nav */ + #banner nav { + background: #000; + font-size: 1.143em; + height: 40px; + line-height: 30px; + margin: 0 auto 2em auto; + padding: 0; + text-align: center; + width: 100%; + } + + #banner nav ul {list-style: none; margin: 0 auto; width: 100%;display: flex;justify-content: center;flex-wrap:wrap;} + #banner nav li {float: left; display: inline; margin: 0;} + + #banner nav a:link, #banner nav a:visited { + color: #FFF; + display: inline-block; + height: 40px; + padding: 5px 1.5em; + text-decoration: none; + border:0; + position:relative; + text-transform:uppercase; + font-family: 'Typo'; + } + #banner nav a:hover, #banner nav a:active, + #banner nav .active a:link, #banner nav .active a:visited { + background: transparent; + color: #FFF; + text-shadow: none !important; + } + #banner nav a:before { + transition: width ease-in 0.3s; + content: ""; + background: #e85520; + width: 0px; + height: 2px; + position: absolute; + top: 35px; + z-index: 1000; + left: 50%; + margin-left: -25px; + } + #banner nav a:hover:before, #banner nav .active a:before { + width:50px; + } + + + +/* + Featured +*****************/ +#featured { + margin-bottom: 2em; + overflow: hidden; + padding: 20px; + width: 760px; + +} + +#featured figure { + border: 2px solid #eee; + float: right; + margin: 0.786em 2em 0 5em; + width: 248px; +} +#featured figure img {display: block; float: right;} + +#featured h2 {color: #C74451; font-size: 1.714em; margin-bottom: 0.333em;} +#featured h3 {font-size: 1.429em; margin-bottom: .5em;} + +#featured h3 a:link, #featured h3 a:visited {color: #000305; text-decoration: none;} +#featured h3 a:hover, #featured h3 a:active {color: #fff;} + +/* + Body +*****************/ +#content { + background: #000; + margin-bottom: 2em; + overflow: hidden; + padding: 20px 20px; + max-width: 1200px; + font-family:Arial; + + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +/* + Extras +*****************/ +#extras {margin: 0 auto 3em auto; overflow: hidden;} + +#extras ul {list-style: none; margin: 0;} +#extras li {border-bottom: 1px solid #fff;} +#extras h2 { + color: #C74350; + font-size: 1.429em; + margin-bottom: .25em; + padding: 0 3px; +} + +#extras a:link, #extras a:visited { + color: #444; + display: block; + border-bottom: 1px solid #F4E3E3; + text-decoration: none; + padding: .3em .25em; +} + +#extras a:hover, #extras a:active {color: #fff;} + + /* Blogroll */ + #extras .blogroll { + float: left; + width: 615px; + } + + #extras .blogroll li {float: left; margin: 0 20px 0 0; width: 185px;} + + /* Social */ + #extras .social { + float: right; + width: 175px; + } + + #extras div[class='social'] a { + background-repeat: no-repeat; + background-position: 3px 6px; + padding-left: 25px; + } + + +/* + About +*****************/ +#about { + background: #fff; + font-style: normal; + margin-bottom: 2em; + overflow: hidden; + padding: 20px; + text-align: left; + width: 760px; + + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +#about .primary {float: left; width: 165px;} +#about .primary strong {color: #C64350; display: block; font-size: 1.286em;} +#about .photo {float: left; margin: 5px 20px;} + +#about .url:link, #about .url:visited {text-decoration: none;} + +#about .bio {float: right; width: 500px;} + +/* + Footer +*****************/ +#contentinfo {padding-bottom: 2em; text-align: right;} + +/***** Sections *****/ +/* Blog */ +.hentry { + display: block; + clear: both; + border-bottom: 1px solid #eee; + padding: 1.5em 0; +} +li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} +#content > .hentry {padding: 1em 0;} +.hentry img{display : none ;} +.entry-title {font-size: 3em; margin-bottom: 10px; margin-top: 0;} +.entry-title a:link, .entry-title a:visited {text-decoration: none; color: #ccc;} +.entry-title a:visited {background-color: #fff;} +.news article .entry-content { font-family: Arial; } + +.hentry .post-info * {font-style: normal;} + + /* Content */ + .hentry footer {margin-bottom: 2em;} + .hentry footer address {display: inline;} + #posts-list footer address {display: block;} + + /* Blog Index */ + #posts-list {list-style: none; margin: 0;} + #posts-list .hentry {padding-left: 10px; position: relative;} + + #posts-list footer { + left: 10px; + position: relative; + float: left; + top: 0.5em; + width: 190px; + } + + /* About the Author */ + #about-author { + background: #f9f9f9; + clear: both; + font-style: normal; + margin: 2em 0; + padding: 10px 20px 15px 20px; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + } + + #about-author strong { + color: #C64350; + clear: both; + display: block; + font-size: 1.429em; + } + + #about-author .photo {border: 1px solid #ddd; float: left; margin: 5px 1em 0 0;} + + /* Comments */ + #comments-list {list-style: none; margin: 0 1em;} + #comments-list blockquote { + background: #f8f8f8; + clear: both; + font-style: normal; + margin: 0; + padding: 15px 20px; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + } + #comments-list footer {color: #888; padding: .5em 1em 0 0; text-align: right;} + + #comments-list li:nth-child(2n) blockquote {background: #F5f5f5;} + + /* Add a Comment */ + #add-comment label {clear: left; float: left; text-align: left; width: 150px;} + #add-comment input[type='text'], + #add-comment input[type='email'], + #add-comment input[type='url'] {float: left; width: 200px;} + + #add-comment textarea {float: left; height: 150px; width: 495px;} + + #add-comment p.req {clear: both; margin: 0 .5em 1em 0; text-align: right;} + + #add-comment input[type='submit'] {float: right; margin: 0 .5em;} + #add-comment * {margin-bottom: .5em;} + +@media screen and (max-width:767px) { + h4 {font-size:1.1em;} + #banner h1 a:link, #banner h1 a:visited { + font-size:30px; + text-align:center; + } + #banner nav { + height:auto; + } + .entry-title { + font-size:1.8em; + } +} diff --git a/themes/hackit0x16/static/css/pygment.css b/themes/hackit0x16/static/css/pygment.css new file mode 100644 index 0000000..fdd056f --- /dev/null +++ b/themes/hackit0x16/static/css/pygment.css @@ -0,0 +1,205 @@ +.hll { +background-color:#eee; +} +.c { +color:#408090; +font-style:italic; +} +.err { +border:1px solid #FF0000; +} +.k { +color:#007020; +font-weight:bold; +} +.o { +color:#666666; +} +.cm { +color:#408090; +font-style:italic; +} +.cp { +color:#007020; +} +.c1 { +color:#408090; +font-style:italic; +} +.cs { +background-color:#FFF0F0; +color:#408090; +} +.gd { +color:#A00000; +} +.ge { +font-style:italic; +} +.gr { +color:#FF0000; +} +.gh { +color:#000080; +font-weight:bold; +} +.gi { +color:#00A000; +} +.go { +color:#303030; +} +.gp { +color:#C65D09; +font-weight:bold; +} +.gs { +font-weight:bold; +} +.gu { +color:#800080; +font-weight:bold; +} +.gt { +color:#0040D0; +} +.kc { +color:#007020; +font-weight:bold; +} +.kd { +color:#007020; +font-weight:bold; +} +.kn { +color:#007020; +font-weight:bold; +} +.kp { +color:#007020; +} +.kr { +color:#007020; +font-weight:bold; +} +.kt { +color:#902000; +} +.m { +color:#208050; +} +.s { +color:#4070A0; +} +.na { +color:#4070A0; +} +.nb { +color:#007020; +} +.nc { +color:#0E84B5; +font-weight:bold; +} +.no { +color:#60ADD5; +} +.nd { +color:#555555; +font-weight:bold; +} +.ni { +color:#D55537; +font-weight:bold; +} +.ne { +color:#007020; +} +.nf { +color:#06287E; +} +.nl { +color:#002070; +font-weight:bold; +} +.nn { +color:#0E84B5; +font-weight:bold; +} +.nt { +color:#062873; +font-weight:bold; +} +.nv { +color:#BB60D5; +} +.ow { +color:#007020; +font-weight:bold; +} +.w { +color:#BBBBBB; +} +.mf { +color:#208050; +} +.mh { +color:#208050; +} +.mi { +color:#208050; +} +.mo { +color:#208050; +} +.sb { +color:#4070A0; +} +.sc { +color:#4070A0; +} +.sd { +color:#4070A0; +font-style:italic; +} +.s2 { +color:#4070A0; +} +.se { +color:#4070A0; +font-weight:bold; +} +.sh { +color:#4070A0; +} +.si { +color:#70A0D0; +font-style:italic; +} +.sx { +color:#C65D09; +} +.sr { +color:#235388; +} +.s1 { +color:#4070A0; +} +.ss { +color:#517918; +} +.bp { +color:#007020; +} +.vc { +color:#BB60D5; +} +.vg { +color:#BB60D5; +} +.vi { +color:#BB60D5; +} +.il { +color:#208050; +} diff --git a/themes/hackit0x16/static/css/reset.css b/themes/hackit0x16/static/css/reset.css new file mode 100644 index 0000000..1e21756 --- /dev/null +++ b/themes/hackit0x16/static/css/reset.css @@ -0,0 +1,52 @@ +/* + Name: Reset Stylesheet + Description: Resets browser's default CSS + Author: Eric Meyer + Author URI: http://meyerweb.com/eric/tools/css/reset/ +*/ + +/* v1.0 | 20080212 */ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + background: transparent; + border: 0; + font-size: 100%; + margin: 0; + outline: 0; + padding: 0; + vertical-align: baseline; +} + +body {line-height: 1;} + +ol, ul {list-style: none;} + +blockquote, q {quotes: none;} + +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +/* remember to define focus styles! */ +:focus { + outline: 0; +} + +/* remember to highlight inserts somehow! */ +ins {text-decoration: none;} +del {text-decoration: line-through;} + +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/themes/hackit0x16/static/css/typogrify.css b/themes/hackit0x16/static/css/typogrify.css new file mode 100644 index 0000000..3bae497 --- /dev/null +++ b/themes/hackit0x16/static/css/typogrify.css @@ -0,0 +1,3 @@ +.caps {font-size:.92em;} +.amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} +.dquo {margin-left:-.38em;} diff --git a/themes/hackit0x16/static/css/wide.css b/themes/hackit0x16/static/css/wide.css new file mode 100644 index 0000000..88fd59c --- /dev/null +++ b/themes/hackit0x16/static/css/wide.css @@ -0,0 +1,48 @@ +@import url("main.css"); + +body { + font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif; +} + +.post-info{ + display: none; +} + +#banner nav { + display: none; + -moz-border-radius: 0px; + margin-bottom: 20px; + overflow: hidden; + font-size: 1em; + background: #F5F4EF; +} + +#banner nav ul{ + padding-right: 50px; +} + +#banner nav li{ + float: right; + color: #000; +} + +#banner nav li a { + color: #000; +} + +#banner h1 { + margin-bottom: -18px; +} + +#featured, #extras { + padding: 50px; +} + +#featured { + padding-top: 20px; +} + +#extras { + padding-top: 0px; + padding-bottom: 0px; +} diff --git a/themes/hackit0x16/static/cyberright_black.gif b/themes/hackit0x16/static/cyberright_black.gif new file mode 100644 index 0000000..48f0709 Binary files /dev/null and b/themes/hackit0x16/static/cyberright_black.gif differ diff --git a/themes/hackit0x16/static/fonts/monotype.ttf b/themes/hackit0x16/static/fonts/monotype.ttf new file mode 100644 index 0000000..8f74073 Binary files /dev/null and b/themes/hackit0x16/static/fonts/monotype.ttf differ diff --git a/themes/hackit0x16/templates/analytics.html b/themes/hackit0x16/templates/analytics.html new file mode 100644 index 0000000..d76990d --- /dev/null +++ b/themes/hackit0x16/templates/analytics.html @@ -0,0 +1,19 @@ +{% if PIWIK_URL and PIWIK_SITE_ID %} + +{% endif %} diff --git a/themes/hackit0x16/templates/archives.html b/themes/hackit0x16/templates/archives.html new file mode 100644 index 0000000..f678494 --- /dev/null +++ b/themes/hackit0x16/templates/archives.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% block content %} +
+

Archives for {{ SITENAME }}

+ +
+{% for article in dates %} +
{{ article.locale_date }}
+
{{ article.title }}
+{% endfor %} +
+
+{% endblock %} diff --git a/themes/hackit0x16/templates/article.html b/themes/hackit0x16/templates/article.html new file mode 100644 index 0000000..91cbfc4 --- /dev/null +++ b/themes/hackit0x16/templates/article.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% block html_lang %}{{ article.lang }}{% endblock %} +{% block title %}{{ article.title|striptags }}{% endblock %} + +{% block extra_head %} +{% import 'translations.html' as translations with context %} +{% if translations.entry_hreflang(article) %} + {{ translations.entry_hreflang(article) }} +{% endif %} +{% endblock %} + +{% block content %} +
+
+
+

+ {{ article.title }}

+
+ +
+ {% include 'article_infos.html' %} + {{ article.content }} +
+ {% if DISQUS_SITENAME and SITEURL and article.status != "draft" %} +
+

Comments !

+
+ + +
+ {% endif %} + +
+
+{% endblock %} diff --git a/themes/hackit0x16/templates/article_infos.html b/themes/hackit0x16/templates/article_infos.html new file mode 100644 index 0000000..172ad85 --- /dev/null +++ b/themes/hackit0x16/templates/article_infos.html @@ -0,0 +1,23 @@ +
+ + Published: {{ article.locale_date }} + + {% if article.modified %} +
+ + Updated: {{ article.locale_modified }} + + {% endif %} + + {% if article.authors %} +
+ By {% for author in article.authors %} + {{ author }} + {% endfor %} +
+ {% endif %} +

In {{ article.category }}.

+{% include 'taglist.html' %} +{% import 'translations.html' as translations with context %} +{{ translations.translations_for(article) }} +
diff --git a/themes/hackit0x16/templates/author.html b/themes/hackit0x16/templates/author.html new file mode 100644 index 0000000..0b37290 --- /dev/null +++ b/themes/hackit0x16/templates/author.html @@ -0,0 +1,2 @@ +{% extends "index.html" %} +{% block title %}{{ SITENAME }} - {{ author }}{% endblock %} diff --git a/themes/hackit0x16/templates/authors.html b/themes/hackit0x16/templates/authors.html new file mode 100644 index 0000000..e61a332 --- /dev/null +++ b/themes/hackit0x16/templates/authors.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block title %}{{ SITENAME }} - Authors{% endblock %} + +{% block content %} + +
+

Authors on {{ SITENAME }}

+
    + {% for author, articles in authors|sort %} +
  • {{ author }} ({{ articles|count }})
  • + {% endfor %} +
+
+ +{% endblock %} diff --git a/themes/hackit0x16/templates/base.html b/themes/hackit0x16/templates/base.html new file mode 100644 index 0000000..180b5b1 --- /dev/null +++ b/themes/hackit0x16/templates/base.html @@ -0,0 +1,73 @@ + + + + + {% block title %}{{ SITENAME }}{%endblock%} + + {% if FAVICON %} + + {% endif %} + {% if FEED_ALL_ATOM %} + + {% endif %} + {% if FEED_ALL_RSS %} + + {% endif %} + {% block extra_head %}{% endblock extra_head %} + + + + + {% block content %} + {% endblock %} +
+ {% if LINKS %} +
+

{{ LINKS_WIDGET_NAME | default('links') }}

+
    + {% for name, link in LINKS %} +
  • {{ name }}
  • + {% endfor %} +
+
+ {% endif %} + {% if FEED_ALL_ATOM or FEED_ALL_RSS %} + + {% endif %} +
+ +
+
+ + + diff --git a/themes/hackit0x16/templates/category.html b/themes/hackit0x16/templates/category.html new file mode 100644 index 0000000..56f8e93 --- /dev/null +++ b/themes/hackit0x16/templates/category.html @@ -0,0 +1,2 @@ +{% extends "index.html" %} +{% block title %}{{ SITENAME }} - {{ category }}{% endblock %} diff --git a/themes/hackit0x16/templates/comments.html b/themes/hackit0x16/templates/comments.html new file mode 100644 index 0000000..e69de29 diff --git a/themes/hackit0x16/templates/disqus_script.html b/themes/hackit0x16/templates/disqus_script.html new file mode 100644 index 0000000..e69de29 diff --git a/themes/hackit0x16/templates/github.html b/themes/hackit0x16/templates/github.html new file mode 100644 index 0000000..e69de29 diff --git a/themes/hackit0x16/templates/index.html b/themes/hackit0x16/templates/index.html new file mode 100644 index 0000000..30716e6 --- /dev/null +++ b/themes/hackit0x16/templates/index.html @@ -0,0 +1,37 @@ +{% extends "base.html" %} +{% block content_title %}{% endblock %} +{% block content %} +
+{% if articles %} + {% for article in articles_page.object_list %} + + {% if loop.first %} +
+
    + {% endif %} +
  1. +
    +

    {{ article.title }}

    +
    + +
    + {% include 'article_infos.html' %} + {{ article.summary }} + read more + {% include 'comments.html' %} +
    +
  2. + {% if loop.last %} + {% if loop.length > 1 or articles_page.has_other_pages() %} +
+ {% if articles_page.has_other_pages() %} + {% include 'pagination.html' %} + {% endif %} +
+ {% endif %} + {% endif %} + {% endfor %} +{% endif %} +
+{% endblock content %} diff --git a/themes/hackit0x16/templates/page.html b/themes/hackit0x16/templates/page.html new file mode 100644 index 0000000..7e50c1f --- /dev/null +++ b/themes/hackit0x16/templates/page.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% block html_lang %}{{ page.lang }}{% endblock %} +{% block title %}{{ page.title }}{% endblock %} + +{% block extra_head %} +{% import 'translations.html' as translations with context %} +{% if translations.entry_hreflang(page) %} + {{ translations.entry_hreflang(page) }} +{% endif %} +{% endblock %} + +{% block content %} +
+

{{ page.title }}

+ {% import 'translations.html' as translations with context %} + {{ translations.translations_for(page) }} + {{ page.content }} +
+{% endblock %} diff --git a/themes/hackit0x16/templates/period_archives.html b/themes/hackit0x16/templates/period_archives.html new file mode 100644 index 0000000..252e002 --- /dev/null +++ b/themes/hackit0x16/templates/period_archives.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} +{% block content %} +
+

Archives for {{ period | reverse | join(' ') }}

+ +
+{% for article in dates %} +
{{ article.locale_date }}
+
{{ article.title }}
+{% endfor %} +
+
+{% endblock %} diff --git a/themes/hackit0x16/templates/tag.html b/themes/hackit0x16/templates/tag.html new file mode 100644 index 0000000..68cdcba --- /dev/null +++ b/themes/hackit0x16/templates/tag.html @@ -0,0 +1,2 @@ +{% extends "index.html" %} +{% block title %}{{ SITENAME }} - {{ tag }}{% endblock %} diff --git a/themes/hackit0x16/templates/taglist.html b/themes/hackit0x16/templates/taglist.html new file mode 100644 index 0000000..58f3557 --- /dev/null +++ b/themes/hackit0x16/templates/taglist.html @@ -0,0 +1 @@ +{% if article.tags %}

tags: {% for tag in article.tags %}{{ tag | escape }} {% endfor %}

{% endif %} diff --git a/themes/hackit0x16/templates/tags.html b/themes/hackit0x16/templates/tags.html new file mode 100644 index 0000000..fb09955 --- /dev/null +++ b/themes/hackit0x16/templates/tags.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block title %}{{ SITENAME }} - Tags{% endblock %} + +{% block content %} + +
+

Tags for {{ SITENAME }}

+
    + {% for tag, articles in tags|sort %} +
  • {{ tag }} ({{ articles|count }})
  • + {% endfor %} +
+
+ +{% endblock %} diff --git a/themes/hackit0x16/templates/translations.html b/themes/hackit0x16/templates/translations.html new file mode 100644 index 0000000..fc094dd --- /dev/null +++ b/themes/hackit0x16/templates/translations.html @@ -0,0 +1,18 @@ +{% macro translations_for(article) %} +{% if article.translations %} +
+Translations: + {% for translation in article.translations %} + {{ translation.lang }} + {% endfor %} +
+{% endif %} +{% endmacro %} + +{% macro entry_hreflang(entry) %} +{% if entry.translations %} + {% for translation in entry.translations %} + + {% endfor %} +{% endif %} +{% endmacro %} diff --git a/themes/hackit0x16/templates/twitter.html b/themes/hackit0x16/templates/twitter.html new file mode 100644 index 0000000..e69de29 diff --git a/themes/to0x19/static/effects.scss b/themes/to0x19/static/effects.scss new file mode 100644 index 0000000..5a2437c --- /dev/null +++ b/themes/to0x19/static/effects.scss @@ -0,0 +1,78 @@ +/* pulse {{{ */ +.pulse { + border-radius: 50%; + cursor: pointer; + box-shadow: 0 0 0 rgba(255,255,255, 0); +} +.pulse:hover { + animation: none; +} + +@-webkit-keyframes pulse { + 0% { + -webkit-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 17% { + -webkit-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 20% { + -webkit-box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + } + 23% { + -webkit-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 26% { + -webkit-box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + } + 29% { + -webkit-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 100% { + -webkit-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } +} +@keyframes pulse { + 0% { + -moz-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 17% { + -moz-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 20% { + -moz-box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + } + 23% { + -moz-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 26% { + -moz-box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + box-shadow: 0 0 0 2vw rgba(130,130,130,0.4); + } + 29% { + -moz-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } + 100% { + -moz-box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + box-shadow: 0 0 0 0 rgba(130,130,130,0.4); + } +} +/* pulse }}} */ + +/* rotate {{{ */ +.rotate { + animation: rotation 1s infinite ease-out; +} +@keyframes rotation { + from { + transform: rotate(0deg); + } + to { + transform: rotate(1440deg); + } +} +/* rotate }}} */ diff --git a/themes/to0x19/static/fonts/Metropolis-Black.eot b/themes/to0x19/static/fonts/Metropolis-Black.eot new file mode 100644 index 0000000..271b2d1 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Black.eot differ diff --git a/themes/to0x19/static/fonts/Metropolis-Black.ttf b/themes/to0x19/static/fonts/Metropolis-Black.ttf new file mode 100644 index 0000000..ba26a9d Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Black.ttf differ diff --git a/themes/to0x19/static/fonts/Metropolis-Black.woff b/themes/to0x19/static/fonts/Metropolis-Black.woff new file mode 100644 index 0000000..0b4022d Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Black.woff differ diff --git a/themes/to0x19/static/fonts/Metropolis-Black.woff2 b/themes/to0x19/static/fonts/Metropolis-Black.woff2 new file mode 100644 index 0000000..9ad74d2 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Black.woff2 differ diff --git a/themes/to0x19/static/fonts/Metropolis-Bold.eot b/themes/to0x19/static/fonts/Metropolis-Bold.eot new file mode 100644 index 0000000..ee79d48 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Bold.eot differ diff --git a/themes/to0x19/static/fonts/Metropolis-Bold.ttf b/themes/to0x19/static/fonts/Metropolis-Bold.ttf new file mode 100644 index 0000000..384bc52 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Bold.ttf differ diff --git a/themes/to0x19/static/fonts/Metropolis-Bold.woff b/themes/to0x19/static/fonts/Metropolis-Bold.woff new file mode 100644 index 0000000..8538378 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Bold.woff differ diff --git a/themes/to0x19/static/fonts/Metropolis-Bold.woff2 b/themes/to0x19/static/fonts/Metropolis-Bold.woff2 new file mode 100644 index 0000000..9648b0c Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Bold.woff2 differ diff --git a/themes/to0x19/static/fonts/Metropolis-Regular.eot b/themes/to0x19/static/fonts/Metropolis-Regular.eot new file mode 100644 index 0000000..ab4572a Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Regular.eot differ diff --git a/themes/to0x19/static/fonts/Metropolis-Regular.svg b/themes/to0x19/static/fonts/Metropolis-Regular.svg new file mode 100644 index 0000000..46d3ffb --- /dev/null +++ b/themes/to0x19/static/fonts/Metropolis-Regular.svg @@ -0,0 +1,698 @@ + + + + +Created by FontForge 20200427 at Fri Oct 27 00:40:41 2017 + By www +Copyright (c) 2016 by Chris Simpson. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/to0x19/static/fonts/Metropolis-Regular.ttf b/themes/to0x19/static/fonts/Metropolis-Regular.ttf new file mode 100644 index 0000000..012acd8 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Regular.ttf differ diff --git a/themes/to0x19/static/fonts/Metropolis-Regular.woff b/themes/to0x19/static/fonts/Metropolis-Regular.woff new file mode 100644 index 0000000..6aa4dba Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Regular.woff differ diff --git a/themes/to0x19/static/fonts/Metropolis-Regular.woff2 b/themes/to0x19/static/fonts/Metropolis-Regular.woff2 new file mode 100644 index 0000000..f50bf34 Binary files /dev/null and b/themes/to0x19/static/fonts/Metropolis-Regular.woff2 differ diff --git a/themes/to0x19/static/fonts/Metropolis_Bold.svg b/themes/to0x19/static/fonts/Metropolis_Bold.svg new file mode 100644 index 0000000..45bd55d --- /dev/null +++ b/themes/to0x19/static/fonts/Metropolis_Bold.svg @@ -0,0 +1,705 @@ + + + + +Created by FontForge 20200427 at Fri Feb 16 17:26:47 2018 + By www +Copyright (c) 2016 by Chris Simpson. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/to0x19/static/fonts/fonts.scss b/themes/to0x19/static/fonts/fonts.scss new file mode 100644 index 0000000..d6ca198 --- /dev/null +++ b/themes/to0x19/static/fonts/fonts.scss @@ -0,0 +1,45 @@ +/* recursive-regular - latin */ +$font-display: swap; +@font-face { + font-family: 'Recursive'; + font-display: $font-display; + font-style: normal; + font-weight: 400; + src: url('fonts/recursive-v20-latin-regular.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/recursive-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/recursive-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/recursive-v20-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('fonts/recursive-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/recursive-v20-latin-regular.svg#Recursive') format('svg'); /* Legacy iOS */ +} + +/* recursive-500 - latin */ +@font-face { + font-display: $font-display; + font-family: 'Recursive'; + font-style: normal; + font-weight: 500; + src: url('fonts/recursive-v20-latin-500.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/recursive-v20-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/recursive-v20-latin-500.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/recursive-v20-latin-500.woff') format('woff'), /* Modern Browsers */ + url('fonts/recursive-v20-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/recursive-v20-latin-500.svg#Recursive') format('svg'); /* Legacy iOS */ +} + +/* recursive-800 - latin */ +@font-face { + font-display: $font-display; + font-family: 'Recursive'; + font-style: normal; + font-weight: 800; + src: url('fonts/recursive-v20-latin-800.eot'); /* IE9 Compat Modes */ + src: local(''), + url('fonts/recursive-v20-latin-800.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('fonts/recursive-v20-latin-800.woff2') format('woff2'), /* Super Modern Browsers */ + url('fonts/recursive-v20-latin-800.woff') format('woff'), /* Modern Browsers */ + url('fonts/recursive-v20-latin-800.ttf') format('truetype'), /* Safari, Android, iOS */ + url('fonts/recursive-v20-latin-800.svg#Recursive') format('svg'); /* Legacy iOS */ +} diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-500.eot b/themes/to0x19/static/fonts/recursive-v20-latin-500.eot new file mode 100644 index 0000000..eff1031 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-500.eot differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-500.svg b/themes/to0x19/static/fonts/recursive-v20-latin-500.svg new file mode 100644 index 0000000..ff07549 --- /dev/null +++ b/themes/to0x19/static/fonts/recursive-v20-latin-500.svg @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-500.ttf b/themes/to0x19/static/fonts/recursive-v20-latin-500.ttf new file mode 100644 index 0000000..e0402a9 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-500.ttf differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-500.woff b/themes/to0x19/static/fonts/recursive-v20-latin-500.woff new file mode 100644 index 0000000..8926fce Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-500.woff differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-500.woff2 b/themes/to0x19/static/fonts/recursive-v20-latin-500.woff2 new file mode 100644 index 0000000..e7938e1 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-500.woff2 differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-800.eot b/themes/to0x19/static/fonts/recursive-v20-latin-800.eot new file mode 100644 index 0000000..df17921 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-800.eot differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-800.svg b/themes/to0x19/static/fonts/recursive-v20-latin-800.svg new file mode 100644 index 0000000..9d522e3 --- /dev/null +++ b/themes/to0x19/static/fonts/recursive-v20-latin-800.svg @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-800.ttf b/themes/to0x19/static/fonts/recursive-v20-latin-800.ttf new file mode 100644 index 0000000..3c2b2ca Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-800.ttf differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-800.woff b/themes/to0x19/static/fonts/recursive-v20-latin-800.woff new file mode 100644 index 0000000..776daa7 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-800.woff differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-800.woff2 b/themes/to0x19/static/fonts/recursive-v20-latin-800.woff2 new file mode 100644 index 0000000..28f9edc Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-800.woff2 differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-regular.eot b/themes/to0x19/static/fonts/recursive-v20-latin-regular.eot new file mode 100644 index 0000000..b86b248 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-regular.eot differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-regular.svg b/themes/to0x19/static/fonts/recursive-v20-latin-regular.svg new file mode 100644 index 0000000..8d6e65e --- /dev/null +++ b/themes/to0x19/static/fonts/recursive-v20-latin-regular.svg @@ -0,0 +1,614 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-regular.ttf b/themes/to0x19/static/fonts/recursive-v20-latin-regular.ttf new file mode 100644 index 0000000..141ff71 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-regular.ttf differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff b/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff new file mode 100644 index 0000000..3380075 Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff differ diff --git a/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff2 b/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff2 new file mode 100644 index 0000000..522dcba Binary files /dev/null and b/themes/to0x19/static/fonts/recursive-v20-latin-regular.woff2 differ diff --git a/themes/to0x19/static/images/hamburger24.png b/themes/to0x19/static/images/hamburger24.png new file mode 100644 index 0000000..d985582 Binary files /dev/null and b/themes/to0x19/static/images/hamburger24.png differ diff --git a/themes/to0x19/static/images/hamburger24_color.png b/themes/to0x19/static/images/hamburger24_color.png new file mode 100644 index 0000000..ecef920 Binary files /dev/null and b/themes/to0x19/static/images/hamburger24_color.png differ diff --git a/themes/to0x19/static/images/logoHM24_color2_sito.png b/themes/to0x19/static/images/logoHM24_color2_sito.png new file mode 100644 index 0000000..dcb3fd8 Binary files /dev/null and b/themes/to0x19/static/images/logoHM24_color2_sito.png differ diff --git a/themes/to0x19/static/images/logoHM24_sito.png b/themes/to0x19/static/images/logoHM24_sito.png new file mode 100644 index 0000000..040f9b7 Binary files /dev/null and b/themes/to0x19/static/images/logoHM24_sito.png differ diff --git a/themes/to0x19/static/main.scss b/themes/to0x19/static/main.scss new file mode 100644 index 0000000..7f37bc5 --- /dev/null +++ b/themes/to0x19/static/main.scss @@ -0,0 +1,3 @@ +@import 'theme'; +@import 'effects'; +@import 'talk'; diff --git a/themes/to0x19/static/media-queries.scss b/themes/to0x19/static/media-queries.scss new file mode 100644 index 0000000..9ba29bc --- /dev/null +++ b/themes/to0x19/static/media-queries.scss @@ -0,0 +1,92 @@ +// media aliases and breakpoints +$screen-sm-min: 600px; +$screen-md-min: 960px; +$screen-lg-min: 1280px; +$screen-xl-min: 1920px; + +$screen-xs-max: 599px; +$screen-sm-max: 959px; +$screen-md-max: 1279px; +$screen-lg-max: 1919px; +$screen-xl-max: 5000px; + +// media devices +@mixin xs { + @media screen and (max-width: #{$screen-xs-max}) { + @content; + } +} + +@mixin sm { + @media screen and (min-width: #{$screen-sm-min}) and (max-width: #{$screen-sm-max}) { + @content; + } +} + +@mixin md { + @media screen and (min-width: #{$screen-md-min}) and (max-width: #{$screen-md-max}) { + @content; + } +} + +@mixin lg { + @media screen and (min-width: #{$screen-lg-min}) and (max-width: #{$screen-lg-max}) { + @content; + } +} + +@mixin xl { + @media screen and (min-width: #{$screen-xl-min}) and (max-width: #{$screen-xl-max}) { + @content; + } +} + +// media lt queries +@mixin lt-sm { + @media screen and (max-width: #{$screen-xs-max}) { + @content; + } +} + +@mixin lt-md { + @media screen and (max-width: #{$screen-sm-max}) { + @content; + } +} + +@mixin lt-lg { + @media screen and (max-width: #{$screen-md-max}) { + @content; + } +} + +@mixin lt-xl { + @media screen and (max-width: #{$screen-lg-max}) { + @content; + } +} + +// media gt queries +@mixin gt-xs { + @media screen and (min-width: #{$screen-sm-min}) { + @content; + } +} + +@mixin gt-sm { + @media screen and (min-width: #{$screen-md-min}) { + @content; + } +} + +@mixin gt-md { + @media screen and (min-width: #{$screen-lg-min}) { + @content; + } +} + +@mixin gt-lg { + @media screen and (min-width: #{$screen-xl-min}) { + @content; + } +} \ No newline at end of file diff --git a/themes/to0x19/static/ruotalogo.js b/themes/to0x19/static/ruotalogo.js new file mode 100644 index 0000000..1e0d3e7 --- /dev/null +++ b/themes/to0x19/static/ruotalogo.js @@ -0,0 +1,55 @@ +function menu_get() { + return document.querySelector('#menu-row') +} +function menu_is_shown() { + return (window.getComputedStyle(menu_get()).display !== 'none') +} +function menu_hide() { + menu_get().style.display = 'none' + document.querySelector('#overlay').style.height = '0' +} +function menu_show() { + menu_get().style.display = 'block' + document.querySelector('#overlay').style.height = '100%' +} +document.addEventListener('DOMContentLoaded', function() { + var logo = document.getElementById('logo-img') + logo.classList.add('rotate') + function ruotaLogo() { + logo.style.transform = 'rotate(' + -window.pageYOffset/2+'deg)' + } + function scrollSetup() { + "use strict"; + var last_known_scroll_position = 0 + var ticking = false + + window.addEventListener('scroll', function (e) { + last_known_scroll_position = window.scrollY + + if (!ticking) { + window.requestAnimationFrame(function () { + + ruotaLogo() + ticking = false; + }); + + ticking = true; + } + }) + } + setTimeout(function () { + logo.classList.remove('rotate') + scrollSetup() + }, 1000) + logo.addEventListener('click', function (evt) { + if (!menu_is_shown()) { + menu_show() + } else { + menu_hide() + } + }) + + document.querySelector('#overlay').addEventListener('click', function (evt) { + menu_hide() + }) +}) diff --git a/themes/to0x19/static/skeleton/css/normalize.css b/themes/to0x19/static/skeleton/css/normalize.css new file mode 100644 index 0000000..81c6f31 --- /dev/null +++ b/themes/to0x19/static/skeleton/css/normalize.css @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} \ No newline at end of file diff --git a/themes/to0x19/static/skeleton/css/skeleton.css b/themes/to0x19/static/skeleton/css/skeleton.css new file mode 100644 index 0000000..f28bf6c --- /dev/null +++ b/themes/to0x19/static/skeleton/css/skeleton.css @@ -0,0 +1,418 @@ +/* +* Skeleton V2.0.4 +* Copyright 2014, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 12/29/2014 +*/ + + +/* Table of contents +–––––––––––––––––––––––––––––––––––––––––––––––––– +- Grid +- Base Styles +- Typography +- Links +- Buttons +- Forms +- Lists +- Code +- Tables +- Spacing +- Utilities +- Clearing +- Media Queries +*/ + + +/* Grid +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.container { + position: relative; + width: 100%; + max-width: 960px; + margin: 0 auto; + padding: 0 20px; + box-sizing: border-box; } +.column, +.columns { + width: 100%; + float: left; + box-sizing: border-box; } + +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 85%; + padding: 0; } +} + +/* For devices larger than 550px */ +@media (min-width: 550px) { + .container { + width: 80%; } + .column, + .columns { + margin-left: 4%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } + + .one.column, + .one.columns { width: 4.66666666667%; } + .two.columns { width: 13.3333333333%; } + .three.columns { width: 22%; } + .four.columns { width: 30.6666666667%; } + .five.columns { width: 39.3333333333%; } + .six.columns { width: 48%; } + .seven.columns { width: 56.6666666667%; } + .eight.columns { width: 65.3333333333%; } + .nine.columns { width: 74.0%; } + .ten.columns { width: 82.6666666667%; } + .eleven.columns { width: 91.3333333333%; } + .twelve.columns { width: 100%; margin-left: 0; } + + .one-third.column { width: 30.6666666667%; } + .two-thirds.column { width: 65.3333333333%; } + + .one-half.column { width: 48%; } + + /* Offsets */ + .offset-by-one.column, + .offset-by-one.columns { margin-left: 8.66666666667%; } + .offset-by-two.column, + .offset-by-two.columns { margin-left: 17.3333333333%; } + .offset-by-three.column, + .offset-by-three.columns { margin-left: 26%; } + .offset-by-four.column, + .offset-by-four.columns { margin-left: 34.6666666667%; } + .offset-by-five.column, + .offset-by-five.columns { margin-left: 43.3333333333%; } + .offset-by-six.column, + .offset-by-six.columns { margin-left: 52%; } + .offset-by-seven.column, + .offset-by-seven.columns { margin-left: 60.6666666667%; } + .offset-by-eight.column, + .offset-by-eight.columns { margin-left: 69.3333333333%; } + .offset-by-nine.column, + .offset-by-nine.columns { margin-left: 78.0%; } + .offset-by-ten.column, + .offset-by-ten.columns { margin-left: 86.6666666667%; } + .offset-by-eleven.column, + .offset-by-eleven.columns { margin-left: 95.3333333333%; } + + .offset-by-one-third.column, + .offset-by-one-third.columns { margin-left: 34.6666666667%; } + .offset-by-two-thirds.column, + .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } + + .offset-by-one-half.column, + .offset-by-one-half.columns { margin-left: 52%; } + +} + + +/* Base Styles +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* NOTE +html is set to 62.5% so that all the REM measurements throughout Skeleton +are based on 10px sizing. So basically 1.5rem = 15px :) */ +html { + font-size: 62.5%; } +body { + font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ + line-height: 1.6; + font-weight: 400; + font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #222; } + + +/* Typography +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 2rem; + font-weight: 300; } +h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} +h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } +h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } +h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } +h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } +h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } + +/* Larger than phablet */ +@media (min-width: 550px) { + h1 { font-size: 5.0rem; } + h2 { font-size: 4.2rem; } + h3 { font-size: 3.6rem; } + h4 { font-size: 3.0rem; } + h5 { font-size: 2.4rem; } + h6 { font-size: 1.5rem; } +} + +p { + margin-top: 0; } + + +/* Links +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +a { + color: #1EAEDB; } +a:hover { + color: #0FA0CE; } + + +/* Buttons +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.button, +button, +input[type="submit"], +input[type="reset"], +input[type="button"] { + display: inline-block; + height: 38px; + padding: 0 30px; + color: #555; + text-align: center; + font-size: 11px; + font-weight: 600; + line-height: 38px; + letter-spacing: .1rem; + text-transform: uppercase; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border-radius: 4px; + border: 1px solid #bbb; + cursor: pointer; + box-sizing: border-box; } +.button:hover, +button:hover, +input[type="submit"]:hover, +input[type="reset"]:hover, +input[type="button"]:hover, +.button:focus, +button:focus, +input[type="submit"]:focus, +input[type="reset"]:focus, +input[type="button"]:focus { + color: #333; + border-color: #888; + outline: 0; } +.button.button-primary, +button.button-primary, +input[type="submit"].button-primary, +input[type="reset"].button-primary, +input[type="button"].button-primary { + color: #FFF; + background-color: #33C3F0; + border-color: #33C3F0; } +.button.button-primary:hover, +button.button-primary:hover, +input[type="submit"].button-primary:hover, +input[type="reset"].button-primary:hover, +input[type="button"].button-primary:hover, +.button.button-primary:focus, +button.button-primary:focus, +input[type="submit"].button-primary:focus, +input[type="reset"].button-primary:focus, +input[type="button"].button-primary:focus { + color: #FFF; + background-color: #1EAEDB; + border-color: #1EAEDB; } + + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } + + +/* Lists +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +ul { + list-style: circle inside; } +ol { + list-style: decimal inside; } +ol, ul { + padding-left: 0; + margin-top: 0; } +ul ul, +ul ol, +ol ol, +ol ul { + margin: 1.5rem 0 1.5rem 3rem; + font-size: 90%; } +li { + margin-bottom: 1rem; } + + +/* Code +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +code { + padding: .2rem .5rem; + margin: 0 .2rem; + font-size: 90%; + white-space: nowrap; + background: #F1F1F1; + border: 1px solid #E1E1E1; + border-radius: 4px; } +pre > code { + display: block; + padding: 1rem 1.5rem; + white-space: pre; } + + +/* Tables +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +th, +td { + padding: 12px 15px; + text-align: left; + border-bottom: 1px solid #E1E1E1; } +th:first-child, +td:first-child { + padding-left: 0; } +th:last-child, +td:last-child { + padding-right: 0; } + + +/* Spacing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +button, +.button { + margin-bottom: 1rem; } +input, +textarea, +select, +fieldset { + margin-bottom: 1.5rem; } +pre, +blockquote, +dl, +figure, +table, +p, +ul, +ol, +form { + margin-bottom: 2.5rem; } + + +/* Utilities +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.u-full-width { + width: 100%; + box-sizing: border-box; } +.u-max-full-width { + max-width: 100%; + box-sizing: border-box; } +.u-pull-right { + float: right; } +.u-pull-left { + float: left; } + + +/* Misc +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +hr { + margin-top: 3rem; + margin-bottom: 3.5rem; + border-width: 0; + border-top: 1px solid #E1E1E1; } + + +/* Clearing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ + +/* Self Clearing Goodness */ +.container:after, +.row:after, +.u-cf { + content: ""; + display: table; + clear: both; } + + +/* Media Queries +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* +Note: The best way to structure the use of media queries is to create the queries +near the relevant code. For example, if you wanted to change the styles for buttons +on small devices, paste the mobile query code up in the buttons section and style it +there. +*/ + + +/* Larger than mobile */ +@media (min-width: 400px) {} + +/* Larger than phablet (also point when grid becomes active) */ +@media (min-width: 550px) {} + +/* Larger than tablet */ +@media (min-width: 750px) {} + +/* Larger than desktop */ +@media (min-width: 1000px) {} + +/* Larger than Desktop HD */ +@media (min-width: 1200px) {} diff --git a/themes/to0x19/static/talk.scss b/themes/to0x19/static/talk.scss new file mode 100644 index 0000000..0dbdcfa --- /dev/null +++ b/themes/to0x19/static/talk.scss @@ -0,0 +1,17 @@ +.talk-grid { + .talk { text-align: center; } + td { border: 0; } + td.talk-grid-time { + border-bottom: 1px solid #444; + border-top: 1px solid #444; + vertical-align: top; + padding-top: 0; +} + td.talk { padding-bottom: 1em; padding-top: 1em; line-height: 1.2em; } + .tag-cibo { + background-color: adjust-color($c-bg, $lightness: -15%); + } + .talk-grid-time-minutes-15, .talk-grid-time-minutes-45 { + visibility: hidden; + } +} diff --git a/themes/to0x19/static/theme.scss b/themes/to0x19/static/theme.scss new file mode 100644 index 0000000..943389a --- /dev/null +++ b/themes/to0x19/static/theme.scss @@ -0,0 +1,257 @@ +/* + * palette da 4 colori che pare abbiano un che di maya: + * Crimson sky (#CF6766),Indigo (#30415D), Ultramarine (#031424) e Light Blue (#8EAEBD); + * oppureuna palette forse veramente troppo colorata e accesa: + * Papaya (#E24E42), Mustard(#E9B000), Blush (#EB6E80) e Aqua (#008F95). + * */ + +@import 'media-queries.scss'; + +// variant 1 +//$c-crimson-sky: #CF6766; +$c-crimson-sky: #d9756d; +$c-indigo: #30415D; +$c-ultramarine: #031424; +$c-lightblue: #8EAEBD; + +// variant 2 +$c-magenta: #f05191; +$c-indigo-dye: #1A86C8; +$c-wild-orchid: #FF5AB7; + +$c-eerie-black: #222; +$c-alice-blue: #EBF4F8; +$c-international-orange-golden-gate-bridge: #C03221; // quasi rosso +$c-sandy-brown: #EE964B; // arancione +$c-maroon: #B7245C; // na specie di magenta +$c-star-command-blue: #2274A5; + +// variant 1 +// $c-primary: $c-star-command-blue; +// $c-secondary: $c-alice-blue; +// $c-tertiary: $c-eerie-black; +// $c-quaternary: $c-wild-orchid; + +$c-primary: #6cb52f;//$c-indigo-dye; +$c-secondary: $c-alice-blue; +$c-tertiary: #1c1c1a;//$c-eerie-black; +// $c-quaternary: $c-wild-orchid; +$c-quaternary: #6cb52f;//$c-wild-orchid; + +// https://coolors.co/f05191-0d4264-c07291-ebf4f8 +$c-text: $c-secondary; +$c-bg: $c-tertiary; +$c-bg-menu: adjust-color($c-bg, $lightness: -20%); +$c-titles: $c-primary; +$c-links: $c-quaternary; +$c-smalltitles: $c-titles; //adjust-color($c-titles, $lightness: +15%); + +// variant 2 +/* +$c-primary: $c-papaya; +$c-secondary: $c-mustard; +$c-tertiary: $c-blush; +$c-quaternary: $c-aqua; + +$c-text: $c-secondary; +$c-bg: #006165; // $c-quaternary; +$c-bg-menu: adjust-color($c-bg, $lightness: -10%); //rgb(34, 34, 34); +$c-titles: $c-primary; +$c-smalltitles: adjust-color($c-titles, $saturation: -15%, $lightness: -15%); +$c-links: $c-titles; +*/ + +$f-main: 'Metropolis'; +$f-titles: 'Metropolis'; + + +body { + background-color: $c-bg; + font-size: 20px; + color: $c-text; + font-family: $f-main, Helvetica, cursive, sans-serif; + line-height: 1.5em; + + display: flex; + flex-direction: column; + min-height: 100vh; // senno' nelle pagine corte non funziona + justify-content: space-between; // cosi' li allontaniamo al massimo + row-gap: 7rem; //distanza contenuto-menu +} +a, a:focus, a:hover, a:visited { color: $c-links; } +#header-row { // il titolo va colorato non come fosse un link + a, a:focus, a:active { color: $c-titles; } +} +@mixin larghezza-corpo { + padding-right: 8vw; + padding-left: 2vw; + width: 90%; + max-width: 50em; + margin: 0 auto; +} +h1,h2,h3 { color: $c-titles; } +h4,h5,h6 { + color: $c-smalltitles; + } +#all-wrapper { + @include larghezza-corpo; + margin-top: 3rem; + h1,h2,h3 { color: $c-titles; } + h4,h5,h6 { + color: $c-smalltitles; + } + h1,h2,h3 { + font-family: $f-titles, $f-main, Helvetica, cursive, sans-serif; + font-weight: bolder; + } + strong { font-weight: bold; } +} +#logo-div { + position: fixed; + top: 5vw; + left: -6.5vw; + + border-radius: 50%; + box-shadow: 0px 0 1.3vw black; + line-height: 0; + background-color: transparent; +} + +img { + max-width: 100%; +} + +#logo-img { + width: 13vw; + /* alloca una dimensione approssimativa prima del rendering + * non sappiamo la dimensione esatta, ma con min-height possiamo indicargli che è circa-quadrata + * */ + min-height: 12vw; + /* questo filtro assurdo viene da https://codepen.io/sosuke/pen/Pjoqqp + si tratta di un modo per "convertire" il nero in un altro colore qualsiasi + */ + //filter: invert(79%) sepia(8%) saturate(6176%) hue-rotate(325deg) brightness(97%) contrast(91%) +} +#header-row { + text-align: center; + margin-bottom: 1vw; + h1 { margin: 0; } + a { + text-decoration: none; + @include gt-sm { + font-size: 6rem; + } + @include sm { + font-size: 4.5rem; + } + @include lt-sm { + font-size: 3rem; + } + font-weight: normal; + &:hover { + text-decoration: underline; + } + } +} +.page-slug--index #content .entry-title { display: none; } +.translations-available { + text-align: right; +} +code { + background-color: #333; + border: 1px solid #888; + border-radius: 0.4em; +} + +// BEGIN menu +#menu-row { + display: none; + position: fixed; + z-index: 20; + top: 3em; + left: 8vw; + background: $c-bg-menu; + width: 89vw; + margin-top: 8vw; + border-radius: 1em; + padding: 1em 0px; + ul { list-style: none; } + font-size: 120%; + > div { + max-width: 15em; + text-align: center; + margin: auto; + } + button { + border: none; + color: $c-wild-orchid; + } +} +#overlay { + display: block; + position: fixed; + left: 0; + top: 0; + background-color: rgba(0,0,0,0.5); + overflow-x: hidden; + transition: 0.3s; + width: 100%; + height: 0; + z-index: 3; +} + +@mixin flex-menu-container { + display: flex; + justify-content: space-evenly; + align-items: center; + column-gap: 1.5em; +} +@mixin flex-menu-item { + flex: 1; +} + +#menu-noscript-row { + @include larghezza-corpo; + align-self: flex-end; + nav { + font-size: 80%; + font-weight: bold; + font-family: $f-titles, $f-main, Helvetica, cursive, sans-serif; + text-align: center; + ul { + @include flex-menu-container; + list-style: none; + @include lt-md { + flex-wrap: wrap; + } + } + li { + @include flex-menu-item; + @include lt-md { + flex-basis: 100%; + } + // font-size: 50%; + a:visited, a:hover, a:active, a { + text-decoration: none; + } + white-space: nowrap; + } + } +} + + +// END menu +.news > #content { // pagina news + #posts-list { list-style: none; } + .published { text-align: right; font-size: 80%; } +} + +.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +// Contenta, 朱莉娅 酷 ? +#talk-maschio-femmina-palle .caps { font-variant-caps: all-small-caps; } + diff --git a/themes/to0x19/templates/article_infos.html b/themes/to0x19/templates/article_infos.html new file mode 100644 index 0000000..0724186 --- /dev/null +++ b/themes/to0x19/templates/article_infos.html @@ -0,0 +1,17 @@ +
+
+ Published: +
+ {% if article.modified %} +
+ + Updated: {{ article.locale_modified }} + + {% endif %} + + {# +

In {{ article.category }}.

+#} +{% import 'translations.html' as translations with context %} +{{ translations.translations_for(article) }} +
diff --git a/themes/to0x19/templates/base.html b/themes/to0x19/templates/base.html new file mode 100644 index 0000000..aeac758 --- /dev/null +++ b/themes/to0x19/templates/base.html @@ -0,0 +1,103 @@ + + + + {% block title %}{{ SITENAME }}{%endblock%} || HackIT {{ hm.year }} + + + + + + + + {% assets filters="libsass", output="theme.css", "main.scss" %} + + {% endassets %} + {% assets filters="libsass", output="fonts.css", "fonts/fonts.scss" %} + + {% endassets %} + + {% if FAVICON %} + + {% endif %} + {% if FEED_ALL_ATOM %} + + {% endif %} + {% if FEED_ALL_RSS %} + + {% endif %} + {% block extra_head %}{%endblock%} + + +
+ + + MENU + +
+
+
+
+
+ + HACKMEETING + +
+
+
+ +
+
+ {% block content %} {% endblock content %} +
+
+
+ +
+ + + diff --git a/themes/to0x19/templates/index.html b/themes/to0x19/templates/index.html new file mode 100644 index 0000000..cd3f3eb --- /dev/null +++ b/themes/to0x19/templates/index.html @@ -0,0 +1,36 @@ +{% extends "base.html" %} +{% block content_title %}{% endblock %} +{% block content %} +
+{% if articles %} + {% for article in articles_page.object_list %} + + {% if loop.first %} +
+
    + {% endif %} +
  1. + {% if loop.last %} + {% if loop.length > 1 or articles_page.has_other_pages() %} +
+ {% if articles_page.has_other_pages() %} + {% include 'pagination.html' %} + {% endif %} +
+ {% endif %} + {% endif %} + {% endfor %} +{% endif %} +
+{% endblock content %} diff --git a/themes/to0x19/templates/page.html b/themes/to0x19/templates/page.html new file mode 100644 index 0000000..7b44da3 --- /dev/null +++ b/themes/to0x19/templates/page.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% block html_lang %}{{ page.lang }}{% endblock %} +{% block title %}{{ page.title }}{% endblock %} + +{% block extra_head %} +{% import 'translations.html' as translations with context %} +{% if translations.entry_hreflang(page) %} + {{ translations.entry_hreflang(page) }} +{% endif %} +{% endblock %} + +{% block body_classes %} +page-slug--{{page.slug}} +{% endblock %} + +{% block content %} +
+

{{ page.title }}

+ {% import 'translations.html' as translations with context %} + {{ translations.translations_for(page) }} + {{ page.content }} +
+{% endblock %} + diff --git a/themes/to0x19/templates/translations.html b/themes/to0x19/templates/translations.html new file mode 100644 index 0000000..fc094dd --- /dev/null +++ b/themes/to0x19/templates/translations.html @@ -0,0 +1,18 @@ +{% macro translations_for(article) %} +{% if article.translations %} +
+Translations: + {% for translation in article.translations %} + {{ translation.lang }} + {% endfor %} +
+{% endif %} +{% endmacro %} + +{% macro entry_hreflang(entry) %} +{% if entry.translations %} + {% for translation in entry.translations %} + + {% endfor %} +{% endif %} +{% endmacro %}