Merge branch 'db/6255' into db/6255-6277
diff --git a/Allura/allura/model/filesystem.py b/Allura/allura/model/filesystem.py
index 41a64ab..c56e595 100644
--- a/Allura/allura/model/filesystem.py
+++ b/Allura/allura/model/filesystem.py
@@ -20,7 +20,7 @@
 import logging
 
 import pylons
-import Image
+import PIL
 from gridfs import GridFS
 from tg import config
 from paste.deploy.converters import asint
@@ -136,9 +136,9 @@
         if square and height != width:
             sz = max(width, height)
             if 'transparency' in image.info:
-                new_image = Image.new('RGBA', (sz,sz))
+                new_image = PIL.Image.new('RGBA', (sz,sz))
             else:
-                new_image = Image.new('RGB', (sz,sz), 'white')
+                new_image = PIL.Image.new('RGB', (sz,sz), 'white')
             if height < width:
                 # image is wider than tall, so center horizontally
                 new_image.paste(image, ((width-height)/2, 0))
@@ -148,7 +148,7 @@
             image = new_image
 
         if thumbnail_size:
-            image.thumbnail(thumbnail_size, Image.ANTIALIAS)
+            image.thumbnail(thumbnail_size, PIL.Image.ANTIALIAS)
 
         thumbnail_meta = thumbnail_meta or {}
         thumbnail = cls(
@@ -175,9 +175,9 @@
             return None, None
 
         try:
-            image = Image.open(fp)
+            image = PIL.Image.open(fp)
         except IOError as e:
-            log.error('Error opening image %s %s', filename, e)
+            log.error('Error opening image %s %s', filename, e, exc_info=True)
             return None, None
 
         format = image.format
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 9741d3c..79f595e 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -18,9 +18,10 @@
 import re
 import os, allura
 import pkg_resources
-import Image, StringIO
+import StringIO
 from contextlib import contextmanager
 
+import PIL
 from nose.tools import assert_equals
 from ming.orm.ormsession import ThreadLocalORMSession
 
@@ -216,7 +217,7 @@
                     short_description='A Test Project'),
                     upload_files=[upload])
         r = self.app.get('/p/test/icon')
-        image = Image.open(StringIO.StringIO(r.body))
+        image = PIL.Image.open(StringIO.StringIO(r.body))
         assert image.size == (48,48)
 
         r = self.app.get('/p/test/icon?foo=bar')
@@ -236,11 +237,11 @@
         project = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
         filename = project.get_screenshots()[0].filename
         r = self.app.get('/p/test/screenshot/'+filename)
-        uploaded = Image.open(file_path)
-        screenshot = Image.open(StringIO.StringIO(r.body))
+        uploaded = PIL.Image.open(file_path)
+        screenshot = PIL.Image.open(StringIO.StringIO(r.body))
         assert uploaded.size == screenshot.size
         r = self.app.get('/p/test/screenshot/'+filename+'/thumb')
-        thumb = Image.open(StringIO.StringIO(r.body))
+        thumb = PIL.Image.open(StringIO.StringIO(r.body))
         assert thumb.size == (150,150)
         #FIX: home pages don't currently support screenshots (now that they're a wiki);
         # reinstate this code (or appropriate) when we have a macro for that
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index a641f74..c45d50e 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -20,7 +20,7 @@
 from cStringIO import StringIO
 import urllib2
 
-import Image
+import PIL
 from tg import config
 from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
@@ -234,7 +234,7 @@
                           params=dict(name='Mozq1', css='', homepage='# MozQ1'),
                           extra_environ=dict(username='root'), upload_files=[upload])
         r = self.app.get('/adobe/icon')
-        image = Image.open(StringIO(r.body))
+        image = PIL.Image.open(StringIO(r.body))
         assert image.size == (48, 48)
 
         r = self.app.get('/adobe/icon?foo=bar')
@@ -788,7 +788,7 @@
         assert 'Updated description.' in r
         r = self.app.get('/adobe/_admin/awards/%s' % foo_id, extra_environ=dict(username='root'))
         r = self.app.get('/adobe/_admin/awards/%s/icon' % foo_id, extra_environ=dict(username='root'))
-        image = Image.open(StringIO(r.body))
+        image = PIL.Image.open(StringIO(r.body))
         assert image.size == (48, 48)
         self.app.post('/adobe/_admin/awards/grant',
                           params=dict(grant='FOO', recipient='adobe-1'),
diff --git a/Allura/setup.py b/Allura/setup.py
index 983cff0..4a5f4f1 100644
--- a/Allura/setup.py
+++ b/Allura/setup.py
@@ -68,7 +68,6 @@
         "Pygments >= 1.1.1",
         "python-openid >= 2.2.4",
         "EasyWidgets >= 0.1.1",
-        "PIL >= 1.1.7",
         "iso8601",
         "chardet >= 1.0.1",
         "feedparser >= 5.0.1",
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
index d8d460a..a1bc1a2 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
@@ -17,10 +17,10 @@
 
 import os
 import allura
-import Image
 from StringIO import StringIO
 import logging
 
+import PIL
 from alluratest.controller import TestController
 from allura.lib import helpers as h
 
@@ -136,7 +136,7 @@
                                   },
                           upload_files=[upload]),
         r = self.app.get('/discussion/testforum/icon')
-        image = Image.open(StringIO(r.body))
+        image = PIL.Image.open(StringIO(r.body))
         assert image.size == (48,48)
 
     def test_delete_undelete(self):
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 84b63e5..ef6342e 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -21,9 +21,10 @@
 import os
 import time
 import json
