From: Radek Czajka Date: Tue, 15 Nov 2011 11:23:04 +0000 (+0100) Subject: initial commit X-Git-Url: https://git.mdrn.pl/turniej.git/commitdiff_plain/3dbaa20d66d533211dc34746150cbb31f5afd5d3 initial commit --- 3dbaa20d66d533211dc34746150cbb31f5afd5d3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1146e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +localsettings.py +*.db +*.db-journal +*~ + +# Python garbage +*.pyc +.coverage +pip-log.txt +nosetests.xml + +# Mac OS X garbage +.DS_Store + +# Windows garbage +thumbs.db + +# Eclipse +.project +.settings +.pydevproject +.tmp_* + diff --git a/apps/poetry/__init__.py b/apps/poetry/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/poetry/migrations/0001_initial.py b/apps/poetry/migrations/0001_initial.py new file mode 100644 index 0000000..c6bfda3 --- /dev/null +++ b/apps/poetry/migrations/0001_initial.py @@ -0,0 +1,78 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding model 'Poet' + db.create_table('poetry_poet', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=50)), + ('path', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)), + ('author', self.gf('django.db.models.fields.CharField')(max_length=128, blank=True)), + ('url', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('description', self.gf('django.db.models.fields.TextField')(blank=True)), + ('first_line_title', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('skip_first_lines', self.gf('django.db.models.fields.IntegerField')(default=0)), + )) + db.send_create_signal('poetry', ['Poet']) + + # Adding model 'Poem' + db.create_table('poetry_poem', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50, db_index=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)), + ('text', self.gf('django.db.models.fields.TextField')()), + ('poet', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['poetry.Poet'])), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)), + ('seen_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('view_count', self.gf('django.db.models.fields.IntegerField')(default=1)), + ('for_contest', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('in_contest', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal('poetry', ['Poem']) + + + def backwards(self, orm): + + # Deleting model 'Poet' + db.delete_table('poetry_poet') + + # Deleting model 'Poem' + db.delete_table('poetry_poem') + + + models = { + 'poetry.poem': { + 'Meta': {'object_name': 'Poem'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'for_contest': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'in_contest': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'poet': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['poetry.Poet']"}), + 'seen_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'view_count': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + 'poetry.poet': { + 'Meta': {'object_name': 'Poet'}, + 'author': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'first_line_title': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'skip_first_lines': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + } + } + + complete_apps = ['poetry'] diff --git a/apps/poetry/migrations/__init__.py b/apps/poetry/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/poetry/models.py b/apps/poetry/models.py new file mode 100644 index 0000000..39f3e05 --- /dev/null +++ b/apps/poetry/models.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +import os +import subprocess +from django.db import models +from django.core.urlresolvers import reverse +from poetry.utils import get_hash + + +class Poet(models.Model): + name = models.CharField(max_length=50) + path = models.CharField(max_length=255) + slug = models.SlugField(max_length=50, unique=True, db_index=True) + author = models.CharField(max_length=128, blank=True) + url = models.CharField(max_length=255, blank=True) + description = models.TextField(blank=True) + first_line_title = models.BooleanField(default=False) + skip_first_lines = models.IntegerField(default=0) + + def __unicode__(self): + return self.name + + def get_absolute_url(self): + return reverse('poetry_poet', kwargs={'slug': self.slug}) + + def write(self): + curdir = os.getcwd() + os.chdir(os.path.dirname(self.path)) + text = subprocess.check_output(self.path).decode("utf-8") + os.chdir(curdir) + text = text[:1000] + slug = get_hash(text) + title = '' + if self.first_line_title: + title, text = text.split('\n', 1) + if self.skip_first_lines: + text = text.split('\n', self.skip_first_lines)[-1] + text = text.strip('\n') + poem = self.poem_set.create( + slug=slug, + text=text, + title=title + ) + return poem + + +class Poem(models.Model): + slug = models.SlugField(max_length=50, db_index=True) + title = models.CharField(max_length=255, null=True, blank=True) + text = models.TextField() + poet = models.ForeignKey(Poet) + created_at = models.DateTimeField(auto_now_add=True, editable=False, db_index=True) + seen_at = models.DateTimeField(auto_now_add=True, editable=False) + view_count = models.IntegerField(default=1) + + for_contest = models.BooleanField(default=False) + in_contest = models.BooleanField(default=False) + + def __unicode__(self): + oneliner = u"%s, %s" % (self.poet.name, self.pretty_title()) + if not self.title: + oneliner += u" [%s…]" % self.text[:20] + return oneliner + + def get_absolute_url(self): + return reverse('poetry_poem', kwargs={'slug': self.slug}) + + def pretty_title(self): + return self.title or "***" + + def visit(self): + self.view_count += 1 + self.seen_at = datetime.now() + self.save() diff --git a/apps/poetry/static/poetry/poem.css b/apps/poetry/static/poetry/poem.css new file mode 100644 index 0000000..e2f6f01 --- /dev/null +++ b/apps/poetry/static/poetry/poem.css @@ -0,0 +1,137 @@ +body { + font-size: 16px; + font: Georgia, "Times New Roman", serif; + line-height: 1.5em; + margin: 0; +} + +a { + color: blue; + text-decoration: none; +} + +a:hover { + border-bottom: 1px dotted; +} + +#book-text { + margin: 3em; + max-width: 36em; +} + +/* ================================== */ +/* = Header with logo and menu = */ +/* ================================== */ +#header { + margin: 3.4em 0 0 1.4em; +} + +img { + border: none; +} + + +#menu { + position: fixed; + left: 0em; + top: 0em; + width: 100%; + height: 1.5em; + background: #333; + color: #FFF; + opacity: 0.9; + z-index: 99; +} + +#menu a.menu-link { + display: block; + float: left; + height: 1.5em; + margin-left: 0.5em; + text-align: center; + color: #FFF; +} +#menu span { + color: #888; + font-style: italic; + font-size: .75em; + margin-right: 0.5em; +} + + +/* =================================================== */ +/* = Common elements: headings, paragraphs and lines = */ +/* =================================================== */ +h1 { + font-size: 3em; + margin: 1.5em 0; + text-align: center; + line-height: 1.5em; + font-weight: bold; +} + +h2 { + font-size: 2em; + margin: 1.5em 0 0; + font-weight: bold; + line-height: 1.5em; +} + +h3 { + font-size: 1.5em; + margin: 1.5em 0 0; + font-weight: normal; + line-height: 1.5em; +} + +h4 { + font-size: 1em; + margin: 1.5em 0 0; + line-height: 1.5em; +} + +p { + margin: 0; +} + + +#footnotes { + margin-top: 3em; + margin-left: 2.5em; + font-size: 0.875em; +} + +#footnotes p, #footnotes ul { + margin: 1.5em 0; +} + +#footnotes .permalink { + font-size: .75em; +} + +/* =================== */ +/* = Custom elements = */ +/* =================== */ +span.author { + font-size: 0.5em; + display: block; + line-height: 1.5em; + margin-bottom: 0.25em; +} + +span.author a { + color: inherit; +} + +span.author a { + color: inherit; +} + + +/* =================================== */ +/* = Hide some elements for printing = */ +/* =================================== */ + +@media print { + #menu {display: none;} +} diff --git a/apps/poetry/templates/poetry/main.html b/apps/poetry/templates/poetry/main.html new file mode 100644 index 0000000..76fdf09 --- /dev/null +++ b/apps/poetry/templates/poetry/main.html @@ -0,0 +1,62 @@ +{% extends "base.html" %} +{% load url from future %} + +{% block "body" %} + +

