Author SHA1 Message Date
coja db60f55c73 [NoJS] reimplementing js features without the js 2026-08-10 16:19:59 +02:00
coja 904ed7e317 [Theme] fix persist pages 2026-08-09 06:53:25 +02:00
coja f6093d9876 [Fix] no more sudo for dev 2026-08-09 06:26:17 +02:00
coja 740a90536d [Fix] hamburger undefined 2026-08-09 06:08:56 +02:00
coja 26d1295006 [Fix] lang 2026-08-09 06:07:20 +02:00
coja 352709cec6 Revert "[Fix] no more sudo needed, runtime warn"
This reverts commit cc0127dbe3.
2026-08-09 06:02:28 +02:00
30 changed files with 552 additions and 903 deletions
+1
View File
@@ -17,6 +17,7 @@ events.ical
.vscode/
events.html
events_archive.html
nginx.pid
!site/lif*
+40 -45
View File
@@ -1,4 +1,4 @@
from jinja2 import Environment, FileSystemLoader
#! /usr/bin/env python3
import os
PAGES = [
@@ -29,60 +29,55 @@ PAGES = [
},
]
env = Environment(loader=FileSystemLoader("template"))
def buildPage(
filename: str, pageTitle: str, pageHtml: str, pageStyle: str, template: str, lang: str
) -> str:
template = template.replace("<!--TITLE-->", pageTitle)
style = (
""
if not pageStyle
else f'<link rel="stylesheet" href="/styles/{pageStyle}.css">'
)
template = template.replace("<!--ADDITIONAL_STYLE-->", style)
template = template.replace("PAGE_NAME", filename)
template = template.replace("<!--MAIN-->", pageHtml)
# Fix language switcher links
if lang == "en":
template = template.replace('href="/PAGE_NAME"', f'href="/en/{filename}"')
else:
template = template.replace('href="/en/PAGE_NAME"', f'href="/sr/{filename}"')
return template
def main():
os.makedirs("site/en/", exist_ok=True)
with open("template/page-en.html") as fTempEN, open(
"template/page-sr.html"
) as fTempSR:
templateSR = fTempSR.read()
templateEN = fTempEN.read()
for page in PAGES:
# Build SR Page
with open(f'pages/sr/{page["name"]}.html') as f:
page_content = "<div class='cover-wrap'><img src='/img/students_bug.jpg' alt='Studenti su nasli bug' /></div>"
page_content += f.read()
sr_html = env.get_template("page-sr.html").render(
title=page["titleSR"],
content=page_content,
extra_styles=(
f'<link rel="stylesheet" href="/styles/{page["style"]}.css">'
if page["style"]
else ""
),
lang="sr",
sr_link=f"/en/{page['name']}",
current_path=f"/{page['name']}" if page["name"] != "index" else "/",
pageHtml = "<div class='cover-wrap'><img src='/img/students_bug.jpg' alt='Studenti su nasli bug' /></div>"
pageHtml += f.read()
html = buildPage(
page["name"], page["titleSR"], pageHtml, page["style"], templateSR, "sr"
)
sr_filename = (
"index.html" if page["name"] == "index" else f"{page['name']}.html"
)
with open(f"site/{sr_filename}", "w") as f:
f.write(sr_html)
# Build EN Page
f = open(f'site/{page["name"]}.html', "w")
f.write(html)
f.close()
with open(f'pages/en/{page["name"]}.html') as f:
page_content = "<div class='cover-wrap'><img src='/img/students_bug.jpg' alt='Students found the bug' /></div>"
page_content += f.read()
en_html = env.get_template("page-en.html").render(
title=page["titleEN"],
content=page_content,
extra_styles=(
f'<link rel="stylesheet" href="/styles/{page["style"]}.css">'
if page["style"]
else ""
),
lang="en",
sr_link=f"/{page['name']}",
current_path=f"/en/{page['name']}" if page["name"] != "index" else "/en/",
pageHtml = "<div class='cover-wrap'><img src='/img/students_bug.jpg' alt='Students found the bug' /></div>"
pageHtml += f.read()
html = buildPage(
page["name"], page["titleEN"], pageHtml, page["style"], templateEN, "en"
)
en_filename = (
"index.html" if page["name"] == "index" else f"{page['name']}.html"
)
with open(f"site/en/{en_filename}", "w") as f:
f.write(en_html)
f = open(f'site/en/{page["name"]}.html', "w")
f.write(html)
f.close()
if __name__ == "__main__":
-1
View File
@@ -1 +0,0 @@
172000
+3 -8
View File
@@ -1,17 +1,12 @@
<h1>About us</h1>
<dl>
<dt>Statute:</dt>
<dd>
We make decisions by direct democracy. Our statute can be found at
<a href="/en/statute"> statute page</a>
</dd>
<dd> We make decisions by direct democracy. Our statute can be found at <a href="/en/statute"> statute page</a></dd>
<dt>Contact:</dt>
<dd>
You can send mail to <a href="mailto:dmz@dmz.rs">dmz@dmz.rs</a> or you can
register on <a href="https://forum.dmz.rs">our Forum</a>. Also, we are
available on the
<a href="https://balkan.fedive.rs/@decentrala">Fediverse!</a>
You can send mail to <a href="mailto:dmz@dmz.rs">dmz@dmz.rs</a> or you can register on <a href="https://forum.dmz.rs">our Forum</a>.
Also, we are available on the <a href="https://balkan.fedive.rs/@decentrala">Fediverse!</a>
If you find a bug on the site, please do tell us. We would be very grateful.
</dd>
</dl>
+6 -9
View File
@@ -14,13 +14,10 @@
</p>
<div class="auth-wrap">
<p>
<a href="/account/register/">Register</a>
</p>
<p>
<a href="/account/unregister/">Delete account</a>
</p>
<p>
<a href="/account/changepassword/">Change password</a>
</p>
<p><a href="/account/register/">Register</a></p>
<p></p>
<p><a href="/account/unregister/">Delete account</a></p>
<p></p>
<p><a href="/account/changepassword/">Change password</a></p>
<p></p>
</div>
+13 -74
View File
@@ -1,95 +1,34 @@
<h1>Deconference</h1>
<h2 id="program"><a href="#program">Program</a></h2>
<p>11:00 Otvaranje</p>
<p></p>
<p>
12:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p></p>
<p>
14:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a>
</p>
<p></p>
<p>
16:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks"
>Lightning talks</a
>
</p>
<p></p>
<p>18:00 Diskusije</p>
<p></p>
<p>
20:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p></p>
<p>22:00 Kraj</p>
<p></p>
<p>11:00 Otvaranje<p>
<p>12:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>14:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a><p>
<p>16:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks">Lightning talks</a><p>
<p>18:00 Diskusije<p>
<p>20:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>22:00 Kraj<p>
<h2 id="what"><a href="#what">What?</a></h2>
<p>
Deconference is the inaugural conference organized by
<a href="https://dmz.rs">Decentrala</a>, a Belgrade hackerspace. It serves as
a platform for individuals to present and discuss ideas related to
decentralization in all its forms.
</p>
<p>Deconference is the inaugural conference organized by <a href="https://dmz.rs">Decentrala</a>, a Belgrade hackerspace. It serves as a platform for individuals to present and discuss ideas related to decentralization in all its forms.</p>
<h2 id="when-and-where"><a href="#when-and-where">When & Where?</a></h2>
<p>
Deconference will take place all day on Sunday, September 15, 2024, at
Cultural Center Magacin, located at
<a href="https://osm.org/go/xf3Fz31te?node=1226456745"
>Kraljevića Marka 4-8, Belgrade</a
>. The evening prior, a social gathering will be hosted at
<a href="https://dckrov.rs/">Community Center Krov</a>, located at
<a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Belgrade</a>.
</p>
<p>Deconference will take place all day on Sunday, September 15, 2024, at Cultural Center Magacin, located at <a href="https://osm.org/go/xf3Fz31te?node=1226456745">Kraljevića Marka 4-8, Belgrade</a>. The evening prior, a social gathering will be hosted at <a href="https://dckrov.rs/">Community Center Krov</a>, located at <a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Belgrade</a>.</p>
<h2 id="why"><a href="#why">Why?</a></h2>
<p>
Decentrala was founded by a small group of enthusiasts united by the idea of
technological decentralization. Over the past year and a half, we've organized
over 160 events—lectures, workshops, discussions, hackathons—aimed at
democratizing technological knowledge and educating people about privacy, open
source principles, the right to repair (and how to repair), digital assets,
and usage rights. Since day one, our approach has been to inform individuals
about alternatives rather than impose opinions upon them.
</p>
<p>Decentrala was founded by a small group of enthusiasts united by the idea of technological decentralization. Over the past year and a half, we've organized over 160 events—lectures, workshops, discussions, hackathons—aimed at democratizing technological knowledge and educating people about privacy, open source principles, the right to repair (and how to repair), digital assets, and usage rights. Since day one, our approach has been to inform individuals about alternatives rather than impose opinions upon them.</p>
<p>
Through engaging with diverse visitors, many from non-technical backgrounds,
we've come to realize that decentralization encompasses more than just "open
technology." Many activists and organizations today advocate for various forms
of decentralization. Therefore, we welcome stories about decentralization from
diverse perspectives.
</p>
<p>Through engaging with diverse visitors, many from non-technical backgrounds, we've come to realize that decentralization encompasses more than just "open technology." Many activists and organizations today advocate for various forms of decentralization. Therefore, we welcome stories about decentralization from diverse perspectives.</p>
<h2 id="who"><a href="#who">Who?</a></h2>
<p>
Deconference is an open platform for anyone interested in discussing,
demonstrating, or exploring decentralization. You can register your event by
emailing <a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> up
until the day of the Deconference (September 15).
</p>
<p>Deconference is an open platform for anyone interested in discussing, demonstrating, or exploring decentralization. You can register your event by emailing <a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> up until the day of the Deconference (September 15).</p>
<p>We will update this section as topics are confirmed.</p>
<h2 id="how"><a href="#how">How?</a></h2>
<p>
The Deconference is funded by the organizers' private assets. Like all of
Decentrala's activities, Deconference is free for all attendees.
Unfortunately, we are unable to provide grants to lecturers or presenters.
</p>
<p>The Deconference is funded by the organizers' private assets. Like all of Decentrala's activities, Deconference is free for all attendees. Unfortunately, we are unable to provide grants to lecturers or presenters.</p>
<p>Decentrala accepts donations exclusively from individuals.</p>
+13 -54
View File
@@ -1,68 +1,27 @@
<h1>Welcome!</h1>
<p>
We are <em>Decentrala</em> - a group of enthusiasts gathered around the idea
of decentralization and knowledge sharing. Here are some more facts about us:
We are <em>Decentrala</em> - a group of enthusiasts gathered around the idea of decentralization and knowledge sharing.
Here are some more facts about us:
</p>
<dl>
<dt>Motivation:</dt>
<dd>
Decentralization promotes
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#odrzivost"
>sustainability</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#dostupnost"
>availability</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#pristupacnost"
>accesibility</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#nezavisnost"
>autonomy</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#privatnost"
>privacy</a
>
and
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#sloboda"
>freedom</a
>. On those networks we have less
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#manipulacija"
>manipulation</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#propaganda"
>propaganda</a
>, ads, and
<a
href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#neopterecenost-paznje-sporednim-stvarima"
>
are not designed to lock your attention (dumbing down)
</a>
.
<a href="https://forum.dmz.rs/t/zasto-nam-je-decentralizacija-bitna/506/1">
Tell us why decentralization is important to you
</a>
<dd>Decentralization promotes <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#odrzivost">sustainability</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#dostupnost">availability</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#pristupacnost">accesibility</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#nezavisnost">autonomy</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#privatnost">privacy</a> and <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#sloboda">freedom</a>. On those networks we have less <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#manipulacija">manipulation</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#propaganda">propaganda</a>, ads, and <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#neopterecenost-paznje-sporednim-stvarima">are not designed to lock your attention (dumbing down)</a>.
<a href="https://forum.dmz.rs/t/zasto-nam-je-decentralizacija-bitna/506/1">Tell us why decentralization is important to you</a>
</dd>
<dt>Knowledge:</dt>
<dd>
All our workshops are free and open to everyone. Also, if you have something
to share, feel free to announce the event on the
<a href="https://forum.dmz.rs">Forum</a>.
All our workshops are free and open to everyone.
Also, if you have something to share, feel free to announce the event on the <a href="https://forum.dmz.rs"></a>Forum</a>.
</dd>
<dt>Actions:</dt>
<dd>
From time to time we organize actions, hackathons, crypto parties,
exhibitions, etc.
</dd>
<dd>From time to time we organize actions, hackathons, crypto parties, exhibitions, etc.</dd>
<dt>Services:</dt>
<dd>
Our servers run various services (like e-mail, git, wiki, etc...) that are
open to everyone.
</dd>
<dd>Our servers run various services (like e-mail, git, wiki, etc...) that are open to everyone.</dd>
</dl>
<p>
If you are still interested, you can create an
<a href="/en/account">account</a> on our server which will enable the use of
all our <a href="/en/services">services</a>. If you want to see first how it
all looks, you can come to one of our <a href="/en/events">event</a>, and meet
us there!
If you are still interested, you can create an <a href="/en/account">account</a>
on our server which will enable the use of all our <a href="/en/services">services</a>.
If you want to see first how it all looks, you can come to one of our
<a href="/en/events">event</a>, and meet us there!
</p>
+2 -2
View File
@@ -43,8 +43,8 @@
<tr>
<td><a href="https://jitsi.dmz.rs/">Jitsi</a></td>
<td>
<a href="https://jitsi.org/">Jitsi.org</a> meeting app, conferences, group
video calls, online events, alternative to zoom.
<a href="https://jitsi.org/">Jitsi.org</a> meeting app, conferences, group video calls, online events, alternative
to zoom.
</td>
</tr>
<!--<tr>
+18 -48
View File
@@ -2,8 +2,7 @@
<div>
<p>
Decentrala is a community, united around the principles of decentralized
technology and the spreading of knowledge.
Decentrala is a community, united around the principles of decentralized technology and the spreading of knowledge. 
</p>
<div class="values">
<label>Our key values include:</label>
@@ -13,65 +12,36 @@
<li>Privacy and security</li>
</ul>
</div>
<p> Donations are accepted only from individuals, with no conditions or obligations. </p>
<p> Only open-source services are hosted on the Decentrala infrastructure. </p>
<p> Parts of the statute can be defined immutable, and cannot be voted on. </p>
<p>
Donations are accepted only from individuals, with no conditions or
obligations.
</p>
<p>Only open-source services are hosted on the Decentrala infrastructure.</p>
<p>Parts of the statute can be defined immutable, and cannot be voted on.</p>
<p>
Every member or group has the right to act in the name of Decentrala, if
their initiatives align with Decentrala's goals and statute, as long as
their events are announced and explained on Decentrala's public digital
communication channels.
Every member or group has the right to act in the name of Decentrala,
if their initiatives align with Decentralas goals and statute,
as long as their events are announced and explained on Decentralas public digital communication channels.
</p>
<p>
Decentrala rules and statutes are decided independently by a voting body
that makes decisions on the principles of direct democracy, consensus, or by
a simple majority of two-thirds of the total number of collective members.
Decentrala rules and statutes are decided independently by a voting body that makes decisions on the principles of direct democracy,
consensus, or by a simple majority of two-thirds of the total number of collective members.
</p>
</div>
<h2>Voting Body</h2>
<div>
<p>
Membership applications are accepted only if two-thirds of attending members
vote in favor.
</p>
<p>Only members who are physically present have the right to vote.</p>
<p>Membership applications are accepted only if two-thirds of attending members vote in favor. </p>
<p>Only members who are physically present have the right to vote.</p
<p>There is no limit on the number of members of the voting body.</p>
<p>
An individual may withdraw from the union at any time, or may be expelled by
a two-thirds majority of present members.
</p>
<p>
If a member of a voting body is absent during three consecutive meetings,
they are automatically excluded from the voting body.
</p>
<p>
A member can be re-admitted to the governing body according to the
predefined procedure for adding new members, if they are present at that
meeting.
</p>
<p>
The current members of the voting body are using pseudonyms malin, coja,
bora, mad3v, txrpe, euffrat, netstat.
</p>
<p> An individual may withdraw from the union at any time, or may be expelled by a two-thirds majority of present members. </p
<p> If a member of a voting body is absent during three consecutive meetings, they are automatically excluded from the voting body. </p>
<p> A member can be re-admitted to the governing body according to the predefined procedure for adding new members, if they are present at that meeting. </p>
<p> The current members of the voting body are using pseudonyms malin, coja, bora, mad3v, txrpe, euffrat, netstat.</p>
</div>
<h2>Meetings</h2>
<div>
<p>
The vote of the polling body is valid if at least three members of the
polling body are present.
</p>
<p>
The meeting time and place of the Decentral Assembly must be announced at
least seven days in advance of the meeting on the Decentrala's forum.
</p>
<p>
The voting body's session should be held at least once every two months.
</p>
<p> The vote of the polling body is valid if at least three members of the polling body are present. </p>
<p> The meeting time and place of the Decentral Assembly must be announced at least seven days in advance of the meeting on the Decentrala's forum. </p>
<p> The voting body's session should be held at least once every two months. </p>
</div>
+4 -17
View File
@@ -1,23 +1,10 @@
<h1>O nama</h1>
<dl>
<dt>Statut:</dt>
<dd>
Sve odluke se donose po principu direktne demokratije. Nas statut mozete
pogledati na <a href="/statute">stranici za statut</a>.
</dd>
<dd> Sve odluke se donose po principu direktne demokratije. Nas statut mozete pogledati na <a href="/statute">stranici za statut</a>. </dd>
<dt>Kontakt:</dt>
<dd>
Možeš nam poslati mejl na adresu
<a href="mailto:dmz@dmz.rs">dmz@dmz.rs</a> ili se možeš pridružiti našem
<a href="https://forum.dmz.rs">Forumu</a>.
</dd>
<dd>
Takođe smo dostupni i na
<a href="https://balkan.fedive.rs/@decentrala">Fediversu!</a>
</dd>
<dd>
U slučaju da pronađeš <em>bug</em> na sajtu, bili bismo ti jako zahvalni ako
nam ga prijaviš.
</dd>
<dd>Možeš nam poslati mejl na adresu <a href="mailto:dmz@dmz.rs">dmz@dmz.rs</a> ili se možeš pridružiti našem <a href="https://forum.dmz.rs">Forumu</a>.</dd>
<dd>Takođe smo dostupni i na <a href="https://balkan.fedive.rs/@decentrala">Fediversu!</a></dd>
<dd>U slučaju da pronađeš <em>bug</em> na sajtu, bili bismo ti jako zahvalni ako nam ga prijaviš.</dd>
</dl>
+14 -68
View File
@@ -1,89 +1,35 @@
<h1>Dekonferencija</h1>
<h2 id="program"><a href="#program">Program</a></h2>
<p>11:00 Otvaranje</p>
<p>
12:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p>
14:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a>
</p>
<p>
16:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks"
>Lightning talks</a
>
</p>
<p>18:00 Diskusije</p>
<p>
20:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p>22:00 Kraj</p>
<p>11:00 Otvaranje<p>
<p>12:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>14:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a><p>
<p>16:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks">Lightning talks</a><p>
<p>18:00 Diskusije<p>
<p>20:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>22:00 Kraj<p>
<h2 id="what"><a href="#what">Šta?</a></h2>
<p>
Dekonferencija je prva konferencija organizovana od strane
<a href="https://dmz.rs">Decentrale</a>, Beogradskog hakerspejsa.
Dekonferencija služi kao platforma za predstavljanje i diskusiju ideja
decentralizacije u svim svojim oblicima.
</p>
<p>Dekonferencija je prva konferencija organizovana od strane <a href="https://dmz.rs">Decentrale</a>, Beogradskog hakerspejsa. Dekonferencija služi kao platforma za predstavljanje i diskusiju ideja decentralizacije u svim svojim oblicima.</p>
<h2 id="when-and-where"><a href="#when-and-where">Kad & Gde?</a></h2>
<p>
Dekonferencija će se održati u nedelju, 15.-og Septembra, 2024, u Kulturnom
Centru Magacin, na adresi
<a href="https://osm.org/go/xf3Fz31te?node=1226456745"
>Kraljevića Marka 4-8, Beograd</a
>. Veče pre, održaće se druženje povodom organizovanja konferencije u
prostorijama <a href="https://dckrov.rs/">Društvenog Centra Krov</a>, na
adresi <a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Beograd</a>.
</p>
<p>Dekonferencija će se održati u nedelju, 15.-og Septembra, 2024, u Kulturnom Centru Magacin, na adresi <a href="https://osm.org/go/xf3Fz31te?node=1226456745">Kraljevića Marka 4-8, Beograd</a>. Veče pre, održaće se druženje povodom organizovanja konferencije u prostorijama <a href="https://dckrov.rs/">Društvenog Centra Krov</a>, na adresi <a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Beograd</a>.</p>
<h2 id="why"><a href="#why">Zašto?</a></h2>
<p>
Decentrala je osnovana od strane male grupe entuzijasta udružene oko ideje
decentralizacije tehnologije. Poslednjih godinu i po, organizovali smo više od
160 događaja—predavanja, radionica, diskusija, hakatona—sa ciljem
demokratizacije tehnološkog znanja i edukacije o privatnosti, open source
principa, prava na popravku (i kako popraviti), digitalna svojina, i pravo
korišćenja. Od prvog dana, naš pristup je bio da informišemo pojedince o
alternativama umesto da im namećemo naše mišljenje.
</p>
<p>Decentrala je osnovana od strane male grupe entuzijasta udružene oko ideje decentralizacije tehnologije. Poslednjih godinu i po, organizovali smo više od 160 događaja—predavanja, radionica, diskusija, hakatona—sa ciljem demokratizacije tehnološkog znanja i edukacije o privatnosti, open source principa, prava na popravku (i kako popraviti), digitalna svojina, i pravo korišćenja. Od prvog dana, naš pristup je bio da informišemo pojedince o alternativama umesto da im namećemo naše mišljenje.</p>
<p>
Vremenom, angažovanjem sa raznovrsnim posetiocima, od kojih su mnogi iz
ne-tehničkih sfera, shvatili smo da decentralizacija obuhvata više od samo
"otvorene tehnologije." Mnogi aktivisti i organizacije se danas zalažu za
različite oblike decentralizacije. Zato, smatramo da su dobrodošle priče
decentralizacije iz različitih perspektiva.
</p>
<p>Vremenom, angažovanjem sa raznovrsnim posetiocima, od kojih su mnogi iz ne-tehničkih sfera, shvatili smo da decentralizacija obuhvata više od samo "otvorene tehnologije." Mnogi aktivisti i organizacije se danas zalažu za različite oblike decentralizacije. Zato, smatramo da su dobrodošle priče decentralizacije iz različitih perspektiva.</p>
<h2 id="who"><a href="#who">Ko?</a></h2>
<p>
Dekonferencija je otvorena platforma za sve zainteresovane za diskusiju,
demonstraciju, ili istraživanje decentralizacije. Možete registrovati vaš
događaj slanjem email-a na
<a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> do dana
Dekonferencije (15.-ti Septembar).
</p>
<p>Dekonferencija je otvorena platforma za sve zainteresovane za diskusiju, demonstraciju, ili istraživanje decentralizacije. Možete registrovati vaš događaj slanjem email-a na <a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> do dana Dekonferencije (15.-ti Septembar).</p>
<p>Osvežićemo ovaj deo kako se teme događaja potvrde.</p>
<h2 id="how"><a href="#how">Kako?</a></h2>
<p>
Dekonferencija je finansirana od strane ličnih sredstava organizatora. Kao i
sve aktivnosti Decentrale, Dekonferencija je besplatna svima. Nažalost, nismo
u stanju da pružimo subvencije predavačima.
</p>
<p>Dekonferencija je finansirana od strane ličnih sredstava organizatora. Kao i sve aktivnosti Decentrale, Dekonferencija je besplatna svima. Nažalost, nismo u stanju da pružimo subvencije predavačima.</p>
<p>Decentrala prihvata donacije isključivo od fizičkih lica.</p>
+14 -54
View File
@@ -1,67 +1,27 @@
<h1>Dobrodošli!</h1>
<p>
Mi smo <em>Decentrala</em> - grupa entuzijasta okupljena oko ideja
decentralizacije i slobodnog širenja znanja. Zvuči interesantno? Evo još nekih
stvari o nama:
Mi smo <em>Decentrala</em> - grupa entuzijasta okupljena oko ideja decentralizacije i slobodnog širenja znanja.
Zvuči interesantno? Evo još nekih stvari o nama:
</p>
<dl>
<dt>Motivacija:</dt>
<dd>
Decentralizacijom postizemo
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#odrzivost"
>odrzivost</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#dostupnost"
>dostupnost</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#pristupacnost"
>pristupacnost</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#nezavisnost"
>nezavisnost</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#privatnost"
>privatnost</a
>
i
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#sloboda"
>slobodu</a
>. Na ovim mrezama ima manje
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#manipulacija"
>manipulacije</a
>,
<a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#propaganda"
>propagande</a
>, reklama, i
<a
href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#neopterecenost-paznje-sporednim-stvarima"
>nisu dizajnirane za zadrzavanje paznje (zaglupljivanje)</a
>.
<a href="https://forum.dmz.rs/t/zasto-nam-je-decentralizacija-bitna/506/1"
>Recite zasto je vama decentralizacija bitna</a
>
<dd>Decentralizacijom postizemo <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#odrzivost">odrzivost</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#dostupnost">dostupnost</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#pristupacnost">pristupacnost</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#nezavisnost">nezavisnost</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#privatnost">privatnost</a> i <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#sloboda">slobodu</a>. Na ovim mrezama ima manje <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#manipulacija">manipulacije</a>, <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#propaganda">propagande</a>, reklama, i <a href="https://wiki.dmz.rs/en/zastojedecentralizacijabitna#neopterecenost-paznje-sporednim-stvarima">nisu dizajnirane za zadrzavanje paznje (zaglupljivanje)</a>.
<a href="https://forum.dmz.rs/t/zasto-nam-je-decentralizacija-bitna/506/1">Recite zasto je vama decentralizacija bitna</a>
</dd>
<dt>Znanje:</dt>
<dd>
Sve naše radionice su besplatne i otvorene za sve zainteresovane. Ako želiš
nešto da podeliš najavi se na našem
<a href="https://forum.dmz.rs">Forumu</a> i održi radionicu kod nas!
<dd>Sve naše radionice su besplatne i otvorene za sve zainteresovane.
Ako želiš nešto da podeliš najavi se na našem <a href="https://forum.dmz.rs">Forumu</a> i održi radionicu kod nas!
</dd>
<dt>Akcije:</dt>
<dd>
Povremeno organizujemo različite akcije, hakatone, crypto-partije, izložbe i
slične događaje otvorene za sve zainteresovane.
</dd>
<dd>Povremeno organizujemo različite akcije, hakatone, crypto-partije, izložbe i slične događaje otvorene za sve
zainteresovane. </dd>
<dt>Servisi:</dt>
<dd>
Na našim serverima pokrećemo razne servise (email, git, wiki i druge) koji
su otvoreni za sve i koji se mogu koristiti sa ili bez našeg naloga.
</dd>
<dd>Na našim serverima pokrećemo razne servise (email, git, wiki i druge) koji su otvoreni za sve i koji se mogu
koristiti sa ili bez našeg naloga.</dd>
</dl>
<p>
Ako si i dalje zainteresovan, možeš napraviti <a href="/account">nalog</a> na
našem serveru koji će ti omogućiti korišćenje svih naših
<a href="/services">servisa</a>. Ako želiš prvo da vidiš kako to sve izgleda u
realnosti, možeš doći na neki od naših <a href="/events">događaja</a>, i tu
nas upoznati!
Ako si i dalje zainteresovan, možeš napraviti <a href="/account">nalog</a> na našem serveru koji će ti
omogućiti korišćenje svih naših <a href="/services">servisa</a>.
Ako želiš prvo da vidiš kako to sve izgleda u realnosti, možeš doći na neki od naših <a
href="/events">događaja</a>, i tu nas upoznati!
</p>
+1 -2
View File
@@ -46,8 +46,7 @@
<tr>
<td><a href="https://jitsi.dmz.rs/">Jitsi</a></td>
<td>
<a href="https://jitsi.org/">Jitsi.org</a> aplikacija za sastanke, groupne
video pozive, online dogadjaje, alternativa za zoom.
<a href="https://jitsi.org/">Jitsi.org</a> aplikacija za sastanke, groupne video pozive, online dogadjaje, alternativa za zoom.
</td>
</tr>
<!--<tr>
+1 -1
View File
@@ -24,7 +24,7 @@
Jednostavno koriscenje naseg softwera se takodje racuna kao doprinos, posto
bi se time pridruzili decentralizaciji.
</p>
<p>Takođe primamo donacije u bitcoinu na adresi:</p>
<p>Takođe primamo donacije u bitcoin na adresi:</p>
<ul>
<li>Bitcoin: <i>bc1qjhsfgq79wuzzv32yml9zglwzf9qcwfj3atuy74</i></li>
<!--
+116 -174
View File
@@ -1,7 +1,7 @@
from jinja2 import Environment, FileSystemLoader
#! /usr/bin/env python3
import csv
from datetime import datetime
import os
DAYS_SR = ["PON", "UTO", "SRE", "ČET", "PET", "SUB", "NED"]
DAYS_EN = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
@@ -25,8 +25,6 @@ TYPES_DICT = {
"party": ("zabava", "entertainment"),
}
env = Environment(loader=FileSystemLoader("template"))
def load_events(csv_path: str) -> list[dict]:
events = []
@@ -52,11 +50,64 @@ def load_events(csv_path: str) -> list[dict]:
return events
def build_html(events: list[dict], dayNames: list[str], typesNames: dict) -> str:
events_html = []
for event in events:
title = event["title"]
location = event["location"]
date = event["date"]
date = (
dayNames[date.weekday()]
+ ", "
+ str(date.day)
+ ". "
+ str(date.month)
+ ". "
+ str(date.year)
+ ", "
)
time = event["time"] + "h"
event_html = []
event_html.append(f"<div class='date'>{date} {time}</div>")
if event["link"] != "":
event_html.append(
f"<div class='title'><a href=\"{event['link']}\">{title}</a></div>"
)
else:
event_html.append(f"<div class='title'>{title}</div>")
if "https://" in location:
place, link = location.split("https://")
event_html.append(
f"<div class='place'><a href=\"https://{link}\" target='_blank'>@{place.strip()}</a></div>"
)
else:
event_html.append(f"<div class='place'>@{location.strip()}</div>")
if len(event["types"]) != 0:
types_list = "<div class='types'>"
last_item = event["types"][-1]
for t in event["types"]:
if typesNames.get(t) is not None:
types_list += typesNames.get(t)
if t != last_item:
types_list += ", "
else:
print(f"Unknown type {t}!")
types_list += "</div>"
event_html.append(types_list)
event_html = "".join(event_html)
events_html.append(f"\n<div class='event'>{event_html}</div>")
return events_html
def build_ical(events: list[dict]) -> str:
today = datetime.today().now()
# Header
events_ical = ""
with open("template/head.ical", "r") as file:
events_ical += file.read()
# Events
for event in events:
title = event["title"]
location = event["location"]
@@ -65,7 +116,7 @@ def build_ical(events: list[dict]) -> str:
url = event["link"]
uid = str(date.month).zfill(2) + str(date.day).zfill(2) + time[:2]
date_str = str(date.year) + str(date.month).zfill(2) + str(date.day).zfill(2)
date = str(date.year) + str(date.month).zfill(2) + str(date.day).zfill(2)
created = (
str(today.year)
+ str(today.month).zfill(2)
@@ -76,190 +127,81 @@ def build_ical(events: list[dict]) -> str:
+ str(today.second).zfill(2)
+ "Z"
)
date_str = date_str + "T" + time.replace(":", "") + "00"
date = date + "T" + time.replace(":", "") + "00"
event_template_str = env.get_template("event.ical").render(
UID=uid,
CREATED=created,
DATE=date_str,
TITLE=title,
URL=url,
LOCATION=(
"DC Krov\\, Kraljice Marije 47\\, 6\\, Beograd\\, Serbia"
if location.startswith("DC Krov")
else (
"Matematički fakultet\\, Svetog Nikole 39\\, Beograd\\, Serbia"
if location.startswith("Matematički fakultet (Učionica 153)")
else location
)
),
)
events_ical += event_template_str
event_template = ""
with open("template/event.ical", "r") as file:
event_template += file.read()
event_template = event_template.replace("<!--UID-->", uid)
event_template = event_template.replace("<!--CREATED-->", created)
event_template = event_template.replace("<!--DATE-->", date)
event_template = event_template.replace("<!--TITLE-->", title)
event_template = event_template.replace("<!--URL-->", url)
ical_location = location
for prefix, address in ICAL_LOCATION_ADDRESSES.items():
if location.startswith(prefix):
ical_location = address
break
event_template = event_template.replace("<!--LOCATION-->", ical_location)
events_ical += event_template
# Footer
with open("template/end.ical", "r") as file:
events_ical += file.read()
return events_ical
def render_page(template_name, output_path, context):
template = env.get_template(template_name)
with open(output_path, "w") as file:
file.write(template.render(context))
# Main execution
events = sorted(load_events("dogadjaji.csv"), key=lambda e: e["date"])
today = datetime.today().date()
past_events = sorted(
[e for e in events if e["date"] <= today], key=lambda e: e["date"], reverse=True
)
new_events = [e for e in events if e["date"] >= today]
past_events = list(filter(lambda e: e["date"] <= today, events))
past_events.reverse()
new_events = list(filter(lambda e: e["date"] >= today, events))
sr_types = {k: v[0] for k, v in TYPES_DICT.items()}
en_types = {k: v[1] for k, v in TYPES_DICT.items()}
# Build Serbian Pages
render_page(
"events-sr.html",
"pages/sr/events.html",
{
"lang": "sr",
"title": "Događaji",
"sr_link": "/events_archive",
"events_html": env.from_string("""
{% for event in events %}
<div class='event'>
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
{% if event.link %}
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
{% else %}
<div class='title'>{{ event.title }}</div>
{% endif %}
{% if 'https://' in event.location %}
{% set place, link = event.location.split('https://') %}
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
{% else %}
<div class='place'>@{{ event.location.strip() }}</div>
{% endif %}
{% if event.types %}
<div class='types'>
{% for t in event.types %}
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
""").render(events=new_events, types_names=sr_types),
},
)
page_template = ""
render_page(
"events-en.html",
"pages/en/events.html",
{
"lang": "en",
"title": "Events",
"sr_link": "/events_archive",
"events_html": env.from_string("""
{% for event in events %}
<div class='event'>
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
{% if event.link %}
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
{% else %}
<div class='title'>{{ event.title }}</div>
{% endif %}
{% if 'https://' in event.location %}
{% set place, link = event.location.split('https://') %}
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
{% else %}
<div class='place'>@{{ event.location.strip() }}</div>
{% endif %}
{% if event.types %}
<div class='types'>
{% for t in event.types %}
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
""").render(events=new_events, types_names=en_types),
},
)
sr_types = {}
en_types = {}
# Build Archive Pages
render_page(
"events_archive-sr.html",
"pages/sr/events_archive.html",
{
"lang": "sr",
"title": "Arhiva događaja",
"sr_link": "/events",
"events_html": env.from_string("""
{% for event in events %}
<div class='event'>
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
{% if event.link %}
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
{% else %}
<div class='title'>{{ event.title }}</div>
{% endif %}
{% if 'https://' in event.location %}
{% set place, link = event.location.split('https://') %}
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
{% else %}
<div class='place'>@{{ event.location.strip() }}</div>
{% endif %}
{% if event.types %}
<div class='types'>
{% for t in event.types %}
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
""").render(events=past_events, types_names=sr_types),
},
)
for key, value_pair in TYPES_DICT.items():
sr_types[key] = value_pair[0]
en_types[key] = value_pair[1]
render_page(
"events_archive-en.html",
"pages/en/events_archive.html",
{
"lang": "en",
"title": "Events archive",
"sr_link": "/en/events",
"events_html": env.from_string("""
{% for event in events %}
<div class='event'>
<div class='date'>{{ event.date.strftime('%a, %d. %b. %Y') }}, {{ event.time }}h</div>
{% if event.link %}
<div class='title'><a href="{{ event.link }}">{{ event.title }}</a></div>
{% else %}
<div class='title'>{{ event.title }}</div>
{% endif %}
{% if 'https://' in event.location %}
{% set place, link = event.location.split('https://') %}
<div class='place'><a href="https://{{ link }}" target='_blank'>@{{ place.strip() }}</a></div>
{% else %}
<div class='place'>@{{ event.location.strip() }}</div>
{% endif %}
{% if event.types %}
<div class='types'>
{% for t in event.types %}
{{ types_names.get(t, t) }}{% if not loop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
""").render(events=past_events, types_names=en_types),
},
)
# Build Serbian Events page
new_events_html = build_html(new_events, DAYS_SR, sr_types)
with open("template/events-sr.html", "r") as file:
page_template = [line for line in file]
with open("pages/sr/events.html", "w") as file:
file.writelines(page_template + new_events_html)
# Build English Events page
new_events_html = build_html(new_events, DAYS_EN, en_types)
with open("template/events-en.html", "r") as file:
page_template = [line for line in file]
with open("pages/en/events.html", "w") as file:
file.writelines(page_template + new_events_html)
# Build Serbian Archive page
past_events_html = build_html(past_events, DAYS_SR, sr_types)
with open("template/events_archive-sr.html", "r") as file:
page_template = [line for line in file]
with open("pages/sr/events_archive.html", "w") as file:
file.writelines(page_template + past_events_html)
# Build English Archive page
past_events_html = build_html(past_events, DAYS_EN, en_types)
with open("template/events_archive-en.html", "r") as file:
page_template = [line for line in file]
with open("pages/en/events_archive.html", "w") as file:
file.writelines(page_template + past_events_html)
new_events_ical = build_ical(new_events)
# Build ical
with open("site/events.ical", "w") as file:
-8
View File
@@ -1,8 +0,0 @@
[tool.black]
line-length = 88
target-version = ['py312']
[tool.flake8]
max-line-length = 88
extend-ignore = "E203"
exclude = ".venv"
+3 -6
View File
@@ -1,9 +1,6 @@
cairosvg
black
feedgen
flake8
freetype-py
jinja2
markdown
pillow
freetype-py
python-dateutil
feedgen
pillow
-1
View File
@@ -6,7 +6,6 @@
<link rel="stylesheet" href="/styles/style.css">
<link rel="stylesheet" href="/styles/404.css">
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon">
<script src="/scripts/main.js" defer></script>
<title>404</title>
</head>
<body>
+31 -94
View File
@@ -1,7 +1,11 @@
<!doctype html>
<html lang="sr">
<head>
<!--
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <pre>
*@@*
*@@@@*
*@@*
@@ -21,144 +25,77 @@
| | | | _|| | | _| | \| | | | | |_) | / _ \ | | / _ \
| |_| | |__| |___| |___| |\ | | | | _ < / ___ \| |___ / ___ \
|____/|_____\____|_____|_| \_| |_| |_| \_\/_/ \_\_____/_/ \_\
-->
<script>
(function () {
const theme = localStorage.getItem("theme");
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
if (theme === "dark" || (!theme && prefersDark))
document.documentElement.classList.add("dark");
})();
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</pre> -->
<link rel="stylesheet" href="/styles/reset.css" />
<link rel="stylesheet" href="/styles/style.css" />
<link rel="stylesheet" href="/styles/deconference.css">
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="/scripts/main.js"></script>
<title>Dekonferencija Decentrala</title>
<link rel="alternate" hreflang="sr" href="/en/deconference" />
<link rel="alternate" hreflang="en" href="/en/deconference" />
</head>
<body>
<input type="checkbox" id="menu-toggle" />
<input type="checkbox" id="theme-toggle" />
<header>
<a id="logo" href="/">
<img src="/img/logo-light.svg" alt="Logo" /> Decentrala
<img src="/img/logo-light.svg" alt="Logo" />
Decentrala
</a>
<button id="theme-switcher"></button>
<label for="theme-toggle" id="theme-switcher"></label>
<a class="lang" hreflang="en" href="/en/deconference">EN</a>
</header>
<main>
<div class="page-wrap">
<div class="page-wrap">
<div class='cover-wrap'><img src='/img/students_bug.jpg' alt='Studenti su nasli bug' /></div><h1>Dekonferencija</h1>
<h2 id="program"><a href="#program">Program</a></h2>
<p>11:00 Otvaranje</p>
<p>
12:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p>
14:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a>
</p>
<p>
16:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks"
>Lightning talks</a
>
</p>
<p>18:00 Diskusije</p>
<p>
20:00
<a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty"
>Cryptoparty</a
>
</p>
<p>22:00 Kraj</p>
<p>11:00 Otvaranje<p>
<p>12:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>14:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/hakaton">Hakaton</a><p>
<p>16:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/lightningtalks">Lightning talks</a><p>
<p>18:00 Diskusije<p>
<p>20:00 <a href="https://wiki.dmz.rs/en/decentrala/dogadjaji/cryptoparty">Cryptoparty</a><p>
<p>22:00 Kraj<p>
<h2 id="what"><a href="#what">Šta?</a></h2>
<p>
Dekonferencija je prva konferencija organizovana od strane
<a href="https://dmz.rs">Decentrale</a>, Beogradskog hakerspejsa.
Dekonferencija služi kao platforma za predstavljanje i diskusiju ideja
decentralizacije u svim svojim oblicima.
</p>
<p>Dekonferencija je prva konferencija organizovana od strane <a href="https://dmz.rs">Decentrale</a>, Beogradskog hakerspejsa. Dekonferencija služi kao platforma za predstavljanje i diskusiju ideja decentralizacije u svim svojim oblicima.</p>
<h2 id="when-and-where"><a href="#when-and-where">Kad & Gde?</a></h2>
<p>
Dekonferencija će se održati u nedelju, 15.-og Septembra, 2024, u Kulturnom
Centru Magacin, na adresi
<a href="https://osm.org/go/xf3Fz31te?node=1226456745"
>Kraljevića Marka 4-8, Beograd</a
>. Veče pre, održaće se druženje povodom organizovanja konferencije u
prostorijama <a href="https://dckrov.rs/">Društvenog Centra Krov</a>, na
adresi <a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Beograd</a>.
</p>
<p>Dekonferencija će se održati u nedelju, 15.-og Septembra, 2024, u Kulturnom Centru Magacin, na adresi <a href="https://osm.org/go/xf3Fz31te?node=1226456745">Kraljevića Marka 4-8, Beograd</a>. Veče pre, održaće se druženje povodom organizovanja konferencije u prostorijama <a href="https://dckrov.rs/">Društvenog Centra Krov</a>, na adresi <a href="https://osm.org/go/xf3HQQdIH">Kraljice Marije 47, Beograd</a>.</p>
<h2 id="why"><a href="#why">Zašto?</a></h2>
<p>
Decentrala je osnovana od strane male grupe entuzijasta udružene oko ideje
decentralizacije tehnologije. Poslednjih godinu i po, organizovali smo više od
160 događaja—predavanja, radionica, diskusija, hakatona—sa ciljem
demokratizacije tehnološkog znanja i edukacije o privatnosti, open source
principa, prava na popravku (i kako popraviti), digitalna svojina, i pravo
korišćenja. Od prvog dana, naš pristup je bio da informišemo pojedince o
alternativama umesto da im namećemo naše mišljenje.
</p>
<p>Decentrala je osnovana od strane male grupe entuzijasta udružene oko ideje decentralizacije tehnologije. Poslednjih godinu i po, organizovali smo više od 160 događaja—predavanja, radionica, diskusija, hakatona—sa ciljem demokratizacije tehnološkog znanja i edukacije o privatnosti, open source principa, prava na popravku (i kako popraviti), digitalna svojina, i pravo korišćenja. Od prvog dana, naš pristup je bio da informišemo pojedince o alternativama umesto da im namećemo naše mišljenje.</p>
<p>
Vremenom, angažovanjem sa raznovrsnim posetiocima, od kojih su mnogi iz
ne-tehničkih sfera, shvatili smo da decentralizacija obuhvata više od samo
"otvorene tehnologije." Mnogi aktivisti i organizacije se danas zalažu za
različite oblike decentralizacije. Zato, smatramo da su dobrodošle priče
decentralizacije iz različitih perspektiva.
</p>
<p>Vremenom, angažovanjem sa raznovrsnim posetiocima, od kojih su mnogi iz ne-tehničkih sfera, shvatili smo da decentralizacija obuhvata više od samo "otvorene tehnologije." Mnogi aktivisti i organizacije se danas zalažu za različite oblike decentralizacije. Zato, smatramo da su dobrodošle priče decentralizacije iz različitih perspektiva.</p>
<h2 id="who"><a href="#who">Ko?</a></h2>
<p>
Dekonferencija je otvorena platforma za sve zainteresovane za diskusiju,
demonstraciju, ili istraživanje decentralizacije. Možete registrovati vaš
događaj slanjem email-a na
<a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> do dana
Dekonferencije (15.-ti Septembar).
</p>
<p>Dekonferencija je otvorena platforma za sve zainteresovane za diskusiju, demonstraciju, ili istraživanje decentralizacije. Možete registrovati vaš događaj slanjem email-a na <a href="mailto:dekonferencija@dmz.rs">dekonferencija@dmz.rs</a> do dana Dekonferencije (15.-ti Septembar).</p>
<p>Osvežićemo ovaj deo kako se teme događaja potvrde.</p>
<h2 id="how"><a href="#how">Kako?</a></h2>
<p>
Dekonferencija je finansirana od strane ličnih sredstava organizatora. Kao i
sve aktivnosti Decentrale, Dekonferencija je besplatna svima. Nažalost, nismo
u stanju da pružimo subvencije predavačima.
</p>
<p>Dekonferencija je finansirana od strane ličnih sredstava organizatora. Kao i sve aktivnosti Decentrale, Dekonferencija je besplatna svima. Nažalost, nismo u stanju da pružimo subvencije predavačima.</p>
<p>Decentrala prihvata donacije isključivo od fizičkih lica.</p>
</div>
</div>
</main>
<footer>
<button class="hamburger closed">
<label for="menu-toggle" class="hamburger">
<img src="/img/strelica-closed-light.svg" alt="Menu" />
</button>
</label>
<nav class="menu">
<a href="/events">Događaji</a>
<a href="/services">Servisi</a>
<a href="/statute">Statut</a>
<a href="/about">O nama</a>
<a href="/account">Nalog</a>
<a class="account" href="/account">Nalog</a>
<a href="/support">Podrška</a>
</nav>
<span class="links">
-85
View File
@@ -1,85 +0,0 @@
window.addEventListener("DOMContentLoaded", () => {
const getById = (id) => document.getElementById(id);
const getByClass = (className) => document.getElementsByClassName(className)[0];
const themeBtn = getById("theme-switcher");
const hamburger = getByClass("hamburger");
const hamburgerIcon = hamburger.children[0]
const menu = document.getElementsByTagName("nav")[0];
const imgs = document.getElementsByTagName("img");
const main = document.getElementsByTagName("main")[0];
const isMenuOpen = () => hamburger.classList.contains("open");
const theme = window.localStorage.getItem("theme");
/* Functions */
const changeToDarkTheme = () => {
window.localStorage.setItem("theme", "dark");
document.documentElement.classList.add("dark");
themeBtn?.setAttribute("title", "turn the light on");
Array.from(imgs).forEach((img) => {
if (img.src.includes("-light")) img.src = img.src.replace("-light", "-dark");
});
}
const changeToLightTheme = () => {
window.localStorage.setItem("theme", "light");
document.documentElement.classList.remove("dark");
themeBtn?.setAttribute("title", "turn the light off");
Array.from(imgs).forEach((img) => {
if (img.src.includes("-dark")) img.src = img.src.replace("-dark", "-light");
});
}
const closeMenu = () => {
hamburger.classList = "hamburger closed"
hamburgerIcon.src = hamburgerIcon.src.replace("opened", "closed");
menu.classList = "menu closed";
}
const openMenu = () => {
hamburger.classList = "hamburger open"
hamburgerIcon.src = hamburgerIcon.src.replace("closed", "opened");
menu.classList = "menu open";
}
/* Listeners */
window.addEventListener("resize", () => isMenuOpen() && closeMenu());
main.addEventListener("click", () => isMenuOpen() && closeMenu());
/* Language persistence */
const currentLang = document.documentElement.lang || "sr";
const anchors = document.getElementsByTagName("a");
Array.from(anchors).forEach((a) => {
// Skip language switcher links
if (a.classList.contains("lang")) return;
const href = a.getAttribute("href");
if (!href) return;
if (href.startsWith("/")) {
// Replace existing language prefix or add one
if (href.startsWith("/sr") || href.startsWith("/en")) {
if (!href.startsWith(`/${currentLang}`)) {
a.setAttribute("href", `/${currentLang}${href.slice(3)}`);
}
} else {
// No language prefix, prepend currentLang
a.setAttribute("href", `/${currentLang}${href}`);
}
}
});
hamburger?.addEventListener("click", () => isMenuOpen() ? closeMenu() : openMenu());
themeBtn.addEventListener("click", () => {
const title = themeBtn.getAttribute("title") ?? "off"
if (title.indexOf("off") !== -1) changeToDarkTheme();
else changeToLightTheme();
});
/* Rest */
const userPerfersDark = window?.matchMedia?.("(prefers-color-scheme: dark)").matches
if (!theme && userPerfersDark) changeToDarkTheme();
else theme === "light" ? changeToLightTheme() : changeToDarkTheme();
})
+90 -1
View File
@@ -11,12 +11,39 @@
--bg: var(--light-bg);
}
html.dark {
/* Theme toggle via checkbox hack */
#theme-toggle {
display: none;
}
/* Use :has() selector to detect checkbox state */
body:has(#theme-toggle:checked) {
--border: var(--dark-border);
--text: var(--dark-text);
--bg: var(--dark-bg);
}
body:has(#theme-toggle:checked) header #theme-switcher {
background: linear-gradient(
90deg,
var(--dark-border) 0%,
var(--dark-border) 50%,
var(--dark-bg) 51%,
var(--dark-bg) 100%
);
}
body:has(#theme-toggle:checked) header #theme-switcher:hover {
border-color: var(--hightlight);
background: linear-gradient(
90deg,
var(--hightlight) 0%,
var(--hightlight) 50%,
var(--dark-bg) 51%,
var(--dark-bg) 100%
);
}
@font-face {
font-family: "Iosevka";
src: url("/font/iosevka-regular.woff") format("woff");
@@ -123,6 +150,7 @@ a:visited {
var(--bg) 51%,
var(--bg) 100%
);
cursor: pointer;
}
#theme-switcher:hover {
@@ -136,6 +164,27 @@ a:visited {
);
}
#theme-toggle:checked ~ body header #theme-switcher {
background: linear-gradient(
90deg,
var(--dark-border) 0%,
var(--dark-border) 50%,
var(--dark-bg) 51%,
var(--dark-bg) 100%
);
}
#theme-toggle:checked ~ body header #theme-switcher:hover {
border-color: var(--hightlight);
background: linear-gradient(
90deg,
var(--hightlight) 0%,
var(--hightlight) 50%,
var(--dark-bg) 51%,
var(--dark-bg) 100%
);
}
.lang {
font-size: 2rem;
}
@@ -212,6 +261,46 @@ button {
.hamburger {
display: block !important;
cursor: pointer;
}
#menu-toggle {
display: none;
}
#menu-toggle:checked ~ footer .menu {
display: flex;
flex-direction: column;
}
#menu-toggle:checked ~ footer .hamburger {
position: relative;
}
#menu-toggle:checked ~ footer .hamburger::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("/img/strelica-opened-light.svg");
background-repeat: no-repeat;
background-size: contain;
}
/* Show hamburger icon on mobile */
.hamburger {
cursor: pointer;
}
.hamburger img {
width: 1.5rem;
height: 1.5rem;
}
#menu-toggle:checked ~ footer .hamburger img {
opacity: 0;
}
}
-87
View File
@@ -1,87 +0,0 @@
<!doctype html>
<html lang="{{ lang }}">
<head>
<!--
*@@*
*@@@@*
*@@*
||
||
*@@* *@@* *@@*
*@@@@*===*@@@@*===*@@@@*
*@@* *@@* *@@*
|| //
|| //
*@@*//
*@@@@*
*@@*
____ _____ ____ _____ _ _ _____ ____ _ _ _
| _ \| ____/ ___| ____| \ | |_ _| _ \ / \ | | / \
| | | | _|| | | _| | \| | | | | |_) | / _ \ | | / _ \
| |_| | |__| |___| |___| |\ | | | | _ < / ___ \| |___ / ___ \
|____/|_____\____|_____|_| \_| |_| |_| \_\/_/ \_\_____/_/ \_\
-->
<script>
(function () {
const theme = localStorage.getItem("theme");
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
if (theme === "dark" || (!theme && prefersDark))
document.documentElement.classList.add("dark");
})();
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/styles/reset.css" />
<link rel="stylesheet" href="/styles/style.css" />
{% block extra_styles %}{% endblock %}
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon" />
<script src="/scripts/main.js"></script>
<title>{{ title }} Decentrala</title>
<link rel="alternate" hreflang="sr" href="{{ sr_link }}" />
</head>
<body>
<header>
<a id="logo" href="/">
<img src="/img/logo-{{ 'dark' if is_dark else 'light' }}.svg" alt="Logo" /> Decentrala
</a>
<button id="theme-switcher"></button>
<a class="lang" hreflang="{{ 'sr' if lang == 'en' else 'en' }}" href="{{ current_path.replace('/en/', '/') if lang == 'en' else ('/en' + current_path if not current_path.startswith('/en/') else current_path) }}">{{ 'SR' if lang == 'en' else 'EN' }}</a>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<button class="hamburger closed">
<img src="/img/strelica-closed-{{ 'dark' if is_dark else 'light' }}.svg" alt="Menu" />
</button>
<nav class="menu">
{% set base_path = '/en/' if lang == 'en' else '/' %}
<a href="{{ base_path }}events">{{ 'Događaji' if lang == 'sr' else 'Events' }}</a>
<a href="{{ base_path }}services">{{ 'Servisi' if lang == 'sr' else 'Services' }}</a>
<a href="{{ base_path }}statute">{{ 'Statut' if lang == 'sr' else 'Statute' }}</a>
<a href="{{ base_path }}about">{{ 'O nama' if lang == 'sr' else 'About us' }}</a>
<a href="{{ base_path }}account">{{ 'Nalog' if lang == 'sr' else 'Account' }}</a>
<a href="{{ base_path }}support">{{ 'Podrška' if lang == 'sr' else 'Support' }}</a>
</nav>
<span class="links">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
<img src="/img/cc-{{ 'dark' if is_dark else 'light' }}.svg" alt="CreativeCommons" />
</a>
<a href="{{ base_path }}webring">
<img src="/img/w-{{ 'dark' if is_dark else 'light' }}.svg" alt="Webring" />
</a>
<a href="https://gitea.dmz.rs/Decentrala/website">
<img src="/img/git-{{ 'dark' if is_dark else 'light' }}.svg" alt="SourceCode" />
</a>
<a href="https://balkan.fedive.rs/@decentrala">
<img src="/img/mastodon-{{ 'dark' if is_dark else 'light' }}.svg" alt="Mastodon" />
</a>
</span>
</footer>
</body>
</html>
+4 -8
View File
@@ -1,22 +1,18 @@
{% block content %}
<h1>Events</h1>
<div class="description">
<p>
Following list contains all forthcoming events. Held events are listed in
<a href="/{{ lang }}/events_archive">archive</a>.
<a href="/en/events_archive">archive</a>.
</p>
<p>
Events are also available as an
<a href="https://dmz.rs/events.ical">ical</a> file.
</p>
<p>
<a href="https://wiki.dmz.rs/en/kako-pronaci-prostor" target="_blank">Short description</a>
<a href="https://wiki.dmz.rs/en/kako-pronaci-prostor" target="_blank">
Short description
</a>
how to find a space
</p>
</div>
<div class="events-list">
{{ events_html|safe }}
</div>
{% endblock %}
+4 -8
View File
@@ -1,22 +1,18 @@
{% block content %}
<h1>Događaji</h1>
<div class="description">
<p>
Naredna lista sadrži sve predstojeće događaje. Za listu održanih događaja
pogledaj <a href="/{{ lang }}/events_archive">arhivu</a>.
pogledaj <a href="/events_archive">arhivu</a>.
</p>
<p>
Događaje možeš učitati i sa
<a href="https://dmz.rs/events.ical">ical</a> datotekom.
</p>
<p>
<a href="https://wiki.dmz.rs/en/kako-pronaci-prostor" target="_blank">Kratako uputstvo</a>
<a href="https://wiki.dmz.rs/en/kako-pronaci-prostor" target="_blank">
Kratako uputstvo
</a>
kako pronaci prostor
</p>
</div>
<div class="events-list">
{{ events_html|safe }}
</div>
{% endblock %}
+2 -10
View File
@@ -1,14 +1,6 @@
{% block title %}Events archive{% endblock %}
{% block content %}
<h1 class="title">Events archive</h1>
<h1>Events archive</h1>
<p>
All events that we organized so far. You can find future events on
<a href="/{{ lang }}/events">Events page</a>
<a href="/en/events">Events page</a>
</p>
<br />
<div class="events-list">
{{ events_html|safe }}
</div>
{% endblock %}
+2 -10
View File
@@ -1,14 +1,6 @@
{% block title %}Arhiva događaja{% endblock %}
{% block content %}
<h1 class="title">Arhiva događaja</h1>
<h1>Arhiva događaja</h1>
<p>
Svi događaji koje smo do sada organzivali. Predstojeće događaje možeš naći
<a href="/{{ lang }}/events">ovde</a>
<a href="/events">ovde</a>
</p>
<br />
<div class="events-list">
{{ events_html|safe }}
</div>
{% endblock %}
+79 -8
View File
@@ -1,11 +1,82 @@
{% extends "base.html" %}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<input type="checkbox" id="theme-toggle" />
{% block title %}{{ title }} Decentrala{% endblock %}
<!-- <pre>
{% block extra_styles %}{{ extra_styles|safe }}{% endblock %}
*@@*
*@@@@*
*@@*
||
||
*@@* *@@* *@@*
*@@@@*===*@@@@*===*@@@@*
*@@* *@@* *@@*
|| //
|| //
*@@*//
*@@@@*
*@@*
{% block content %}
<div class="page-wrap">
{{ content|safe }}
</div>
{% endblock %}
____ _____ ____ _____ _ _ _____ ____ _ _ _
| _ \| ____/ ___| ____| \ | |_ _| _ \ / \ | | / \
| | | | _|| | | _| | \| | | | | |_) | / _ \ | | / _ \
| |_| | |__| |___| |___| |\ | | | | _ < / ___ \| |___ / ___ \
|____/|_____\____|_____|_| \_| |_| |_| \_\/_/ \_\_____/_/ \_\
</pre> -->
<link rel="stylesheet" href="/styles/reset.css" />
<link rel="stylesheet" href="/styles/style.css" />
<!--ADDITIONAL_STYLE-->
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon" />
<title><!--TITLE--> Decentrala</title>
<link rel="alternate" hreflang="sr" href="/PAGE_NAME" />
</head>
<body>
<input type="checkbox" id="theme-toggle" />
<input type="checkbox" id="menu-toggle" />
<header>
<a id="logo" href="/en/index">
<img src="/img/logo-light.svg" alt="Logo" /> Decentrala
</a>
<label for="theme-toggle" id="theme-switcher"></label>
<a class="lang" hreflang="sr" href="/PAGE_NAME">SR</a>
</header>
<main>
<div class="page-wrap">
<!--MAIN-->
</div>
</main>
<footer>
<label for="menu-toggle" class="hamburger">
<img src="/img/strelica-closed-light.svg" alt="Menu" />
</label>
<nav class="menu">
<a href="/en/events">Events</a>
<a href="/en/services">Services</a>
<a href="/en/statute">Statute</a>
<a href="/en/about">About</a>
<a href="/en/account">Account</a>
<a href="/en/support">Support</a>
</nav>
<span class="links">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
<img src="/img/cc-light.svg" alt="CreativeCommons" />
</a>
<a href="/en/webring">
<img src="/img/w-light.svg" alt="Webring" />
</a>
<a href="https://gitea.dmz.rs/Decentrala/website">
<img src="/img/git-light.svg" alt="SourceCode" />
</a>
<a href="https://balkan.fedive.rs/@decentrala">
<img src="/img/mastodon-light.svg" alt="Mastodon" />
</a>
</span>
</footer>
</body>
</html>
+79 -8
View File
@@ -1,11 +1,82 @@
{% extends "base.html" %}
<!doctype html>
<html lang="sr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{% block title %}{{ title }} Decentrala{% endblock %}
<!-- <pre>
{% block extra_styles %}{{ extra_styles|safe }}{% endblock %}
*@@*
*@@@@*
*@@*
||
||
*@@* *@@* *@@*
*@@@@*===*@@@@*===*@@@@*
*@@* *@@* *@@*
|| //
|| //
*@@*//
*@@@@*
*@@*
{% block content %}
<div class="page-wrap">
{{ content|safe }}
</div>
{% endblock %}
____ _____ ____ _____ _ _ _____ ____ _ _ _
| _ \| ____/ ___| ____| \ | |_ _| _ \ / \ | | / \
| | | | _|| | | _| | \| | | | | |_) | / _ \ | | / _ \
| |_| | |__| |___| |___| |\ | | | | _ < / ___ \| |___ / ___ \
|____/|_____\____|_____|_| \_| |_| |_| \_\/_/ \_\_____/_/ \_\
</pre> -->
<link rel="stylesheet" href="/styles/reset.css" />
<link rel="stylesheet" href="/styles/style.css" />
<!--ADDITIONAL_STYLE-->
<link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon" />
<title><!--TITLE--> Decentrala</title>
<link rel="alternate" hreflang="en" href="/en/PAGE_NAME" />
</head>
<body>
<input type="checkbox" id="menu-toggle" />
<input type="checkbox" id="theme-toggle" />
<header>
<a id="logo" href="/">
<img src="/img/logo-light.svg" alt="Logo" />
Decentrala
</a>
<label for="theme-toggle" id="theme-switcher"></label>
<a class="lang" hreflang="en" href="/en/PAGE_NAME">EN</a>
</header>
<main>
<div class="page-wrap">
<!--MAIN-->
</div>
</main>
<footer>
<label for="menu-toggle" class="hamburger">
<img src="/img/strelica-closed-light.svg" alt="Menu" />
</label>
<nav class="menu">
<a href="/events">Događaji</a>
<a href="/services">Servisi</a>
<a href="/statute">Statut</a>
<a href="/about">O nama</a>
<a class="account" href="/account">Nalog</a>
<a href="/support">Podrška</a>
</nav>
<span class="links">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
<img src="/img/cc-light.svg" alt="CreativeCommons" />
</a>
<a href="/webring">
<img src="/img/w-light.svg" alt="Webring" />
</a>
<a href="https://gitea.dmz.rs/Decentrala/website">
<img src="/img/git-light.svg" alt="SourceCode" />
</a>
<a href="https://balkan.fedive.rs/@decentrala">
<img src="/img/mastodon-light.svg" alt="Mastodon" />
</a>
</span>
</footer>
</body>
</html>