«Статичный» сайт на GAE
В один прекрасный вечер понадобилось сделать статичную копию сайта и разместить ее в сети. Причем сделать, как всегда, нужно было вчера и желательно бесплатно.
Итак, для начала мне нужна статичная копия сайта. Т.к. на локалке у меня всегда актуальная версия скриптов, обновляю базу и с помощью wget -r site.local
получаю копию.
Т.к. в последнее время сильно увлекся питоном и посматриваю в сторону 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.