+ +Turniej Elektrybałtów

+{% comment %} +
+ +
+
+ + +
+{% endcomment %} +

Uczestnicy:

+ + +
+ +Twórz-że się! + +

Ostatnio opublikowane utwory:

+ + +{% endblock %} diff --git a/apps/poetry/templates/poetry/poem.html b/apps/poetry/templates/poetry/poem.html new file mode 100644 index 0000000..55bf749 --- /dev/null +++ b/apps/poetry/templates/poetry/poem.html @@ -0,0 +1,86 @@ +{% load url from future %} + + + + Turniej Elektrybałtów: {{ poem.poet.name }} + + + + + + + + +
+ + + + + + + +
+

+ {{ poem.poet.name }} + {% if poem.title %}{{ poem.title }}{% else %}***{% endif %} +

+ {{ poem.text|linebreaksbr }} +
+

O utworze

+

Autor: {{ poem.poet.name }} (wszyscy autorzy). +
Zobacz nowy wiersz tego autora, + albo nowy wiersz dowolnego autora.

+ + + +
+

Podziel się wierszem!

+ +
+
+ + + +
+ albo użyj linku:
+ +
+ + + + +
+ + + + + + + + diff --git a/apps/poetry/templates/poetry/poet.html b/apps/poetry/templates/poetry/poet.html new file mode 100644 index 0000000..053dce5 --- /dev/null +++ b/apps/poetry/templates/poetry/poet.html @@ -0,0 +1,44 @@ +{% extends "base.html" %} +{% load url from future %} + +{% block "body" %} + +

+ +{{ poet.name }}

+ +
+ +
+
+ + +
+ +

Zobacz wszystkich autorów.

+ +

Autor programu: {{ poet.author }}

+ +

{{ poet.description }}

+ +

Kod źródłowy: {{ poet.url }}

+ +Twórz-że! + +

Ostatnio opublikowane utwory:

