• Как проверить загружаемый на сервер файл (.doc, .rtf) на вредоносный код?

    Sardar
    @Sardar
    Логика изначально не правильная. Загрузить можно что угодно, но нужно запретить исполнение файла вашим сервером. На самом деле исполнение зловреда на сервере достаточно редкое явление, если только вы не любите подключать счетчики от третьих лиц к себе в страницы через include с левого URL и если вы не любите размещать загруженные файлы с файлами вашего движка в одном месте.

    Также под статичные файлы желательно завести отдельный домен (желательно 2ого уровня) и не принимать файлы, content-type которых вы не сможете распознать (например по расширению). Это нужно не для вас, а для ваших посетителей. Тогда даже если вы пропустите <script src="/url/to/image.png">, то браузер при взгляде на заголовок Content-type = "image/png" не станет выполнять скрипт (убедитесь, что ваш сервер всегда высылает Content-type). Ну и наконец, если все пошло не так и скрипт все таки выполнился у клиента, то размещение на отдельной домене не позволит украсть куку с сессией. Впрочем позволит, если вы размещаете куки на *.domain.com, а статику на static.domain.com. Безопасность это вообще обширная тема.
    Ответ написан
    1 комментарий
  • Какой выбрать диспетчер очередей?

    Sardar
    @Sardar
    Вам подойдет RabbitMQ. Хотя "возможность ставить задачу на паузу" это требование не к диспетчеру сообщений, как и "Склейка одинаковых задач". Для выполнения первого условия можно использовать в логике задачи любой конфигуратор, тот же ZooKeeper. Смысл в проверке конфига и уведомлениях, если опция "пауза задачи Х" выставлена, то всем отписаться от очереди. Второе решается в логике задачи - выполнить всю работу по первому уведомлению, игнорируя все остальные.
    Ответ написан
    Комментировать
  • Python Web: Multiprocessing vs Threads. Что лучше использовать для парсинга?

    Sardar
    @Sardar
    Можно использовать Scrapy. Вам тогда не придется думать о параллельных процессах, блокировках и IO в целом. Вы просто пишете логику разбора страницы. Сам проект на Twisted.
    Ответ написан
    Комментировать
  • Как определить текущего пользователя из модели?

    Sardar
    @Sardar
    Нет, default там не нужен. Скорее всего User у вас из django.contrib.auth.models.User. А это значит, что у вас стоит AuthenticationMiddleware. А это значит, что у вас есть пользователь request.user, попробуйте его напечатать из вашего view. Значит вы можете post.author = request.user

    Ваша форма скорее всего не включает поле с пользователем, а значит сохранять надо как post = form.save(commit=False), чтобы форма записала данные в post, но не пыталась его сохранить. Потом вы присваиваете пользователя.

    А вообще, стоило бы полностью пройти туториал.
    Ответ написан
    5 комментариев
  • Какую архитектуру создать для написания сервера статистики на Ruby?

    Sardar
    @Sardar
    Мне тут посоветовали Scribe для быстрого сбора событий. Используется facebook'ом, объемы статистики которого малыми не назвать. Scribe может очень быстро принять сообщение, а затем сбрасывать его произвольное время на другой Scribe сервер или в локальный файл. Таким образом отослать событие "ничего" не стоит по времени. События могут быть внутренние (открытие страницы) или принятые от вашего плеера/приложения (play/pause) через (REST) API. Во втором случае лучше не использовать тяжелый стек RoR, а взять что-то крайне легковесное. Ведь там не будет никакой логики, принять данные и сразу в Scribe. Я бы сделал на чистом python/WSGI.

    В идеале поставить по scribe процессу на каждый app. сервер, которые будут сливать события на единый выделенный scribe сервер, сливающий все в набор файлов. На этом же сервере можно поставить любую аналитику, которая на вход получит большие файлы с логами, а на выходе необходимую вам статистику (можно на map-reduce, можно и попроще). Ротацию файлов можно поставить на 10 минут, scribe сам за вас их крутит. Готовые агрегаты сливаются в любую БД, скорость ее работы не принципиальна, ведь они пойдут на графики для узкого круга людей.
    Ответ написан
    Комментировать
  • PHP + ZeroMQ, как не потерять сообщения, если PULL-воркер упал?

    Sardar
    @Sardar
    Может стоит использовать persistent очередь, вроде RabbitMQ? Нет ограничений на размер сообщений и они сохраняются, пока не будут употреблены. При чем сообщение резервируется, пока worker выполняет задачу и либо удаляется из очереди при успешном завершении, либо возвращается в очередь, если worker по тихому умер.
    Ответ написан
    Комментировать
  • SQL запрос из нескольких ARCHIVE таблиц с общим ORDER BY?

    Sardar
    @Sardar
    Acrhive база это всегда full table scan. Зато они очень быстрые на добавление. Любое выражение ORDER BY на такой таблице это merge sort со сливом во временные файлы кучи данных (по сути построение индекса на лету), а значит долго. UNION ALL не будет будет сортировать несколько выборок сразу, он просто соединяет результаты. С другой стороны, все ваши таблицы содержат данные только одного интервала, а значит все записи таблицы со старшей датой будут старше записей любой другой младшей таблицы. Тогда просто UINION ALL всех таблиц в порядке даты даст вам нужный результат.
    Ответ написан
    Комментировать
  • Как SQL запросом узнать историю изменения данных?

    Sardar
    @Sardar
    SELECT t.id, COUNT(*), SUM(t.ct)
    FROM (SELECT l.id, y.value, COUNT(*) as ct
        FROM links l
        INNER JOIN history_yap y ON l.link_id = y.link_id
        GROUP BY l.id, y.value) t
    GROUP BY t.id
    UNION ALL
    SELECT l.id, -1, -1
    FROM links l
    LEFT JOIN history_yap y ON l.link_id = y.link_id
    WHERE y.id IS NULL;


    Логика почти та же, но во внутреннем запросе мы также считаем сколько всего было записей в links X history_yap. Также добавлен второй запрос на ссылки без каких либо записей в history_yap. В результате имеем таблицу с тремя колонками:
    * link.id - искомое
    * количество уникальных значений. Если -1, то в history_yap для этого links.id не было ни одной записи. Если больше 1, то есть минимум два history_yap для этой ссылки с разными значениями. Если 1, то смотрим на третью колонку.
    * количество строк в links X history_yap для каждого links.id. Если во второй колонке 1 и в третьей колонке 1, то для этого links.id есть всего одна запись history_yap. Все остальные значения игнорируем.

    P.S. ответил новым постом, т.к. в комментариях код не добавить.
    Ответ написан
  • Как SQL запросом узнать историю изменения данных?

    Sardar
    @Sardar
    SELECT t.id, COUNT(*)
    FROM (SELECT l.id, y.value
        FROM links l
        INNER JOIN history_yap y ON l.link_id = y.link_id
        GROUP BY l.id, y.value) t
    GROUP BY t.id
    HAVING COUNT(*) > 1;


    Требуются индексы на link_id для быстрой работы. Логика:
    * выбрать все ссылки и их историю изменений, нас интересуют уникальные значения. Этот внутренний select можно дополнить where, выбирающий строки только с определенного времени.
    * полученную таблицу снова группируем по id, получаем ссылку и количество уникальных значений.
    * дополняем условием "если уникальных значений больше 1", а значит было изменение.

    Запрос видит только изменения с одного значения на другое. Моменты когда ссылка была добавлена в links, а также первую запись истории в history_yap запрос не видит.
    Ответ написан
  • Изучаю python для последующего освоения django. Где искать скринкасты?

    Sardar
    @Sardar
    Для Django нужны лишь базовые навыки питона (функции, классы, import'ы). Просто начните с документации.

    Если хочется разобраться с этой кухней, то может стоит посмотреть на Pyramid? Подробная документация по поводу веб проектов, множество скрытых аспектов оговариваются явно. В отличии от Django потребуется чуть больше времени на документацию, но после этого внутреннее устройство любого другого фреймворка становится очевидным.
    Ответ написан
    Комментировать
  • Переходить с CodeIgniter или нет?

    Sardar
    @Sardar
    не понимаю выигрыш от того что их можно не писать руками

    Есть множество других аспектов у работы с БД, кроме как выборка данных. ORM обычно обвязан кучей смежных возможностей. К примеру schema migrations – автоматическое изменение таблиц под последнюю версию. На подобии того как git/mercurial/etc держат версии вашего кода, также должны быть версии вашей БД, с помощью которых можно выкатывать обновления или возвращаться назад. Помимо миграций есть архивы, утилиты для заполнения тестовыми данными и прочее-прочее.

    Если хочется попробовать чего-то нового, то попробуйте Django. Да, это python. Для смелых можно Pyramid. Питон сам по себе очень гибкий с его мета-программированием. Вам больше не нужно генерить файлы с кодом или держать кеш под автоматически сгенерированный код. Нет глобального namespace, где неизвестным образом появляются классы, следовательно нет танцев с class loaders и всегда ясно откуда и что пришло - это очень повышает ясность кода. Любые объекты самоописываются, так, что можно получить веб-формы из ORM моделей, автоматическая валидация, generic views (django view == контроллер для всего остального мира) и многое другое. Автоматическая админка. Хороший асинхронный фреймворк в лице Celery. Неплохое управление на management commands, которые легко пишутся. Вместе с Fabric уходит головная боль с выкатыванием новых версий на тестовые и боевые сервера. В общем batteries included.
    Ответ написан
    1 комментарий
  • Генерация JSON с вложенными объектами

    Sardar
    @Sardar
    Вас чем-то не устраивает

    SELECT ... FROM posts p JOIN users u ON u.userid = p.userid

    или, быть может, я не понял вопроса?
    Ответ написан
    2 комментария
  • Чудеса с BLOWFISH внутри JSON

    Sardar
    @Sardar
    JSON парсер может отваливаться в тихую, если не может распознать кодировку. Тем более в закодированных данных в конце padding из \0, что совсем не текст. Упакуй в base64.

    Чем читаешь? В браузере?
    Ответ написан
    2 комментария
  • OpenSSL: подписать корневой сертифкат?

    Sardar
    @Sardar
    Зачем? У предыдущего истекает срок, его подпись игнорируется. К тому же вы выпускаете корневой CA, которому доверяют по умолчанию при любых условиях.
    Ответ написан
    1 комментарий
  • Что выбрать: primary key или unique для уникального foreign key?

    Sardar
    @Sardar
    Лучше UNIQUE. Это позволит иметь отдельный простой точный id для связной таблицы. Это обычно упрощает работу потом, если придется работать со связной таблицей в параллельных запросах вне serialized транзакций. Лишний индекс для int primary key не проблема.
    Ответ написан
    Комментировать
  • Как визуализировать эволюцию графа?

    Sardar
    @Sardar Автор вопроса
    Спасибо. Я наверное зря не уточнил, мне бы не готовые утилиты, мне бы артикли/методы/алгоритмы для визуализации эволюции/изменения графа. А я это доработаю до своей задачи и напишу необходимый софт.

    Но спасибо за наводки, сейчас покопаюсь в их доке/сорцах/скриншотах.
    Ответ написан
    Комментировать
  • Вопросы по Django

    Sardar
    @Sardar
    > автоматическая сборка статики
    django-staticfiles интегрирован в основной фремворк. Теперь ./manage.py collectstatic собирает статику по всем приложениям в одно место. Все конфигурируемо.

    > валидация в одном месте (серверная и клиентская)
    В стандарном фреймворке нет.

    > проблема с пользователями (расширение профиля)
    Теперь можно привязать произвольную модель с ссылкой на User как профиль. Хотя и раньше неудобств в этом плане не было, разве нет?
    Ответ написан
    2 комментария
  • Идеологически правильный setter?

    Sardar
    @Sardar
    > каждый метод должен быть ответственен за одно действие
    Не надо понимать все так буквально. Не стоит к примеру подключаться к базе, выбирать инфу, закачивать обратно результаты и сливать инфу в лог одной большой простыней в одной функции. Но это не значит, что каждую простейшую операцию (такую как присваивание) нужно выносить в отдельный метод.

    > а в нашем случае исключение кажется не совсем уместным
    Исключение говорит «я не могу выполнить команду», в данном случае не допускаем некорректный ввод. Не надо боятся и экономить на исключениях, это удобный механизм (вплоть до таких задач как остановить map(), но это уже вопрос вкуса). Не важно как глубоко «вложен» вызов до вашей функции/свойства, вы на самом деле этого не знаете и не можете знать.

    Да, ваш сеттер должен проверять ввод и присваивать значение, если оно съедобно, иначе генерить исключение.
    Ответ написан
    2 комментария
  • Когда считать процесс разработки ПО завершенным?

    Sardar
    @Sardar
    «Никогда». При первых итерациях сдается рабочий прототип, как можно быстрей. К 2/3 бюджета проекта обычно прототип уже делает все, что необходимо заказчику. В этот момент лучше всего отбрасывать часть фич, посвящая время тестам и доводке до ума, с энтузиазмом привлекая к этому заказчика, что бы у него не было мыслие «его кидают». Под оставшиеся 1/10 бюджета в конце берут поддержку (не разу не видел, что бы заказчик хотел вывести оставшиеся деньги из бюджета). Все откинутые фичи подробно расписываются и оформляются в v2.0. Если ваша поддержка действительно не лажает, то заказчик будет счастлив и через пол года/год создаст новый бюджет, все повторяется. Вы при этом никогда не переходите через рамки начального бюджета.

    Итог: пока есть идеи, никогда.

    По опыту, что бы сделать заказчика счастливым, не надо боятся откидывать low-priority фичи. А виденье приоритета появляется после первых релизов/прототипов, а не (как ошибочно думает большинство) на этапе дизайна. Откинутые и новые фичи держат проект в развитии постоянно, хоть и с паузами.
    Ответ написан
    Комментировать
  • Что делать с усталостью?

    Sardar
    @Sardar
    Изнуряющая физическая нагрузка. От качаловки и до похода в горы на неделю со всей провизией «на себе». Это приток крови к мозгу, это интерес иным вещам, чем работа. Банально, но вправду работает.

    Бег два раза в неделю тоже держит тонус, но я бы не смог бегать в задымленном городе, потому по ситуации. Вернется сон, вернется душевное равновесие.

    Если вы креативный человек, то бездумное просиживание недели за каким нибудь сериалом наоборот ухудшит ситуацию. Безделье убивает.
    Ответ написан
    Комментировать