PhantomJS отображает квадратики вместо русских букв

Если в системе не установлены нужные для сайта шрифты, если их нельзя установить, либо еще по какой-то причине phantomjs показывает вам квадратики, можете попробовать следующий способ.
На сайте, с которым работаем, задать @font-face для всех используемых шрифтов и только после этого читать/фотографировать содержимое страницы. ВНИМАНИЕ! Работает только на версии >= 1.6.

См. пример, здесь БУДУТ квадратики:
[code lang=»html»]
<!DOCTYPE HTML>
<html>
<head>
<title>@font-face demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style type="text/css">
body {
font-family: Arial;
margin: 50px;
}
</style>
</head>
<body>
<p>Тест русского текста.</p>
<p>Если вы видите русский текст, то тест успешно пройден.</p>
</body>
</html>
[/code]
Для запуска можно использовать примерно такую команду:
[code lang=»bash»]
phantomjs rasterize.js http://crusat.ru/demos/fontface/index-no-fontface.html test.png
[/code]

А здесь со шрифтами все будет отлично:
[code lang=»html»]
<!DOCTYPE HTML>
<html>
<head>
<title>@font-face demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style type="text/css">
@font-face {
font-family: Arial;
src: url(arial.ttf) format("truetype");
}
body {
font-family: Arial;
margin: 50px;
}
</style>
</head>
<body>
<p>Тест русского текста.</p>
<p>Если вы видите русский текст, то тест успешно пройден.</p>
</body>
</html>
[/code]
Для запуска можно использовать примерно такую команду:
[code lang=»bash»]
phantomjs rasterize.js http://crusat.ru/demos/fontface/index.html test.png
[/code]

Это самое простое решение, что пришло мне в голову.

Добавляем только несуществующие записи в таблицу (SQL)

Допустим, у нас есть таблица tags такого вида (ниже привожу sql-запрос для ее создания):

[code lang=»sql»]
CREATE TABLE `tags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`tag_name` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`uid` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
[/code]

Ее смысл в том, что для каждого пользователя мы можем задавать отдельный набор тэгов, которые будут отображаться только ему. Кстати, отображать их удобно через jquery UI autocomplete multiple.

Также, когда мы передаем какой то набор сохраняемых тэгов для выбранного пользователя (опустим моменты разрезания, тримминг пробелов и т.д.), мы не хотим, чтобы повторялись одинаковые значения. Этого можно добиться, сделав следующее.

Сначала сделаем уникальный ключ из двух полей — tag_name и uid.
[code lang=»sql»]
ALTER TABLE tags ADD unique index(tag_name,uid);

[/code]

А затем мы можем добавлять несуществующие записи таким образом (обратите внимание на слово IGNORE — оно позволяет не показывать ошибку, когда создаются дубликаты уже существующих записей, а просто пропускать ее):

[code lang=»sql»]
INSERT IGNORE INTO tags(tag_name, uid) VALUES (‘my_tag1’, 1), (‘my_tag2’, 1), (‘мой тэг’, 1)

[/code]

Безопасный eval в python

Об этом уже достаточно много сказано, но может и мой вариант кому-то приглянется. Обычно запрещают список опасных функций для eval’а. Можно пойти чуть по другому пути и наоборот, разрешить, что-то. Я набросал пример, цель которого была — вычисление математических выражений. Чтобы было не так скучно, сделал это в django через аякс 🙂

Итак, views.py
[code lang=»python»]
import re, json
from django.shortcuts import render_to_response
from django.http import HttpResponse

#…

def calc(request):
return render_to_response(‘calc.html’, {})

def calc_json_expression(request):
p = re.compile(r'[-+*\/\(\)0-9(sin)(cos)(tan)]*’, re.IGNORECASE)
calcmath = request.POST["calc-math"]
res = ».join(p.findall(calcmath))
from math import sin, cos, tan
json_data = {}
try:
json_data[‘exp’] = res
json_data[‘res’] = eval(res)
except:
json_data[‘exp’] = »
json_data[‘res’] = ‘0’
return HttpResponse(json.dumps(json_data), mimetype="application/json")
[/code]

urls.py
[code lang=»python»]
urlpatterns = patterns(‘kernel.views’,
# …
url(r’^calc/$’, ‘calc’),
url(r’^calc-json-expression/$’, ‘calc_json_expression’),
)
[/code]

и файл шаблона calc.html
[code lang=»html»]
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>
<h1>Calc</h1>
<form method="post" id="calc-form">
<p><label for="calc-math">Print math expression</label><input type="text" name="calc-math" id="calc-math" value="" placeholder="Expression"></p>
<p>Expression: <span id="calc-math-expression"></span></p>
<p>Result: <span id="calc-math-answer">0</span></p>
</form>

<script type="text/javascript">
$(‘#calc-math’).keyup(function() {
$.post(‘calc-json-expression/’, $("#calc-form").serialize(),function(data){
$(‘#calc-math-answer’).text(data["res"]);
$(‘#calc-math-expression’).text(data["exp"]);
}, "json");
});
</script>
</body>
</html>
[/code]

Самое интересное во всем этом коде — выбор допустимых символов и слов регулярным выражением. Сюда можно добавить и другие выражения, но принцип должен быть понятен.

[code lang=»python»]
p = re.compile(r'[-+*\/\(\)0-9(sin)(cos)(tan)]*’, re.IGNORECASE)
[/code]

Собственно, это и есть мой способ, подобных при поиске «безопасный eval» не увидел. Проблема, с которой столкнулся — это ограничение на время исполнения скрипта. Такой штуки нет ни в джанго, ни в питоне. Поэтому 10 в миллиардной степени, например, этот скрипт не обработает, а сайт просто упадет. Есть решения, интернет ими кишит, но они, в основном, только для *nix, либо практически нерабочие. Если кто-то найдет кроссплатформенный рабочий код — отпишитесь, пожалуйста 🙂