+ + +{% endblock %} diff --git a/apps/poetry/urls.py b/apps/poetry/urls.py new file mode 100644 index 0000000..8d0baeb --- /dev/null +++ b/apps/poetry/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('poetry.views', + url(r'^wiersz/(?P[a-zA-Z0-9-]+)/$', 'poem', name='poetry_poem'), + + url(r"^$", "main", name="poetry_main"), + url(r"^nowy/$", 'new', name="poetry_new"), + url(r"^(?P[a-zA-Z0-9-]+)/$", "poet", name="poetry_poet"), + url(r"^(?P[a-zA-Z0-9-]+)/nowy/$", 'new', name="poetry_new"), + +) diff --git a/apps/poetry/utils.py b/apps/poetry/utils.py new file mode 100644 index 0000000..76dce25 --- /dev/null +++ b/apps/poetry/utils.py @@ -0,0 +1,10 @@ +import time + +from base64 import urlsafe_b64encode +from django.utils.hashcompat import sha_constructor + + +def get_hash(seed): + sha_digest = sha_constructor('%s%s' % + (time.time(), unicode(seed).encode('utf-8', 'replace'))).digest() + return urlsafe_b64encode(sha_digest).replace('=', '').replace('_', '-').lower() diff --git a/apps/poetry/views.py b/apps/poetry/views.py new file mode 100644 index 0000000..06c95a2 --- /dev/null +++ b/apps/poetry/views.py @@ -0,0 +1,29 @@ +from django.shortcuts import render, get_object_or_404 +from poetry.models import Poet, Poem + + +def new(request, slug=None): + if slug is not None: + poet = get_object_or_404(Poet, slug=slug) + else: + poet = Poet.objects.order_by('?')[0] + + poem = poet.write() + return render(request, "poetry/poem.html", locals()) + + +def poem(request, slug): + poem = get_object_or_404(Poem, slug=slug) + return render(request, "poetry/poem.html", locals()) + + +def poet(request, slug): + poet = get_object_or_404(Poet, slug=slug) + last = poet.poem_set.order_by('-created_at')[:20] + return render(request, "poetry/poet.html", locals()) + + +def main(request): + poets = Poet.objects.all().order_by('?') + last = Poem.objects.all().order_by('-created_at')[:20] + return render(request, "poetry/main.html", locals()) diff --git a/fabfile.py b/fabfile.py new file mode 100644 index 0000000..eb30a2f --- /dev/null +++ b/fabfile.py @@ -0,0 +1,200 @@ +from __future__ import with_statement # needed for python 2.5 +from fabric.api import * +from fabric.contrib import files + +import os + + +# ========== +# = Config = +# ========== +# Globals +env.project_name = 'turniej' +env.use_south = True + +# Servers +def giewont(): + env.hosts = ['giewont.icm.edu.pl'] + env.user = 'lektury' + env.path = '/srv/turniej.wolnelektury.pl' + env.virtualenv = '/usr/bin/virtualenv' + # This goes to VHost configuration + env.server_name = 'turniej.wolnelektury.pl' + env.server_admin = 'Radoslaw Czajka ' + # /var/log/apache2/* logs + env.access_log = 'turniej.log' + env.error_log = 'turniej-errors.log' + + +servers = [giewont] + +# ========= +# = Tasks = +# ========= +def test(): + "Run the test suite and bail out if it fails" + require('hosts', 'path', provided_by=servers) + require('python', provided_by=[find_python]) + result = run('cd %(path)s/%(project_name)s; %(python)s manage.py test' % env) + +def setup(): + """ + Setup a fresh virtualenv as well as a few useful directories, then run + a full deployment. virtualenv with pip should be already installed. + """ + require('hosts', 'path', 'virtualenv', provided_by=servers) + + run('mkdir -p %(path)s; cd %(path)s; %(virtualenv)s ve;' % env, pty=True) + run('cd %(path)s; mkdir releases; mkdir packages;' % env, pty=True) + run('cd %(path)s/releases; ln -s . current; ln -s . previous' % env, pty=True) + upload_default_localsettings() + deploy() + +def deploy(): + """ + Deploy the latest version of the site to the servers, + install any required third party modules, + install the virtual host and then restart the webserver + """ + + import time + env.release = time.strftime('%Y-%m-%dT%H%M') + + upload_tar_from_git() + find_python() + upload_wsgi_script() + upload_vhost_sample() + install_requirements() + copy_localsettings() + symlink_current_release() + collectstatic() + migrate() + restart_webserver() + +def deploy_version(version): + "Specify a specific version to be made live" + require('hosts', 'path', provided_by=servers) + env.version = version + with cd(env.path): + run('rm releases/previous; mv releases/current releases/previous;', pty=True) + run('ln -s %(version)s releases/current' % env, pty=True) + restart_webserver() + +def rollback(): + """ + Limited rollback capability. Simple loads the previously current + version of the code. Rolling back again will swap between the two. + """ + require('hosts', 'path', provided_by=servers) + with cd(env.path): + run('mv releases/current releases/_previous;', pty=True) + run('mv releases/previous releases/current;', pty=True) + run('mv releases/_previous releases/previous;', pty=True) + restart_webserver() + + +# ===================================================================== +# = Helpers. These are called by other functions rather than directly = +# ===================================================================== +def upload_tar_from_git(): + "Create an archive from the current Git branch and upload it" + print '>>> upload tar from git' + require('path', provided_by=servers) + require('release', provided_by=[deploy]) + local('/bin/bash lib/git-archive-all.sh --format tar %(release)s.tar' % env) + local('gzip %(release)s.tar' % env) + run('mkdir -p %(path)s/releases/%(release)s' % env, pty=True) + run('mkdir -p %(path)s/packages' % env, pty=True) + put('%(release)s.tar.gz' % env, '%(path)s/packages/' % env) + run('cd %(path)s/releases/%(release)s && tar zxf ../../packages/%(release)s.tar.gz' % env, pty=True) + local('rm %(release)s.tar.gz' % env) + +def find_python(): + "Finds where virtualenv Python stuff is" + print ">>> find Python paths" + require('path', provided_by=servers) + env.python = '%(path)s/ve/bin/python' % env + env.pip = '%(path)s/ve/bin/pip' % env + env.site_packages = run('%(python)s -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"' % env) + +def upload_vhost_sample(): + "Create and upload Apache virtual host configuration sample" + print ">>> upload vhost sample" + require('path', 'project_name', 'user', provided_by=servers) + require('access_log', 'error_log', 'server_admin', 'server_name', provided_by=servers) + require('site_packages', provided_by=[find_python]) + files.upload_template('%(project_name)s.vhost.template' % env, '%(path)s/%(project_name)s.vhost' % env, context=env) + +def upload_wsgi_script(): + "Create and upload a wsgi script sample" + print ">>> upload wsgi script sample" + require('path', 'project_name', provided_by=servers) + require('python', 'site_packages', provided_by=[find_python]) + files.upload_template('%(project_name)s.wsgi.template' % env, '%(path)s/%(project_name)s.wsgi' % env, context=env) + run('chmod ug+x %(path)s/%(project_name)s.wsgi' % env) + +def install_requirements(): + "Install the required packages from the requirements file using pip" + print '>>> install requirements' + require('path', provided_by=servers) + require('release', provided_by=[deploy]) + require('pip', provided_by=[find_python]) + run('%(pip)s install -r %(path)s/releases/%(release)s/requirements.txt' % env, pty=True) + +def secret_key(): + """Generates a new SECRET_KEY.""" + from random import Random + import string + + r = Random() + return "".join(r.choice(string.printable) for i in range(64)) + +def upload_default_localsettings(): + "Uploads localsettings.py with media paths and stuff" + print ">>> upload default localsettings.py" + require('path', provided_by=servers) + + env.secret_key = secret_key() + files.upload_template('%(project_name)s/localsettings.py.template' % env, '%(path)s/localsettings.py' % env, context=env) + +def copy_localsettings(): + "Copy localsettings.py from root directory to release directory (if this file exists)" + print ">>> copy localsettings" + require('path', 'project_name', provided_by=servers) + require('release', provided_by=[deploy]) + + with settings(warn_only=True): + run('cp %(path)s/localsettings.py %(path)s/releases/%(release)s/%(project_name)s' % env) + +def symlink_current_release(): + "Symlink our current release" + print '>>> symlink current release' + require('path', provided_by=servers) + require('release', provided_by=[deploy]) + with cd(env.path): + run('rm releases/previous; mv releases/current releases/previous') + run('ln -s %(release)s releases/current' % env) + +def collectstatic(): + """Runs collectstatic management command from Django staticfiles.""" + print '>>> collectstatic' + require('path', 'project_name', provided_by=servers) + require('python', provided_by=[find_python]) + with cd('%(path)s/releases/current/%(project_name)s' % env): + run('%(python)s manage.py collectstatic --noinput' % env, pty=True) + +def migrate(): + "Update the database" + print '>>> migrate' + require('path', 'project_name', provided_by=servers) + require('python', provided_by=[find_python]) + with cd('%(path)s/releases/current/%(project_name)s' % env): + run('%(python)s manage.py syncdb --noinput' % env, pty=True) + if env.use_south: + run('%(python)s manage.py migrate' % env, pty=True) + +def restart_webserver(): + "Restart the web server" + print '>>> restart webserver' + require('path', 'project_name', provided_by=servers) + run('touch %(path)s/%(project_name)s.wsgi' % env) diff --git a/lib/git-archive-all.sh b/lib/git-archive-all.sh new file mode 100644 index 0000000..95e8582 --- /dev/null +++ b/lib/git-archive-all.sh @@ -0,0 +1,208 @@ +#!/bin/bash - +# +# File: git-archive-all.sh +# +# Description: A utility script that builds an archive file(s) of all +# git repositories and submodules in the current path. +# Useful for creating a single tarfile of a git super- +# project that contains other submodules. +# +# Examples: Use git-archive-all.sh to create archive distributions +# from git repositories. To use, simply do: +# +# cd $GIT_DIR; git-archive-all.sh +# +# where $GIT_DIR is the root of your git superproject. +# +# License: GPL3 +# +############################################################################### +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +############################################################################### + +# DEBUGGING +set -e +set -C # noclobber + +# TRAP SIGNALS +trap 'cleanup' QUIT EXIT + +# For security reasons, explicitly set the internal field separator +# to newline, space, tab +OLD_IFS=$IFS +IFS=' + ' + +function cleanup () { + rm -f $TMPFILE + rm -f $TOARCHIVE + IFS="$OLD_IFS" +} + +function usage () { + echo "Usage is as follows:" + echo + echo "$PROGRAM <--version>" + echo " Prints the program version number on a line by itself and exits." + echo + echo "$PROGRAM <--usage|--help|-?>" + echo " Prints this usage output and exits." + echo + echo "$PROGRAM [--format ] [--prefix ] [--separate|-s] [output_file]" + echo " Creates an archive for the entire git superproject, and its submodules" + echo " using the passed parameters, described below." + echo + echo " If '--format' is specified, the archive is created with the named" + echo " git archiver backend. Obviously, this must be a backend that git archive" + echo " understands. The format defaults to 'tar' if not specified." + echo + echo " If '--prefix' is specified, the archive's superproject and all submodules" + echo " are created with the prefix named. The default is to not use one." + echo + echo " If '--separate' or '-s' is specified, individual archives will be created" + echo " for each of the superproject itself and its submodules. The default is to" + echo " concatenate individual archives into one larger archive." + echo + echo " If 'output_file' is specified, the resulting archive is created as the" + echo " file named. This parameter is essentially a path that must be writeable." + echo " When combined with '--separate' ('-s') this path must refer to a directory." + echo " Without this parameter or when combined with '--separate' the resulting" + echo " archive(s) are named with a dot-separated path of the archived directory and" + echo " a file extension equal to their format (e.g., 'superdir.submodule1dir.tar')." +} + +function version () { + echo "$PROGRAM version $VERSION" +} + +# Internal variables and initializations. +readonly PROGRAM=`basename "$0"` +readonly VERSION=0.2 + +OLD_PWD="`pwd`" +TMPDIR=${TMPDIR:-/tmp} +TMPFILE=`mktemp "$TMPDIR/$PROGRAM.XXXXXX"` # Create a place to store our work's progress +TOARCHIVE=`mktemp "$TMPDIR/$PROGRAM.toarchive.XXXXXX"` +OUT_FILE=$OLD_PWD # assume "this directory" without a name change by default +SEPARATE=0 + +FORMAT=tar +PREFIX= +TREEISH=HEAD + +# RETURN VALUES/EXIT STATUS CODES +readonly E_BAD_OPTION=254 +readonly E_UNKNOWN=255 + +# Process command-line arguments. +while test $# -gt 0; do + case $1 in + --format ) + shift + FORMAT="$1" + shift + ;; + + --prefix ) + shift + PREFIX="$1" + shift + ;; + + --separate | -s ) + shift + SEPARATE=1 + ;; + + --version ) + version + exit + ;; + + -? | --usage | --help ) + usage + exit + ;; + + -* ) + echo "Unrecognized option: $1" >&2 + usage + exit $E_BAD_OPTION + ;; + + * ) + break + ;; + esac +done + +if [ ! -z "$1" ]; then + OUT_FILE="$1" + shift +fi + +# Validate parameters; error early, error often. +if [ $SEPARATE -eq 1 -a ! -d $OUT_FILE ]; then + echo "When creating multiple archives, your destination must be a directory." + echo "If it's not, you risk being surprised when your files are overwritten." + exit +elif [ `git config -l | grep -q '^core\.bare=false'; echo $?` -ne 0 ]; then + echo "$PROGRAM must be run from a git working copy (i.e., not a bare repository)." + exit +fi + +# Create the superproject's git archive +git archive --format=$FORMAT --prefix="$PREFIX" $TREEISH > $TMPDIR/$(basename $(pwd)).$FORMAT +echo $TMPDIR/$(basename $(pwd)).$FORMAT >| $TMPFILE # clobber on purpose +superfile=`head -n 1 $TMPFILE` + +# find all '.git' dirs, these show us the remaining to-be-archived dirs +find . -name '.git' -type d -print | sed -e 's/^\.\///' -e 's/\.git$//' | (grep -v '^$' || echo -n) >> $TOARCHIVE + +while read path; do + TREEISH=$(git submodule | grep "^ .*${path%/} " | cut -d ' ' -f 2) # git submodule does not list trailing slashes in $path + cd "$path" + git archive --format=$FORMAT --prefix="${PREFIX}$path" ${TREEISH:-HEAD} > "$TMPDIR"/"$(echo "$path" | sed -e 's/\//./g')"$FORMAT + if [ $FORMAT == 'zip' ]; then + # delete the empty directory entry; zipped submodules won't unzip if we don't do this + zip -d "$(tail -n 1 $TMPFILE)" "${PREFIX}${path%/}" >/dev/null # remove trailing '/' + fi + echo "$TMPDIR"/"$(echo "$path" | sed -e 's/\//./g')"$FORMAT >> $TMPFILE + cd "$OLD_PWD" +done < $TOARCHIVE + +# Concatenate archives into a super-archive. +if [ $SEPARATE -eq 0 ]; then + if [ $FORMAT == 'tar' ]; then + sed -e '1d' $TMPFILE | while read file; do + tar --concatenate -f "$superfile" "$file" && rm -f "$file" + done + elif [ $FORMAT == 'zip' ]; then + sed -e '1d' $TMPFILE | while read file; do + # zip incorrectly stores the full path, so cd and then grow + cd `dirname "$file"` + zip -g "$superfile" `basename "$file"` && rm -f "$file" + done + cd "$OLD_PWD" + fi + + echo "$superfile" >| $TMPFILE # clobber on purpose +fi + +while read file; do + mv "$file" "$OUT_FILE" +done < $TMPFILE diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..aec394f --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +django-debug-toolbar diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2e16d22 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +# Django basics +django>=1.3,<1.4 +South>=0.7 + +piwik diff --git a/turniej.vhost.template b/turniej.vhost.template new file mode 100644 index 0000000..3caae7f --- /dev/null +++ b/turniej.vhost.template @@ -0,0 +1,31 @@ + + ServerName "%(server_name)s" + ServerAdmin "%(server_admin)s" + + WSGIDaemonProcess %(project_name)s user=%(user)s group=%(user)s processes=2 threads=15 display-name=%%{GROUP} python-path=%(site_packages)s + WSGIProcessGroup %(project_name)s + + WSGIScriptAlias / %(path)s/%(project_name)s.wsgi + + Order allow,deny + allow from all + + + Alias /media %(path)s/media + + Options Indexes + Order allow,deny + Allow from all + + + Alias /static %(path)s/releases/current/%(project_name)s/static + + Options Indexes + Order allow,deny + Allow from all + + + LogLevel warn + ErrorLog /var/log/apache2/%(error_log)s + CustomLog /var/log/apache2/%(access_log)s combined + diff --git a/turniej.wsgi.template b/turniej.wsgi.template new file mode 100644 index 0000000..af1781c --- /dev/null +++ b/turniej.wsgi.template @@ -0,0 +1,26 @@ +#!%(python)s +import site +site.addsitedir('%(site_packages)s') + +import os +from os.path import abspath, dirname, join +import sys + +# Redirect sys.stdout to sys.stderr for bad libraries like geopy that use +# print statements for optional import exceptions. +sys.stdout = sys.stderr + +# Add apps and lib directories to PYTHONPATH +sys.path = [ + '%(path)s/releases/current/%(project_name)s', + '%(path)s/releases/current', + '%(path)s/releases/current/apps', + '%(path)s/releases/current/lib', + # add paths to submodules here +] + sys.path + +# Run Django +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' + +from django.core.handlers.wsgi import WSGIHandler +application = WSGIHandler() diff --git a/turniej/__init__.py b/turniej/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/turniej/localsettings.py.template b/turniej/localsettings.py.template new file mode 100644 index 0000000..3765080 --- /dev/null +++ b/turniej/localsettings.py.template @@ -0,0 +1,27 @@ +# This template is uploaded by `fab setup`. +# You should fill out the details in the version deployed on the server. + + +ADMINS = ( + #('Name', 'E-mail'), +) + +MANAGERS = ( + #('Name', 'E-mail'), +) + +# on +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': '', # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + + +SECRET_KEY = %(secret_key)r +MEDIA_ROOT = '%(path)s/media/' diff --git a/turniej/manage.py b/turniej/manage.py new file mode 100755 index 0000000..eb91c2d --- /dev/null +++ b/turniej/manage.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +import os.path +import sys + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Add apps and lib directories to PYTHONPATH +sys.path = [ + os.path.join(ROOT, 'apps'), + os.path.join(ROOT, 'lib'), + # add /lib/* paths here for submodules +] + sys.path + +from django.core.management import execute_manager +import imp +try: + imp.find_module('settings') # Assumed to be in the same directory. +except ImportError: + import sys + sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) + sys.exit(1) + +import settings + +if __name__ == "__main__": + execute_manager(settings) diff --git a/turniej/settings.py b/turniej/settings.py new file mode 100644 index 0000000..62a66e5 --- /dev/null +++ b/turniej/settings.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +# Django settings for turniej project. +import os.path + +PROJECT_DIR = os.path.abspath(os.path.dirname(__file__)) + +DEBUG = False +TEMPLATE_DEBUG = DEBUG + +ADMINS = [ + # ('Your Name', 'your_email@domain.com'), +] + +MANAGERS = ADMINS + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': os.path.join(PROJECT_DIR, 'dev.db'), # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = None + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +#LANGUAGE_CODE = 'pl' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +#USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale +#USE_L10N = True + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +MEDIA_ROOT = os.path.join(PROJECT_DIR, '../media') + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = '/media/' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = os.path.join(PROJECT_DIR, '../static') + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '/static/' + +# URL prefix for admin static files -- CSS, JavaScript and images. +# Make sure to use a trailing slash. +# Examples: "http://foo.com/static/admin/", "/static/admin/". +ADMIN_MEDIA_PREFIX = '/static/admin/' + +# Additional locations of static files +STATICFILES_DIRS = ( + # Put strings here, like "/home/html/static" or "C:/www/django/static". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. + + os.path.join(PROJECT_DIR, 'static'), +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', +) + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = [ + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.common.CommonMiddleware', + #'django.contrib.sessions.middleware.SessionMiddleware', + #'django.middleware.csrf.CsrfViewMiddleware', + #'django.contrib.auth.middleware.AuthenticationMiddleware', + #'django.contrib.messages.middleware.MessageMiddleware', +] + +ROOT_URLCONF = 'turniej.urls' + +TEMPLATE_DIRS = [ + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. + os.path.join(PROJECT_DIR, 'templates'), +] + +INSTALLED_APPS = [ + #'django.contrib.auth', + #'django.contrib.contenttypes', + #'django.contrib.sessions', + #'django.contrib.sites', + #'django.contrib.messages', + 'django.contrib.staticfiles', + + # 'django.contrib.admin', + # 'django.contrib.admindocs', + + 'south', + + 'poetry', +] + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error. +# See http://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': True, + }, + } +} + +# Load localsettings, if they exist +try: + from localsettings import * +except ImportError: + pass diff --git a/turniej/static/img/cc.png b/turniej/static/img/cc.png new file mode 100644 index 0000000..1de9d62 Binary files /dev/null and b/turniej/static/img/cc.png differ diff --git a/turniej/static/img/di.png b/turniej/static/img/di.png new file mode 100644 index 0000000..8136626 Binary files /dev/null and b/turniej/static/img/di.png differ diff --git a/turniej/static/img/favicon.ico b/turniej/static/img/favicon.ico new file mode 100644 index 0000000..89067a8 Binary files /dev/null and b/turniej/static/img/favicon.ico differ diff --git a/turniej/static/img/fnp.png b/turniej/static/img/fnp.png new file mode 100644 index 0000000..fe75e2d Binary files /dev/null and b/turniej/static/img/fnp.png differ diff --git a/turniej/static/img/koed.png b/turniej/static/img/koed.png new file mode 100644 index 0000000..6bcce17 Binary files /dev/null and b/turniej/static/img/koed.png differ diff --git a/turniej/static/img/lempl.png b/turniej/static/img/lempl.png new file mode 100644 index 0000000..51c9b9e Binary files /dev/null and b/turniej/static/img/lempl.png differ diff --git a/turniej/static/img/turniej-maly.png b/turniej/static/img/turniej-maly.png new file mode 100644 index 0000000..b11f0d6 Binary files /dev/null and b/turniej/static/img/turniej-maly.png differ diff --git a/turniej/static/img/turniej.png b/turniej/static/img/turniej.png new file mode 100644 index 0000000..dbcbda4 Binary files /dev/null and b/turniej/static/img/turniej.png differ diff --git a/turniej/static/img/wl.png b/turniej/static/img/wl.png new file mode 100644 index 0000000..1d6cb6a Binary files /dev/null and b/turniej/static/img/wl.png differ diff --git a/turniej/static/style.css b/turniej/static/style.css new file mode 100644 index 0000000..f26fe8e --- /dev/null +++ b/turniej/static/style.css @@ -0,0 +1,148 @@ +html { + margin: 0; +} + +body { + margin: 0; + padding: 1em; + color: #2F4110; + background: url("http://static.wolnelektury.pl/img/bg.png") repeat-x scroll 0 0 #FFFFFF; + + font-size: .75em; + font-family: Verdana,Arial,Helvetica,sans-serif; +} + + +#body { + max-width: 900px; + margin:auto; + +} + + +#content { + width: 420px; + margin-top: 2em; +} + + + +h1 { + font: bold 2.2em Arial,sans-serif; + padding-top: .7em; + margin-bottom: .2em; +} + + +h2 { + font-size: 1.1em; + margin:0; +} + +a { + color: #295158; + text-decoration: none; +} +a:hover { + border-bottom: 1px dotted; +} + + +.plain li { + list-style: none; +} + +li { + margin: 1em; +} + +#termin-wrap { + margin-top: 3em; +} + + +.clr { + clear: both; +} + +#footer { + border-top: 1px solid #ddd; + margin-top: 7em; + clear: both; + +} +#footer img { + margin: 30px 13px; + vertical-align: middle; +} + + +blockquote { + font-size: .9em; + font-style: italic; + margin-left: 350px; + margin-right: 50px; + margin-bottom: 4em; +} +blockquote p { + margin: .5em 0 0 0; +} + +.more { + text-align: right; +} + +.uwaga { + border: 1px solid #ddd; + padding: 1em; + background-color: #ff8; +} + +.social { + margin-top: 10px; + margin-bottom: 10px; +} + + +.tworz { + font-size: 1.5em; + padding: .8em; + background: #555; + color: white; + margin: 1em auto; + display: block; + width: 10em; + text-align: center; + border: 1px solid #000; + border-radius: 1em; +} +.tworz:hover { + border: 1px solid #000; + background: #666; +} + +.last { + list-style: none; + padding: 0; +} +.last li { + margin-left: 0; +} + +.poet-list { + padding: 0; + margin: 1em 0; +} +.poet-list li { + float: left; + width: 30%; + list-style: none; + padding: .8em 0; + border: 1px solid #888; + background: #eee; + border-radius: 1em; + text-align: center; +} +.poet-list li:before { + content: "» "; +} diff --git a/turniej/templates/404.html b/turniej/templates/404.html new file mode 100644 index 0000000..5bfd7f8 --- /dev/null +++ b/turniej/templates/404.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block "body" %} +

