From: Ɓukasz Rekucki Date: Thu, 15 Oct 2009 16:28:32 +0000 (+0200) Subject: Merge branch 'master' of stigma:platforma X-Git-Url: https://git.mdrn.pl/redakcja.git/commitdiff_plain/39d26aa0f2cb893f19282657b2fddd2a494f2263?hp=c6fc086238de9fefb56169edc148bbcd3ff866fa Merge branch 'master' of stigma:platforma --- diff --git a/.gitignore b/.gitignore index c91e29e0..9fa4e403 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,17 @@ localsettings.py dev.sqlite +requirements.pybundle + +# Python garbage *.pyc -.*.swp +.coverage + +# Mac OS X garbage .DS_Store -media -files + +# Windows garbage +thumbs.db + +# Netbeans garbage nbproject -nbproject/* -.coverage +nbproject/* \ No newline at end of file diff --git a/crop.py b/crop.py deleted file mode 100755 index a7d83840..00000000 --- a/crop.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -import sys -import os -from os.path import splitext, dirname, basename, realpath -from PIL import Image - - -def crop(image, top=0, right=0, bottom=0, left=0): - width, height = image.size - if top < 1: - top = int(height * top) - if right < 1: - right = int(width * right) - if bottom < 1: - bottom = int(height * bottom) - if left < 1: - left = int(width * left) - - bounds = (int(left), int(top), int(width - right), int(height - bottom)) - image = image.crop(bounds) - image.load() - return image - - -output_dir = realpath(os.getcwd()) + '/output' -bounds = [float(i) for i in sys.argv[1].split(':')] - -for file_name in sys.argv[2:]: - base_name, ext = splitext(file_name) - try: - image = Image.open(file_name) - except IOError, e: - sys.stderr.write('\nerror:%s:%s\n' % (file_name, e.message)) - continue - - image = crop(image, *bounds) - image.save(output_dir + '/' + basename(file_name)) \ No newline at end of file diff --git a/dump_toolbar.sh b/dump_toolbar.sh deleted file mode 100755 index aede1747..00000000 --- a/dump_toolbar.sh +++ /dev/null @@ -1 +0,0 @@ -./project/manage.py dumpdata --format=xml toolbar | xmllint --format - > apps/toolbar/fixtures/przyciski.xml diff --git a/fabfile.py b/fabfile.py index 5f9cd3fe..8b55e587 100644 --- a/fabfile.py +++ b/fabfile.py @@ -1,20 +1,158 @@ -from __future__ import with_statement +from __future__ import with_statement # needed for python 2.5 +from fabric.api import * -from fabric.api import run, env, cd +import os + +# ========== +# = Config = +# ========== +# Globals +env.project_name = 'platforma' +env.use_south = False + +# Servers def staging(): - '''Add staging server to hosts''' - env.hosts = ['platforma@stigma.nowoczesnapolska.org.pl:2222'] - env.project_dir = '/home/platforma/platforma' + """Use staging server""" + env.hosts = ['stigma.nowoczesnapolska.org.pl:2222'] + env.user = 'zuber' + env.path = '/var/services/platforma' + env.python = '/usr/bin/python' + env.virtualenv = '/usr/bin/virtualenv' + env.pip = '/usr/bin/pip' + +def production(): + """Use production server""" + env.hosts = ['wolnelektury.pl:22123'] + env.user = 'fundacja' + env.path = '/opt/lektury/platforma' + env.python = '/opt/lektury/basevirtualenv/bin/python' + env.virtualenv = '/opt/lektury/basevirtualenv/bin/virtualenv' + env.pip = '/opt/lektury/basevirtualenv/bin/pip' + + +# ========= +# = Tasks = +# ========= +def test(): + "Run the test suite and bail out if it fails" + require('hosts', 'path', provided_by=[staging, production]) + 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 and pip should be already installed. + """ + require('hosts', 'path', provided_by=[staging, production]) + + run('mkdir -p %(path)s; cd %(path)s; %(virtualenv)s --no-site-packages .;' % env, pty=True) + run('cd %(path)s; mkdir releases; mkdir shared; mkdir packages;' % env, pty=True) + run('cd %(path)s/releases; ln -s . current; ln -s . previous' % env, pty=True) + deploy() def deploy(): - '''Deploy server''' - with cd(env.project_dir): - run('git pull') - run('./project/manage.py syncdb') - restart_server() + """ + 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 + """ + require('hosts', 'path', provided_by=[staging, production]) + + import time + env.release = time.strftime('%Y-%m-%dT%H%M') + + upload_tar_from_git() + upload_pybundle() + install_requirements() + symlink_current_release() + migrate() + restart_webserver() + +def deploy_version(version): + "Specify a specific version to be made live" + require('hosts', 'path', provided_by=[localhost,webserver]) + 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', provided_by=[staging, production]) + require('path') + 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 master branch and upload it" + print '>>> upload tar from git' + require('release', provided_by=[deploy]) + local('git archive --format=tar master | gzip > %(release)s.tar.gz' % 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 install_requirements(): + "Install the required packages from the requirements file using pip" + print '>>> install requirements' + require('release', provided_by=[deploy]) + run('cd %(path)s; %(pip)s install -E . requirements.pybundle' % env) + +def upload_pybundle(): + "Create pybundle with required libraries and upload it" + print ">>> upload pybundle" + require('release', provided_by=[deploy]) + with settings(warn_only=True): + pip_options = run('cat %(path)s/releases/%(release)s/pip-options.txt' % env) + if pip_options.failed: + env.pip_options = '' + else: + env.pip_options = pip_options + + requirements_mtime = os.path.getmtime('requirements.txt') + bundle_mtime = 0 + try: + bundle_mtime = os.path.getmtime('requirements.pybundle') + except os.error: + pass + + if requirements_mtime > bundle_mtime: + local('pip bundle requirements.pybundle %(pip_options)s -r requirements.txt' % env) + put('requirements.pybundle', '%(path)s' % env) + +def symlink_current_release(): + "Symlink our current release" + print '>>> symlink current release' + require('release', provided_by=[deploy]) + require('path', provided_by=[staging, production]) + with cd(env.path): + run('rm releases/previous; mv releases/current releases/previous') + run('ln -s %(release)s releases/current' % env) -def restart_server(): - with cd(env.project_dir): - run('touch project/dispatch.wsgi') +def migrate(): + "Update the database" + print '>>> migrate' + require('project_name', provided_by=[staging, production]) + with cd('%(path)s/releases/current/%(project_name)s' % env): + run('../../../bin/python manage.py syncdb --noinput' % env, pty=True) + if env.use_south: + run('../../../bin/python manage.py migrate' % env, pty=True) +def restart_webserver(): + "Restart the web server" + print '>>> restart webserver' + run('touch %(path)s/releases/current/%(project_name)s/%(project_name)s.wsgi' % env) diff --git a/imgconv.py b/imgconv.py deleted file mode 100755 index ce514b32..00000000 --- a/imgconv.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python -import sys -import os -import shutil -from os.path import splitext, dirname, basename, realpath -from PIL import Image, ImageFilter, ImageEnhance, ImageOps - - -def resize(image, max_width, max_height): - """Resize image so it's not wider than max_width and not higher than max_height.""" - width, height = image.size - ratio = max(1.0, float(width) / max_width, float(height) / max_height) - new_width, new_height = int(width / ratio), int(height / ratio) - return image.resize((new_width, new_height), Image.ANTIALIAS) - - -def crop(image, ratio, from_right=False): - """Crop image to ratio of current width.""" - width, height = image.size - new_width = width * ratio - if from_right: - bounds = (int(width - new_width), 0, int(width), int(height)) - else: - bounds = (0, 0, int(new_width), int(height)) - image = image.crop(bounds) - image.load() - return image - - -def ratio(image): - """Return width to height ratio of image.""" - width, height = image.size - return float(width) / height - - -def try_creating(directory): - try: - os.mkdir(directory) - except: - pass - - -output_dir = realpath(os.getcwd()) + '/output' -# big_output_dir = output_dir + '/big' -tmp_output_dir = output_dir + '/tmp' - -try_creating(output_dir) -# try_creating(big_output_dir) -try_creating(tmp_output_dir) - - -for file_name in sys.argv[1:]: - base_name, ext = splitext(file_name) - try: - image = Image.open(file_name) - except IOError, e: - sys.stderr.write('\nerror:%s:%s\n' % (file_name, e.message)) - continue - - # Check ratio - if ratio(image) > 1: - images = [crop(image, 0.6), crop(image, 0.6, from_right=True)] - else: - images = [image] - - for i, image in enumerate(images): - image_name = '%s.%d.png' % (basename(base_name), i) - - # Save files - small_image = resize(image, 640, 960) - small_image = small_image.convert('L') - small_image = ImageOps.autocontrast(small_image, cutoff=85) - # small_image = small_image.filter(ImageFilter.SHARPEN) - small_image.save(tmp_output_dir + '/' + image_name) - - os.system('pngnq -n 128 -s 1 -e .png -d "%s" -f "%s"' % ( - output_dir, - tmp_output_dir + '/' + image_name, - )) - os.remove(tmp_output_dir + '/' + image_name) - - # big_image = resize(image, 960, 1440) - # big_image = big_image.convert('L') - # big_image = big_image.filter(ImageFilter.SHARPEN) - # big_image.save(tmp_output_dir + '/' + image_name, optimize=True) - # os.system('pngnq -n 16 -s 1 -e .png -d "%s" -f "%s"' % ( - # big_output_dir, - # tmp_output_dir + '/' + image_name, - # )) - # os.remove(tmp_output_dir + '/' + image_name) - - sys.stderr.write('.') - -shutil.rmtree(tmp_output_dir) diff --git a/pip-options.txt b/pip-options.txt new file mode 100644 index 00000000..a0993cec --- /dev/null +++ b/pip-options.txt @@ -0,0 +1 @@ +-f http://redmine.nowoczesnapolska.org.pl/projects/librarian/files \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index bff92e57..972644b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -Django==1.1 -django-piston==0.2.3rc1 -librarian==1.2.2 +Django==1.1.1 +-e hg+ssh://hg@bitbucket.org/jespern/django-piston/#egg=django-piston +librarian==1.2.6 lxml==2.2.2 mercurial==1.3.1 -e git://github.com/zuber/django-cas-consumer.git#egg=django-cas-consumer \ No newline at end of file diff --git a/scripts/crop.py b/scripts/crop.py new file mode 100755 index 00000000..a7d83840 --- /dev/null +++ b/scripts/crop.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +import sys +import os +from os.path import splitext, dirname, basename, realpath +from PIL import Image + + +def crop(image, top=0, right=0, bottom=0, left=0): + width, height = image.size + if top < 1: + top = int(height * top) + if right < 1: + right = int(width * right) + if bottom < 1: + bottom = int(height * bottom) + if left < 1: + left = int(width * left) + + bounds = (int(left), int(top), int(width - right), int(height - bottom)) + image = image.crop(bounds) + image.load() + return image + + +output_dir = realpath(os.getcwd()) + '/output' +bounds = [float(i) for i in sys.argv[1].split(':')] + +for file_name in sys.argv[2:]: + base_name, ext = splitext(file_name) + try: + image = Image.open(file_name) + except IOError, e: + sys.stderr.write('\nerror:%s:%s\n' % (file_name, e.message)) + continue + + image = crop(image, *bounds) + image.save(output_dir + '/' + basename(file_name)) \ No newline at end of file diff --git a/scripts/dump_toolbar.sh b/scripts/dump_toolbar.sh new file mode 100755 index 00000000..aede1747 --- /dev/null +++ b/scripts/dump_toolbar.sh @@ -0,0 +1 @@ +./project/manage.py dumpdata --format=xml toolbar | xmllint --format - > apps/toolbar/fixtures/przyciski.xml diff --git a/scripts/imgconv.py b/scripts/imgconv.py new file mode 100755 index 00000000..ce514b32 --- /dev/null +++ b/scripts/imgconv.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +import sys +import os +import shutil +from os.path import splitext, dirname, basename, realpath +from PIL import Image, ImageFilter, ImageEnhance, ImageOps + + +def resize(image, max_width, max_height): + """Resize image so it's not wider than max_width and not higher than max_height.""" + width, height = image.size + ratio = max(1.0, float(width) / max_width, float(height) / max_height) + new_width, new_height = int(width / ratio), int(height / ratio) + return image.resize((new_width, new_height), Image.ANTIALIAS) + + +def crop(image, ratio, from_right=False): + """Crop image to ratio of current width.""" + width, height = image.size + new_width = width * ratio + if from_right: + bounds = (int(width - new_width), 0, int(width), int(height)) + else: + bounds = (0, 0, int(new_width), int(height)) + image = image.crop(bounds) + image.load() + return image + + +def ratio(image): + """Return width to height ratio of image.""" + width, height = image.size + return float(width) / height + + +def try_creating(directory): + try: + os.mkdir(directory) + except: + pass + + +output_dir = realpath(os.getcwd()) + '/output' +# big_output_dir = output_dir + '/big' +tmp_output_dir = output_dir + '/tmp' + +try_creating(output_dir) +# try_creating(big_output_dir) +try_creating(tmp_output_dir) + + +for file_name in sys.argv[1:]: + base_name, ext = splitext(file_name) + try: + image = Image.open(file_name) + except IOError, e: + sys.stderr.write('\nerror:%s:%s\n' % (file_name, e.message)) + continue + + # Check ratio + if ratio(image) > 1: + images = [crop(image, 0.6), crop(image, 0.6, from_right=True)] + else: + images = [image] + + for i, image in enumerate(images): + image_name = '%s.%d.png' % (basename(base_name), i) + + # Save files + small_image = resize(image, 640, 960) + small_image = small_image.convert('L') + small_image = ImageOps.autocontrast(small_image, cutoff=85) + # small_image = small_image.filter(ImageFilter.SHARPEN) + small_image.save(tmp_output_dir + '/' + image_name) + + os.system('pngnq -n 128 -s 1 -e .png -d "%s" -f "%s"' % ( + output_dir, + tmp_output_dir + '/' + image_name, + )) + os.remove(tmp_output_dir + '/' + image_name) + + # big_image = resize(image, 960, 1440) + # big_image = big_image.convert('L') + # big_image = big_image.filter(ImageFilter.SHARPEN) + # big_image.save(tmp_output_dir + '/' + image_name, optimize=True) + # os.system('pngnq -n 16 -s 1 -e .png -d "%s" -f "%s"' % ( + # big_output_dir, + # tmp_output_dir + '/' + image_name, + # )) + # os.remove(tmp_output_dir + '/' + image_name) + + sys.stderr.write('.') + +shutil.rmtree(tmp_output_dir)