-import Image, StringIO
+import StringIO
 import allura
 
+import PIL
 from mock import patch
 from nose.tools import assert_true, assert_false, assert_equal, assert_in
 from nose.tools import assert_raises, assert_not_in
@@ -543,13 +544,13 @@
         ticket = tm.Ticket.query.find({'ticket_num':1}).first()
         filename = ticket.attachments.first().filename
 
-        uploaded = Image.open(file_path)
+        uploaded = PIL.Image.open(file_path)
         r = self.app.get('/bugs/1/attachment/'+filename)
-        downloaded = Image.open(StringIO.StringIO(r.body))
+        downloaded = PIL.Image.open(StringIO.StringIO(r.body))
         assert uploaded.size == downloaded.size
         r = self.app.get('/bugs/1/attachment/'+filename+'/thumb')
 
-        thumbnail = Image.open(StringIO.StringIO(r.body))
+        thumbnail = PIL.Image.open(StringIO.StringIO(r.body))
         assert thumbnail.size == (100,100)
 
     def test_sidebar_static_page(self):
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 1baa28b..131724c 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -18,12 +18,12 @@
 #       under the License.
 
 import os
-import Image, StringIO
+import StringIO
 import allura
 import json
 
+import PIL
 from nose.tools import assert_true, assert_equal, assert_in
-
 from ming.orm.ormsession import ThreadLocalORMSession
 from mock import patch
 
@@ -379,13 +379,13 @@
         page = model.Page.query.find(dict(title='TEST')).first()
         filename = page.attachments.first().filename
 
-        uploaded = Image.open(file_path)
+        uploaded = PIL.Image.open(file_path)
         r = self.app.get('/wiki/TEST/attachment/'+filename)
-        downloaded = Image.open(StringIO.StringIO(r.body))
+        downloaded = PIL.Image.open(StringIO.StringIO(r.body))
         assert uploaded.size == downloaded.size
         r = self.app.get('/wiki/TEST/attachment/'+filename+'/thumb')
 
-        thumbnail = Image.open(StringIO.StringIO(r.body))
+        thumbnail = PIL.Image.open(StringIO.StringIO(r.body))
         assert thumbnail.size == (255,255)
 
         # Make sure thumbnail is present
diff --git a/README.markdown b/README.markdown
index 4284960..55b6c13 100644
--- a/README.markdown
+++ b/README.markdown
@@ -36,11 +36,9 @@
 
 # Installation
 
-Before we begin, you'll need to install some system packages.  [Use google if you need additional PIL/jpeg help.](http://www.google.com/search?q=ubuntu+pil+jpeg+virtualenv)
+Before we begin, you'll need to install some system packages.
 
     ~$ sudo aptitude install git-core default-jre-headless python-dev libssl-dev libldap2-dev libsasl2-dev libjpeg8-dev zlib1g-dev
-    ~$ sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib
-    ~$ sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib
 
 To install MongoDB 2.2.3, follow the instructions here:
 
diff --git a/requirements-common.txt b/requirements-common.txt
index 2b5f8b5..8005d81 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -28,7 +28,7 @@
 Paste==1.7.5.1
 PasteDeploy==1.5.0
 PasteScript==1.7.4.2
-PIL==1.1.7
+Pillow==2.0.0
 poster==0.8.1
 Pygments==1.5
 pymongo==2.4.2
diff --git a/scripts/rethumb.py b/scripts/rethumb.py
index 0cae31c..5f753ff 100644
--- a/scripts/rethumb.py
+++ b/scripts/rethumb.py
@@ -19,7 +19,7 @@
 import time
 
 import pkg_resources
-import Image
+import PIL
 import tg
 from pylons import tmpl_context as c
 from paste.deploy.converters import asint
@@ -55,7 +55,7 @@
                 base.log.warning("There are %d thumbnails for '%s' - consider clearing them with --force", count, attachment.filename)
                 return
 
-            image = Image.open(attachment.rfile())
+            image = PIL.Image.open(attachment.rfile())
             del doc['content_type']
             del doc['filename']
             att_cls.save_thumbnail(attachment.filename, image, attachment.content_type, att_cls.thumbnail_size, doc, square=True)
@@ -133,4 +133,3 @@
     command = RethumbCommand('rethumb')
     command.parse_args(sys.argv)
     command.command()
-
diff --git a/vagrant/manifests/ubuntu-1204-server-amd64.pp b/vagrant/manifests/ubuntu-1204-server-amd64.pp
index 950f2af..be00025 100644
--- a/vagrant/manifests/ubuntu-1204-server-amd64.pp
+++ b/vagrant/manifests/ubuntu-1204-server-amd64.pp
@@ -45,17 +45,6 @@
     require => Exec[ "package index update" ],
 }
 
-file { '/usr/lib/libz.so':
-  ensure => 'link',
-  target => '/usr/lib/x86_64-linux-gnu/libz.so',
-  require => Package[ "zlib1g-dev" ],
-}
-file { '/usr/lib/libjpeg.so':
-  ensure => 'link',
-  target => '/usr/lib/x86_64-linux-gnu/libjpeg.so',
-  require => Package[ "libjpeg8-dev" ],
-}
-
 # install python pip
 exec { "install venv":
   command => "/usr/bin/pip install virtualenv",
@@ -115,7 +104,6 @@
   returns => 0,
   tries => 3,
   require => [ Exec[ "clone repo"], Exec[ "create allura venv" ],
-               File["/usr/lib/libjpeg.so"], File["/usr/lib/libz.so"],
                ],
 }