Nie znaleziono strony

+ +

Nie ma tu żadnej strony. Przejdź do strony głównej.

+ +{% endblock %} diff --git a/turniej/templates/500.html b/turniej/templates/500.html new file mode 100644 index 0000000..0940a22 --- /dev/null +++ b/turniej/templates/500.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block "body" %} +

Błąd

+ +

Wystąpił błąd serwera. Przepraszamy!

+ +{% endblock %} diff --git a/turniej/templates/base.html b/turniej/templates/base.html new file mode 100644 index 0000000..4b28f18 --- /dev/null +++ b/turniej/templates/base.html @@ -0,0 +1,36 @@ + + + + Turniej Elektrybałtów + + + + + + + + +
+ + + +
+{% block "body" %}{% endblock %} +
+ + + + + + + diff --git a/turniej/templates/home.html b/turniej/templates/home.html new file mode 100644 index 0000000..d0eb78e --- /dev/null +++ b/turniej/templates/home.html @@ -0,0 +1,97 @@ +{% extends "base.html" %} +{% load url from future %} + +{% block "body" %} + +
+logo Turnieju Elektrybałtów: frontalny widok maszynki do mielenia mięsa +

Ostatnie wiersze:

+
    +{% for poem in last %} +
  • {{ poem }}
  • +{% endfor %} +
