«Статичный» сайт на GAE

30 марта 2011 г.

В один прекрасный вечер понадобилось сделать статичную копию сайта и разместить ее в сети. Причем сделать, как всегда, нужно было вчера и желательно бесплатно.

Итак, для начала мне нужна статичная копия сайта. Т.к. на локалке у меня всегда актуальная версия скриптов, обновляю базу и с помощью wget -r site.local получаю копию.

Логотип GAE
Т.к. в последнее время сильно увлекся питоном и посматриваю в сторону GAE, вопроса — «где размешать» у меня не было.

Написав простенький скрипт на питоне, который, в зависимости от урла брал хтмл с диска, немного изменял ссылки, в зависимости от того на каком хосте мы сейчас, и показывал его человеку. Но нажимая на deploy я ожидал, что так просто быть не может и не ошибся — GAE не позволяет грузить больше 3000 файлов. А у меня их сильно больше.

Конечно есть Blobstore! Начал усиленно гуглить как по быстрому закинуть в него тысячи файлов. И ничего не нагуглил. Начинаю понимать, что забиваю гвоздь микроскопом, но остановиться уже не могу.

И тут меня осенило. Если нельзя закинуть все тысячи нужных файлов то можно их зазиповать! Зипую, переписываю скрипт так, что бы нужный хтмл доставался из зипа, deploy. И снова облом — максимальный размер файла который можно закачивать 10 мегабайт.

Ну не беда, разобъем архив на части. Создаю архив zip -s9. Но его почему-то не понимает zipfile. Немного погуглив я нашел замечательную утилиту — zipsplit, которой и порубил большой зип файл на части нужного мне размера.

Deploy и о чудо. Все рабоатет.

Собственно вот тот класс c динственным методом который делает заказчика счастливым.

class MainHandler(webapp.RequestHandler):
    def get(self, reqPath):
        if len(reqPath) == 0 or reqPath[len(reqPath) - 1] == '/': #дело в том что wget -r при закачке файла / сохраняет его как index.html
           reqPath += 'index.html'
        tpl = memcache.get(reqPath) #смотрим есть ли в кеше нужная нам страница
        if tpl:
            self.response.out.write(tpl)
        else:
            for n in range(1,8): # у меня получилось 8 зип файлов нужно по очереди пройтись по ним и найти нужный нам файл
                me = zipfile.ZipFile(os.path.dirname(__file__) + '/tpl'+str(n)+'.zip', 'r')
                try:
                    tpl = me.read(reqPath) #достаем нужную нам страницу
                    me.close()
                    break
                except KeyError:
                    me.close()
                    continue
            if tpl:  # если страница нашлась показываем и сохраняем в кеше страницу
                tpl = tpl.replace('old.url', os.environ['SERVER_NAME'])
                memcache.set(reqPath, tpl, 1200)
                self.response.out.write(tpl)
            else: # если нет редиректим на 404 ошибку
                self.redirect('/404/')

И да, я против забивания гвоздей микроскопом. Но в академических целях — можно.
Цель данной статьи показать что на каждую хитрую жопу как обойти ограничения на количество и объем файлов в GAE.

Теги: рубрика Сайтостроение