+ +
+ +
+

Turniej Elektrybałtów

+

Konkurs automatycznej poezji

+ + + + +

Znacie Leśmianatora? +To niewielki skrypt miksujący na życzenie wiersze z +Wolnych Lektur. +Powstał jako żart, a niechcący + +„odciął się od dosłownie rozumianego dziedzictwa dadaizmu i surrealizmu”. +Idziemy dalej – ogłaszamy otwarty konkurs na najlepszego automatycznego poetę!

+ +

Konkurs wystartował 12 września 2011 roku – z okazji 90 rocznicy urodzin +Stanisława Lema. Termin nadsyłania prac upłynął +10 listopada 2011 roku. +Prezentujemy nadesłane prace w akcji. +Kliknij przycisk, a jeden +z programów-uczestników napisze dla Ciebie wiersz:

+ +Twórz-że się! + +

Zobacz wszystkie programy. Ich kod źródłowy +jest dostępny na wolnej licencji +– nic więc nie stoi na przeszkodzie, by rozwijać je dalej.

+ +

Do zabawy zapraszamy wszystkich – i tych, którzy świetnie programują, i tych, którzy +programować dopiero się uczą. Tych, którzy nie rozstają się z tomikiem +wierszy, i tych, którzy na ten widok dostają gęsiej skórki. Chcemy wybrać +program, który będzie w najciekawszy i najbardziej twórczy sposób miksował +dostępną w Wolnych Lekturach literaturę. W tej konkurencji liczy się przede +wszystkim wyobraźnia, pomysł i chęć do twórczej zabawy.

+ +

Więcej informacji:

+ +
    +
  • Przebieg konkursu – czyli jakie będą kolejne etapy + i co jest nagrodą?
  • + +
  • Technikalia – czyli co i jak trzeba zrobić, + żeby wziąć udział.
  • + +
  • Regulamin – czyli trochę koniecznych formalności.
  • +
+ +

Wszelkiego rodzaju pytania i wątpliwości proszę kierować na adres +radoslaw.czajka@nowoczesnapolska.org.pl

+ +
+
+ + + + + +{% endblock %} diff --git a/turniej/templates/pages/more.html b/turniej/templates/pages/more.html new file mode 100644 index 0000000..c60db14 --- /dev/null +++ b/turniej/templates/pages/more.html @@ -0,0 +1,65 @@ +{% extends "base.html" %} + +{% block "body" %} + +

+ +Turniej Elektrybałtów

+

+Konkurs automatycznej poezji

+ +
+

Gdy wskaźniki amplifikacyjne pokazały, że moc liryczna dochodzi + do maksimum, Trurl nieznacznie tylko drżącą ręką przerzucił wielki + wyłącznik i niemal natychmiast głosem lekko ochrypłym, lecz emanującym + dziwnie sugestywnym czarem, maszyna rzekła:

+ +

– Chrzęskrzyboczek pacionkociewiczarokrzysztofoniczmy.

+

– Czy to już wszystko? – spytał po dłuższej chwili niezwykle uprzejmy + Klapaucjusz.

+

(Stanisław Lem, „Cyberiada”, „Wyprawa pierwsza A, czyli Elektrybałt Trurla”)

+
+ + + +

Konkurs startuje 12 września 2011 roku – z okazji 90 rocznicy urodzin +Stanisława Lema. Termin nadsyłania prac upływa z końcem października 10 listopada 2011 roku. +Powinno być dość czasu na dopracowanie swoich pomysłów.

+ +

Konkurs będzie wyglądał następująco:

+ +
    +
  • Do końca października 10 listopada czekamy na zgłoszenia w postaci programów. + Warunkiem dopuszczalności jest udostępnienie kodu źródłowego na wolnej + licencji GNU AGPL + (jak to zrobić?). + Szerzej o tym, czym powinno być złoszenie – + w dziale Technikalia.
  • + +
  • Użycie wolnej licencji nie oznacza, że kod źródłowy musi być + od razu publicznie dostępny. Programy zostaną przez nas + upublicznione – ale dopiero po upłynięciu terminu nadsyłania zgłoszeń. + Uczestnik może oczywiście samodzielnie upublicznić swoje zgłoszenie + wcześniej – odradzamy to jednak ze względu na komplikacje w przypadku + plagiatu.
  • + +
  • Po uruchomieniu nadesłanych przez uczestników programów dla każdego + uczestnika wygenerujemy 20 wierszy, które odeślemy autorowi + programu. Wybierze on 3 z nich, które następnie zostaną + poddane ocenie jury. W składzie jury znajdą się zarówno osoby związane + z programowaniem, jak i przedstawiciele świata kultury.
  • + +
  • Główną nagrodą jest 16-tomowa kolekcja książek Stanisława Lema. + W ramach dodatkowej nagrody podczas zakończenia konkursu + odbędzie się próba odczytania zwycięskich wierszy na głos.
  • + +
+ +

Programy biorące udział w konkursie zostaną też uruchomione +na stronie Turnieju – +internauci będą więc mieli możliwość samodzielnego „wyklikania” sobie własnego +wiersza przy użyciu każdego z nich.

+ +

Powrót do strony głównej

+ +{% endblock %} diff --git a/turniej/templates/pages/rules.html b/turniej/templates/pages/rules.html new file mode 100644 index 0000000..8dce0f5 --- /dev/null +++ b/turniej/templates/pages/rules.html @@ -0,0 +1,74 @@ +{% extends "base.html" %} + +{% block "body" %} + + +

+ +Turniej Elektrybałtów

+

Konkurs automatycznej poezji

+ +
+

Ustaliwszy, w czym rzecz, zwierzchność żeglugi kosmicznej zwróciła się + oficjalnie do Trurla z żądaniem natychmiastowej likwidacji należącego doń + urządzenia, które zakłócało liryką spokój publiczny i zagrażało zdrowiu + pasażerów.

+ +

(Stanisław Lem, „Cyberiada”, „Wyprawa pierwsza A, czyli Elektrybałt Trurla”)

+
+ + + +

Regulamin konkursu

+ + + + +
    +
  • Organizatorem konkursu jest fundacja Nowoczesna Polska.
  • + +
  • Przedmiotem konkursu jest program komputerowy tworzący remiksy literackie + na podstawie utworów znajdujących się w bilbiotece internetowej Wolne Lektury. + Program biorący udział w konkursie musi być udostępniony na wolnej + licencji GNU AGPL + (jak to zrobić?).
  • + +
  • Konkurs trwa od 12 września do 31 października 10 listopada 2011 roku. + Konkurs ma charakter otwarty. Aby wziąć w nim udział udział, + należy wysłać gotowy program na adres + radoslaw.czajka@nowoczesnapolska.org.pl + + z klauzulą: + Zgłaszam się do konkursu „Turniej Elektrybałtów” i oświadczam, że + znam i akceptuję jego regulamin.
  • + +
  • Nagrodą główną jest 16-tomowa kolekcja dzieł Stanisława Lema. Nie ma + możliwości zamiany nagrody na jej równowartość pieniężną.
  • + +
  • Organizator może odwołać konkurs w każdym czasie, bez podawania + przyczyny. W takim przypadku uczestnikom konkursu nie przysługuje żadna + rekompensata. Uczestnicy zgłaszając swój udział w konkursie automatycznie + wyrażają zgodę na publikację ich twórczości w internecie oraz wyrażają + zgodę na wykorzystanie wizerunku w materiałach promocyjnych konkursu + oraz materiałach promocyjnych Fundacji Nowoczesna Polska.
  • + +
  • Organizator zastrzega sobie prawo do odrzucenia zgłoszenia programu, + którego działanie może zagrażać stabilności, responsywności albo bezpieczeństwu + serwera, a także takich, których poprawne uruchomienie okaże się niemożliwe + lub poważnie utrudnione.
  • + +
  • Organizator konkursu nie ponosi odpowiedzialności za wszelkie + roszczenia osób trzecich wynikające z tytułu wykorzystania materiałów + zgłoszonych przez uczestników konkursu jako własnych. Prace naruszające + prawa autorskie będą dyskwalifikowane.
  • + +
  • Organizator zatrzega sobie prawo wprowadzenia zmian w regulaminie + konkursu.
  • +
+ + + + +

Powrót do strony głównej

+ +{% endblock %} diff --git a/turniej/templates/pages/technical.html b/turniej/templates/pages/technical.html new file mode 100644 index 0000000..d236dcf --- /dev/null +++ b/turniej/templates/pages/technical.html @@ -0,0 +1,115 @@ +{% extends "base.html" %} + +{% block "body" %} + +

+ +Turniej Elektrybałtów

+

Konkurs automatycznej poezji

+ +
+

Gdy atoli, z lekka kulejąc, zbliżył się do maszyny, ta, + na widok obcęgów w jego dłoni i błysków desperacji w oku, buchnęła taką + namiętną liryką błagając o łaskę, że rozszlochany Trurl cisnął narzędzia + i wrócił do siebie, brnąc po kolana w nowych utworach elektroducha, które + sięgały mu do pół piersi, zaścielając szemrzącym oceanem papieru całą halę.

+ +

(Stanisław Lem, „Cyberiada”, „Wyprawa pierwsza A, czyli Elektrybałt Trurla”)

+
+ + + +

Wymogi wobec zgłaszanych programów

+ +
    +
  • Nie nakładamy ograniczeń na wybór języka programowania. Program + powinien dać się jednak uruchomić w środowisku GNU/Linux przy użyciu + wolnodostępnych narzędzi.
  • + +
  • Warunkiem dopuszczalności jest udostępnienie kodu źródłowego na wolnej + licencji GNU AGPL + + (jak to zrobić?) + Programy zostaną upublicznione – ale dopiero po upłynięciu terminu + nadsyłania zgłoszeń. Warunek ten oznacza w szczególności, że zgłoszenie + musi zawierać kod źródłowy. Nie wchodzą w grę żadne skompilowane, pośrednie, + zaciemnione wersje – kod powinien zostać udostępniony w takiej postaci, + nad jaką normalnie pracuje programista.
  • + +
  • Program przy tworzeniu wierszy musi w istotny sposób korzystać + z zasobów Wolnych Lektur. Elementy wynikowych tekstów nie mogą być + zaszyte w treści samego programu. Program nie może też korzystać + podczas pracy z innych źródeł informacji – musi być jasne, że program + naprawdę miksuje dostarczoną mu literaturę, a nie odtwarza nagraną + uprzednio taśmę. Nie jest wymagane korzystanie z wszystkich utworów – + program może miksować np. tylko poezję romantyczną albo tylko fragmenty + oznaczone wybranymi motywami literackimi.
  • + +
  • Generowanie wiersza nie powinno trwać więcej niż kilka sekund. + W ramach procesu instalacji programu dopuszczalne (i wskazane!) jest + natomiast uprzednie zgromadzenie niezbędnych informacji wynikających + z analizy tekstów źródłowych. Najlepiej więc dostarczyć dwa programy + (albo jeden z różnymi opcjami uruchomienia) – jeden pobierający utwory, + analizujący je i zapisujący efekty tej analizy, a drugi generujący + wiersze na podstawie zgromadzonej uprzednio informacji. Sądzimy, że + ok. 10MiB powinno wystarczyć każdemu + [sic!], + ale w razie potrzeby będziemy się starali być elastyczni.
  • + +
  • Program powinien wypisać wiersz na standardowe wyjście w postaci + czystego tekstu, najlepiej używając kodowania UTF-8 (czyli tego samego, + które jest używane w plikach źródłowych).
  • + +
  • Maksymalna długość wiersza wynosi 1000 znaków – dalsze znaki zostaną + odcięte. Poza tym ograniczeniem długość i forma wiersza pozostaje w gestii + autora i jego programu.
  • + +
  • Odrzucone zostana programy, które będą usiłowały w jakikolwiek + sposób zagrozić stabilności lub bezpieczeństwu serwera.
  • +
+ + +

W jaki sposób pobierać utwory?

+ +

Źródłowe utwory można pobierać na kilka sposobów:

+ + + +

Wszystkie pliki źródłowe są zapisane przy użyciu kodowania UTF-8.

+ +

Przykładowy program (napisany w Pythonie), obrazujący wykorzystanie +każdego z tych sposobów, można znaleźć +w naszym repozytorium na GitHubie. +Jest to po prostu Leśmianator – w wersji przygotowanej zgodnie z warunkami +turnieju.

+ + +

Gdzie wysyłać zgłoszenia?

+ +

Zgłoszenia, a także wszelkiego rodzaju pytania i wątpliwości prosimy kierować na adres +radoslaw.czajka@nowoczesnapolska.org.pl. +Prosimy też o dołączenie do każdego zgłoszenia klauzuli o treści: +Zgłaszam się do konkursu „Turniej Elektrybałtów” i oświadczam, że +znam i akceptuję jego regulamin. + +

+ + + + +

Powrót do strony głównej

+ + +{% endblock %} + diff --git a/turniej/urls.py b/turniej/urls.py new file mode 100644 index 0000000..2a2a2f1 --- /dev/null +++ b/turniej/urls.py @@ -0,0 +1,21 @@ +from django.conf.urls.defaults import patterns, include, url +from django.views.generic.simple import direct_to_template + +# from django.contrib import admin +# admin.autodiscover() + +urlpatterns = patterns('', + url(r'^$', 'turniej.views.home', name='main_page'), + + url(r'^regulamin/$', direct_to_template, {'template': 'pages/rules.html'}, + name='rules_page'), + url(r'^wiecej/$', direct_to_template, {'template': 'pages/more.html'}, + name='more_page'), + url(r'^technikalia/$', direct_to_template, {'template': 'pages/technical.html'}, + name='technical_page'), + + url(r'^poezja/', include('poetry.urls')), + + # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), + # url(r'^admin/', include(admin.site.urls)), +) diff --git a/turniej/views.py b/turniej/views.py new file mode 100644 index 0000000..3fe0a87 --- /dev/null +++ b/turniej/views.py @@ -0,0 +1,6 @@ +from django.shortcuts import render +from poetry.models import Poem + +def home(request): + last = Poem.objects.all().order_by('-created_at')[:10] + return render(request, "home.html", locals())