<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Записки сумасшедшего админа</title>
	<atom:link href="http://sincore.ru/feed" rel="self" type="application/rss+xml" />
	<link>http://sincore.ru</link>
	<description>Взгляд из-за грани.......</description>
	<lastBuildDate>Mon, 26 Mar 2012 04:02:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MySQL Мигрируем MyISAM Таблицы в InnoDB..</title>
		<link>http://sincore.ru/archives/285</link>
		<comments>http://sincore.ru/archives/285#comments</comments>
		<pubDate>Mon, 26 Mar 2012 03:58:59 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Программирование]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=285</guid>
		<description><![CDATA[Будет интересно тем кому нужно выборочно конвертировать таблицы. Ниже соответствующий скрипт. #!/usr/bin/env python __author__ = 'valor' import MySQLdb class ChangeEngine(object): &#160; &#160; __connection = None &#160; &#160; def __init__(self): &#160; &#160; &#160; &#160; pass &#160; &#160; def run(self): &#160; &#160; &#8230;<p class="read-more"><a href="http://sincore.ru/archives/285">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Будет интересно тем кому нужно выборочно конвертировать таблицы. Ниже соответствующий скрипт.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#!/usr/bin/env python<br />
<br />
__author__ = 'valor'<br />
<br />
import MySQLdb<br />
<br />
class ChangeEngine(object):<br />
<br />
&nbsp; &nbsp; __connection = None<br />
<br />
&nbsp; &nbsp; def __init__(self):<br />
&nbsp; &nbsp; &nbsp; &nbsp; pass<br />
<br />
&nbsp; &nbsp; def run(self):<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; sql = '''<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SHOW TABLE STATUS FROM dbname WHERE Engine &lt;&gt; &quot;InnoDB&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; '''<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; try:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection = MySQLdb.connect(db='dbname', host='*****', user='****', passwd='****')<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cursor = connection.cursor()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cursor.execute(sql)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table_list = cursor.fetchall()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; change_engine_query = '''ALTER TABLE `dbname`.`{0}` ENGINE = InnoDB;'''<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table_count = len(table_list)<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for tables in table_list:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print &quot;convert table. &quot;+ str(tables[0])+&quot; to InnoDB...&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table_name = tables[0]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cursor.execute(change_engine_query.format(table_name))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.commit()<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table_count -= 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print str(table_count) + &quot; - elapsed tables..&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection.close()<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; except MySQLdb.MySQLError as e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print e<br />
<br />
if __name__ == &quot;__main__&quot;:<br />
&nbsp; &nbsp; app = ChangeEngine()<br />
&nbsp; &nbsp; app.run()</div></div>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/285/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux DLNA Server под Debian</title>
		<link>http://sincore.ru/archives/280</link>
		<comments>http://sincore.ru/archives/280#comments</comments>
		<pubDate>Sat, 14 Jan 2012 12:30:57 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[debian]]></category>
		<category><![CDATA[Памятки]]></category>
		<category><![CDATA[Софт]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[DLNA]]></category>
		<category><![CDATA[PS3]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=280</guid>
		<description><![CDATA[Еще одна запись из серии &#171;На память&#187;. Не так давно приобрел себе консоль Sony PlayStation3 и по мимо игровых функций обнаружил, что она может выступать в роли сетевого медеа-плеера, что при наличии FullHD телека и WiFi люто сократит количество проводов &#8230;<p class="read-more"><a href="http://sincore.ru/archives/280">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="PS3" src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/68/PlayStation_3_Logo_neu.svg/667px-PlayStation_3_Logo_neu.svg.png" alt="" width="240" height="101" />Еще одна запись из серии &#171;На память&#187;.</p>
<p>Не так давно приобрел себе консоль Sony PlayStation3 и по мимо игровых функций обнаружил, что она может выступать в роли сетевого медеа-плеера, что при наличии FullHD телека и WiFi люто сократит количество проводов да и вообще удобно..</p>
<p>И так сонька ищет в сети UPnP-DLNA (о том, что такое DLNA прочитайте <a href="http://ru.wikipedia.org/wiki/DLNA">тут</a>) сервера, о том как расшарить контент с ПК в сеть по данной технологии в доках к PS есть только гайд для винды, что для меня не комильфо.. Порывшись в интернетах нарыл  проект <strong><a href="http://minidlna.sourceforge.net/">Minidlna</a></strong>. О том, что его надо бы скачать и скомпилить думаю догадаетесь сами, благо процедура до боли простая.</p>
<p>Единственное, что я в данном случае сделал это собрал .deb пакет для ленивых, скачать его можно <a title="minidlna_1.0.22-1_amd64.deb" href="http://dl.dropbox.com/u/3177253/DEBS/minidlna_1.0.22-1_amd64.deb" target="_blank">тут</a>. Правда пока только для x86-64 <img src='http://sincore.ru/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/280/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Новости &#8212; Java &#8212; Вышла &#8230;</title>
		<link>http://sincore.ru/archives/277</link>
		<comments>http://sincore.ru/archives/277#comments</comments>
		<pubDate>Tue, 06 Dec 2011 21:19:21 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Без рубрики]]></category>

		<guid isPermaLink="false">http://sincore.ru/archives/277</guid>
		<description><![CDATA[Новости &#8212; Java &#8212; Вышла IntelliJ IDEA 11 Вышла IntelliJ IDEA 11. Тихо и незаметно вышла очередная версия IntelliJ IDEA — Java (и не только) IDE от JetBrains. Изменения коснулись буквально всех подсистем: UI, редактор кода, инструменты и инте&#8230; This &#8230;<p class="read-more"><a href="http://sincore.ru/archives/277">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<div class="g-crossposting-att">
<div class="g-crossposting-att-title"><a href="http://www.linux.org.ru/news/java/7099240" target="_blank">Новости &#8212; Java &#8212; Вышла IntelliJ IDEA 11</a></div>
<div class="g-crossposting-att-img" style="float:left"><a href="http://www.linux.org.ru/news/java/7099240" target="_blank"><img src="http://images0-focus-opensocial.googleusercontent.com/gadgets/proxy?container=focus&amp;gadget=a&amp;resize_h=100&amp;url=http%3A%2F%2Fwww.linux.org.ru%2Fphotos%2F71993%3A1500187528.png" /></a></div>
<div class="g-crossposting-att-txt">Вышла IntelliJ IDEA 11. Тихо и незаметно вышла очередная версия IntelliJ IDEA — Java (и не только) IDE от JetBrains. Изменения коснулись буквально всех подсистем: UI, редактор кода, инструменты и инте&#8230;</div>
</div>
<div class="g-crossposting-backlink"><a href="https://plus.google.com/109303071022652359230/posts/VAbz1PwMYbx" target="_blank">This was posted on Google+&hellip;</a></div>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/277/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VLC Mass IP cams transcoding</title>
		<link>http://sincore.ru/archives/267</link>
		<comments>http://sincore.ru/archives/267#comments</comments>
		<pubDate>Fri, 02 Dec 2011 10:24:29 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[debian]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[ip-cams]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[vlc]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=267</guid>
		<description><![CDATA[В общем есть такой тип проектов, в которых используют большое количество ip камер. Как правило это проекты связанные с городской безопасностью. Например http://www.podryad.tv/live_cam/ один из таких проектов.. В данной статье я расскажу как просто и эффективно реализовать подобный сервис. Соответственно &#8230;<p class="read-more"><a href="http://sincore.ru/archives/267">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>В общем есть такой тип проектов, в которых используют большое количество ip камер. Как правило это проекты связанные с городской безопасностью. Например http://www.podryad.tv/live_cam/ один из таких проектов..</p>
<p>В данной статье я расскажу как просто и эффективно реализовать подобный сервис. Соответственно будем считать, что камеры по городу или объекту расставлены, работают и доступны по сети. В данном конкретном случае будут использоваться камеры AXIS различных моделей. Благо интерфейс доступа к потоку у них стандартизирован.</p>
<p>Еще один не маловажный момент это однородность состава камер, я имею ввиду, что важно иметь камеры одного вендора и даже модели это позволит избежать мучений с настройкой и обслуживанием.</p>
<p>Кратко опишу техническую задачу.</p>
<p>Есть некоторое количество камер потоки с которых нужно транслировать на сайт предварительно перекодировав поток с заворачиванием в FLV контейнер. Как дальше оно будет разруливаться не особо важно.</p>
<p>Для решения задачи я взял всем известный проект <a href="http://www.videolan.org/" target="_blank">VideoLan</a> , который является не только прекрасным проигрывателем мультимедиа, но и не менее прекрасным медиа-сервером.</p>
<blockquote><p>Небольшая ремарка по поводу производительности..</p>
<p>Рабочий проект содержащий &gt; 60 камер, обслуживался одним сервером Dell R710 с двумя процессорами Intel Xeon SixCore X5650 @ 2.67GHz c 6Gb RAM при этом потоки принимались на один гигабитный сетевой интерфейс и через такой же отдавались.. Интенсивность потока в среднем 400Mb/s при разрешении картинки в 840х480.. Средняя загрузка системы за 5ть минут составляла примерно 30 единиц.</p></blockquote>
<p>Работать все будет под управлением OS GNU/Debian 6.0. В принципе под другими дистрибутивами наверно будет работать не хуже.</p>
<p>И так начнем. Для начала нужно поставить необходимые пакеты, в частности сам vlc (а точнее vlc-noc) со всеми зависимостями. так же советую подключить репозитории проекта<a href="http://debian-multimedia.org/" target="_blank"> debian-multimedia</a> если вам понадобится кодировать потоки например в h264.</p>
<p>Когда установка будет закончена, надо создать не привилегированного пользователя от имени которого и будет работать vlc.</p>
<p>Теперь собственно о том как настроить и как всем этим управлять..</p>
<p>В VLC есть такая приятная фишка как  VLM, по сути простой стрим лист. возможности которого по настоящему безграничны.</p>
<p>Вот пример такого листа:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">new cam26 broadcast enabled<br />
setup cam26 input http:<span style="color: #000000; font-weight: bold;">//</span>user:<span style="color: #000000; font-weight: bold;">*****@</span>XXX.XXX.XXX.XXX<span style="color: #000000; font-weight: bold;">/</span>axis-cgi<span style="color: #000000; font-weight: bold;">/</span>mjpg<span style="color: #000000; font-weight: bold;">/</span>video.cgi<br />
setup cam26 output <span style="color: #666666; font-style: italic;">#transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream26.flv}</span><br />
control cam26 play<br />
<br />
new cam25 broadcast enabled<br />
setup cam25 input http:<span style="color: #000000; font-weight: bold;">//</span>user:<span style="color: #000000; font-weight: bold;">*****@</span>XXX.XXX.XXX.XXX<span style="color: #000000; font-weight: bold;">/</span>axis-cgi<span style="color: #000000; font-weight: bold;">/</span>mjpg<span style="color: #000000; font-weight: bold;">/</span>video.cgi<br />
setup cam25 output <span style="color: #666666; font-style: italic;">#transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream25.flv}</span><br />
control cam25 play</div></div>
<p>По сути нету ничего сложного, важно, что лист может содержать огромное количество подобных записей.</p>
<p>Немного об опциях транскодинга и вывода.</p>
<p>#transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}</p>
<ul>
<li>vcodec &#8212; собственно видео кодек в нашем случае это флеш кодек.</li>
<li>vb &#8212; видео буфер &#8212; значение подбирается экспериментально, если изображение мигает или сыпется, данный параметр нужно увеличить. Помните, что увеличивая его вы увеличиваете количество пожираемой ОЗУ.</li>
<li>fps &#8212; количество кадров в секунду, советую устанавливать значение равное значению выставленному на камере.. Если сервер транскодинга слабоват, значение можно уменьшить, но и качество соответственно будет хуже.</li>
<li>ab &#8212; аудио буфер &#8212; если планируется трансляция звука.</li>
<li>samplerate &#8212; входная частота дискретизации.</li>
</ul>
<p>{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream25.flv}</p>
<ul>
<li>access &#8212; указывает на тип доступа к потоку, в нашем случае http</li>
<li>mime &#8212; mime тип для транспорта</li>
<li>mux &#8212; мультиплексор, в нашем случае ffmpeg, который будет заворачивать поток в контейнер flv</li>
<li>dst &#8212; собственно url по которому наш поток будет доступен для клиентов.</li>
</ul>
<p>Теперь немного об аргументах с которыми стартует сервер. Вся строка выглядит так :</p>
<p>cvlc -d -q &#8212;pidfile=/var/run/vlc.pid &#8212;ttl 8 -I telnet &#8212;telnet-host=0.0.0.0 &#8212;telnet-password=********* &#8212;sout-transcode-high-priority &#8212;http-reconnect &#8212;http-caching=10000 &#8212;logmode=syslog &#8212;rt-priority &#8212;vlm-conf /home/vlc/vlc-stream-list.cfg</p>
<p>Разберем ее по порядку:</p>
<ul>
<li>-d &#8212; опция которая говорит vlc запускаться как демон</li>
<li>-q &#8212; опция подавляющая вывод в stdout/stderr сообщений.</li>
<li>&#8212;pidfile &#8212; опция указывающая где будет создан файл идентификатора процесса, так как наш сервер будет запущен с опцией -d то это будет актуально, особенно если вы захотите в дальнейшем написать скрипт для /etc/init.d</li>
<li>&#8212;ttl &#8212; параметр не особо важный, но все же. Его назначение это указание маршрутизаторам время жизни транспортного пакета.. по истечению которого оный будет уничтожен.. Если трансляция осуществляется в рамках одного сегмента, можно установить параметр в единицу, меньше мусора будет.</li>
<li>-I тип интерфейса управления, в нашем случае telnet, есть еще http и что-то еще я уже не помню..</li>
<li>&#8212;telnet-host &#8212; с какого адреса ждать подключения к telnet консоли.</li>
<li>&#8212;telnet-password &#8212; тут все понятно..</li>
<li>&#8212;sout-transcode-high-priority &#8212; опция говорит что процессы транскодинга должны выполнятся с наивысшем приоритетом (аналог системной утилиты nice).</li>
<li>&#8212;http-reconnect &#8212; опция заставляющая vlc пытаться восстановить соединение с http транспортом камер. (При условии что таковой используется, если забор потока идет через rtp сия опция бесполезна)</li>
<li>&#8212;http-caching &#8212; кеш http трафика полезная опция при высокой нагрузке на сеть</li>
<li>&#8212;logmode логи работы vlc будут обрабатываться системными средствами, в частности syslog</li>
<li>&#8212;rt-priority очень важная опция заставляющая работать процессы vlc  с приоритетом реального времени. ВНИМАНИЕ! Если на сервере транскодинга запущены другие программы фонового характера работы.. Данная опция может серьезно снизить их производительность.</li>
<li>&#8212;vlm-conf путь до стрим листа.</li>
</ul>
<p>Вот собственно и все..</p>
<p>Дальше все, что вам нужно сделать это забить стрим лист данными о потоках и запустить сервер.</p>
<p>Вот так после запуска это выглядит у меня :</p>
<p style="text-align: left;"><a href="http://sincore.ru/wp-content/uploads/2011/12/vlc.png"><img class="aligncenter size-large wp-image-268" title="vlc" src="http://sincore.ru/wp-content/uploads/2011/12/vlc-1024x573.png" alt="Работа vlc транскодера на 60 потоках." width="620" height="346" /></a></p>
<p style="text-align: left;">Теперь надо подумать о том как этим управлять..</p>
<p style="text-align: left;">Для управления я сделал следующее:</p>
<ol>
<li style="text-align: left;">Создал таблицу в бд где храню информацию о потоках, их номера параметры кодирования и вывода, IP адреса логины и пароли для доступа к камерам и многое другое, что сильно упрощает жизнь.</li>
<li>На сервер я поместил скрипт который по крону или в ручную регенерирует стрим лист и перезагружает сервер.</li>
<li>Написал небольшую программку для управления записями в БД.</li>
</ol>
<p>Собственно все.. Кому будет интересно могу предоставить структуру таблицы и сходный код программки..</p>
<p>За сим откланюсь, надеюсь изложенная информация будет вам интересна и полезна.</p>
<p>Успехов.</p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/267/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Новая запись в блог&#8230;</title>
		<link>http://sincore.ru/archives/275</link>
		<comments>http://sincore.ru/archives/275#comments</comments>
		<pubDate>Fri, 02 Dec 2011 11:06:41 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Без рубрики]]></category>

		<guid isPermaLink="false">http://sincore.ru/archives/275</guid>
		<description><![CDATA[Новая запись в блоге. Посвящена процессу организации трансляции потоков с IP камер на сайтах. http://sincore.ru/archives/267 This was posted on Google+&#8230;]]></description>
			<content:encoded><![CDATA[<p>Новая запись в блоге. Посвящена процессу организации трансляции потоков с IP камер на сайтах.
<div class="g-crossposting-att">
<div class="g-crossposting-att-title"><a href="http://sincore.ru/archives/267" target="_blank">http://sincore.ru/archives/267</a></div>
<div class="g-crossposting-att-txt"></div>
</div>
<div class="g-crossposting-backlink"><a href="https://plus.google.com/109303071022652359230/posts/2Ae53FEXrQ7" target="_blank">This was posted on Google+&hellip;</a></div>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/275/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Iptables and Ipset in Debian</title>
		<link>http://sincore.ru/archives/265</link>
		<comments>http://sincore.ru/archives/265#comments</comments>
		<pubDate>Mon, 14 Nov 2011 01:44:17 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[debian]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Iptables]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=265</guid>
		<description><![CDATA[Включаем поддержку ipset в iptables. Актуально для ядер &#62; 2.6.30 # apt-get install module-assistant xtables-addons-source # module-assistant prepare # module-assistant auto-install xtables-addons-source # # modprobe ipt_set]]></description>
			<content:encoded><![CDATA[<p>Включаем поддержку ipset в iptables.</p>
<p>Актуально для ядер &gt; 2.6.30</p>
<p># apt-get install module-assistant xtables-addons-source<br />
# module-assistant prepare<br />
# module-assistant auto-install xtables-addons-source</p>
<p># # modprobe ipt_set</p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/265/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python 2.5 &amp; python-mysqldb : TypeError: not all arguments converted during string formatting</title>
		<link>http://sincore.ru/archives/251</link>
		<comments>http://sincore.ru/archives/251#comments</comments>
		<pubDate>Mon, 08 Aug 2011 21:38:50 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Баг]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=251</guid>
		<description><![CDATA[Баг в python-mysqldb Debian 5.0.6 Фаил : /usr/site/lib/python2.5/site-packages/MySQLdb/cursors.py Пакет : Package: python-mysqldb Priority: optional Section: python Installed-Size: 360 Maintainer: Debian Python Modules Team Architecture: amd64 Version: 1.2.2-7 Пример : sql = '''INSERT INTO call_fail_log (`callerid`,`date_stamp`,`cause`) VALUES(%s,FROM_UNIXTIME(%s),%s)''' &#160; &#160; &#160; &#160; &#8230;<p class="read-more"><a href="http://sincore.ru/archives/251">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Баг в python-mysqldb Debian 5.0.6</p>
<p>Фаил : /usr/site/lib/python2.5/site-packages/MySQLdb/cursors.py</p>
<p>Пакет :</p>
<p>Package: python-mysqldb<br />
Priority: optional<br />
Section: python<br />
Installed-Size: 360<br />
Maintainer: Debian Python Modules Team
<python -modules-team@lists.alioth.debian.org>
Architecture: amd64<br />
Version: 1.2.2-7</p>
<p>Пример :</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sql <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'''INSERT INTO call_fail_log (`callerid`,`date_stamp`,`cause`) VALUES(%s,FROM_UNIXTIME(%s),%s)'''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">db_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor.<span style="color: black;">executemany</span><span style="color: black;">&#40;</span>sql<span style="color: #66cc66;">,</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>callerid<span style="color: #66cc66;">,</span>datestamp<span style="color: #66cc66;">,</span>cause<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">db_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>Третий плейсхолдер не работоспособен, причина &#8212; неправильная работа регулярного вырождения при парсинге.</p>
<p>Решение :</p>
<p>Патч.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #660033;">---</span> cursors.py~ <span style="color: #000000;">2007</span>-02-<span style="color: #000000;">11</span> 07:<span style="color: #000000;">48</span>:<span style="color: #000000;">19.000000000</span> <span style="color: #660033;">-0800</span><br />
&nbsp;+++ cursors.py <span style="color: #000000;">2008</span>-<span style="color: #000000;">10</span>-09 <span style="color: #000000;">14</span>:<span style="color: #000000;">31</span>:<span style="color: #000000;">27.000000000</span> <span style="color: #660033;">-0700</span><br />
&nbsp;<span style="color: #000000; font-weight: bold;">@@</span> -<span style="color: #000000;">6</span>,<span style="color: #000000;">7</span> +<span style="color: #000000;">6</span>,<span style="color: #000000;">14</span> <span style="color: #000000; font-weight: bold;">@@</span><br />
&nbsp;<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #ff0000;">&quot;<br />
<br />
&nbsp;import re<br />
&nbsp;-insert_values =<br />
&nbsp;re.compile(r&quot;</span>\svalues\s<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>\<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>?<span style="color: #000000; font-weight: bold;">&lt;!</span>\\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">'.*?\).*(?&lt;!\\)?'</span><span style="color: #000000; font-weight: bold;">|</span>.<span style="color: #7a0874; font-weight: bold;">&#41;</span>+?\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">&quot;,<br />
&nbsp;re.IGNORECASE)<br />
&nbsp;+<br />
&nbsp;+restr = (r&quot;</span>\svalues\s<span style="color: #000000; font-weight: bold;">*</span><span style="color: #ff0000;">&quot;<br />
&nbsp;+ r&quot;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>\<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>?<span style="color: #000000; font-weight: bold;">&lt;!</span>\\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">'[^\)]*?\)[^\)]*(?&lt;!\\)?'</span><span style="color: #ff0000;">&quot;<br />
&nbsp;+ r&quot;</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>^\<span style="color: #7a0874; font-weight: bold;">&#40;</span>\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #ff0000;">&quot;<br />
&nbsp;+ r&quot;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>?:\<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>^\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">*</span>\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">&quot;<br />
&nbsp;+ r&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>+\<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">&quot;)<br />
&nbsp;+<br />
&nbsp;+insert_values= re.compile(restr)<br />
&nbsp;from _mysql_exceptions import Warning, Error, InterfaceError, DataError,<br />
&nbsp;<span style="color: #000099; font-weight: bold;">\<br />
</span> DatabaseError, OperationalError, IntegrityError, InternalError, <span style="color: #000099; font-weight: bold;">\<br />
</span> NotSupportedError, ProgrammingError</span></div></div>
<p>Накладываем патч на /usr/site/lib/python2.5/site-packages/MySQLdb/cursors.py , радуемся.</python>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/251/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asterisk логирование не обслужанных звонков</title>
		<link>http://sincore.ru/archives/243</link>
		<comments>http://sincore.ru/archives/243#comments</comments>
		<pubDate>Mon, 08 Aug 2011 05:21:35 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Asterisk]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Debian]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=243</guid>
		<description><![CDATA[Представим себе сферический колцентр в вакууме, есть голосовое меню и прочие навороты и есть абонент (то же в вакууме) звонящий в этот самый колцентр который пытается куда-то там и зачем-то там дозвониться, внезапно ему наскучивает слушать говор синтетического человека и &#8230;<p class="read-more"><a href="http://sincore.ru/archives/243">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Представим себе сферический колцентр в вакууме, есть голосовое меню и прочие навороты и есть абонент (то же в вакууме) звонящий в этот самый колцентр который пытается куда-то там и зачем-то там дозвониться, внезапно ему наскучивает слушать говор синтетического человека и абонент кладет трубку..<br />
А теперь представим, что колцентр обслуживает абонентов некого оператора связи где каждый абонент на счету и администрация люто печется о качестве сервиса и желает перезвонить не терпеливому абоненту и спросить, что тот хотел.</p>
<p>Замутим логирование кодов закрытия канала связи..</p>
<p>Что есть : Asterisk 1.4 , Python 2.5 , MySQL 5.1</p>
<p>Создадим табличку для MySQL в которую и будем складывать высеры Астериска.</p>
<p>Будем сохранять:<br />
callerid &#8212; собственно номер звонившего<br />
date_stamp &#8212; timestamp обрыва канала (HANGUP,CANCEL, etc..)<br />
cause &#8212; код причины<br />
status и comment &#8212; зело не обязательно, статус записи (типа обслужено или нет) и комментарий</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`asterisk`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`call_fail_log`</span> <span style="color: #66cc66;">&#40;</span><br />
<span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`callerid`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`date_stamp`</span> <span style="color: #993333; font-weight: bold;">TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`cause`</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`status`</span> tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'0'</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`comment`</span> text<span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`call_index`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`callerid`</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>MyISAM <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8</div></div>
<p>Теперь сварганим махонький python agi скрипт который непосредственно сохранять данный в базу..</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span><br />
<br />
<span style="color: #483d8b;">'''<br />
Created on 05.08.2011<br />
<br />
@author: valor<br />
'''</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">class</span> CallFailLog:<br />
<br />
&nbsp; &nbsp; DBHOST <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;192.168.158.160&quot;</span><br />
&nbsp; &nbsp; DBUSER <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;agi&quot;</span><br />
&nbsp; &nbsp; DBPASS <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;asterisk&quot;</span><br />
&nbsp; &nbsp; DBNAME <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;asterisk&quot;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">pass</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> db_init<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; connect <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>db<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBNAME</span><span style="color: #66cc66;">,</span> host<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBHOST</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBUSER</span><span style="color: #66cc66;">,</span> passwd<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBPASS</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> connect<br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span>callerid<span style="color: #66cc66;">,</span> datestamp<span style="color: #66cc66;">,</span> cause<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; sql <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'''INSERT INTO call_fail_log (`callerid`,`date_stamp`,`cause`) VALUES(%s,FROM_UNIXTIME(%s),%s)'''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">db_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cursor.<span style="color: black;">executemany</span><span style="color: black;">&#40;</span>sql<span style="color: #66cc66;">,</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>callerid<span style="color: #66cc66;">,</span>datestamp<span style="color: #66cc66;">,</span>cause<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">db_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:<br />
&nbsp; &nbsp; app <span style="color: #66cc66;">=</span> CallFailLog<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; app.<span style="color: black;">main</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></div>
<p>Как видим все просто и легко..<br />
Теперь лезем в extensions.conf и сделаем макрос обработки кодов + посмотрим откель его можно вызвать..</p>
<p>Собственно макрос:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>macro-logfailcall<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,<span style="color: #000000;">1</span>,GotoIF<span style="color: #7a0874; font-weight: bold;">&#40;</span>$<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;<span style="color: #007800;">${ARG1}</span>&quot;</span> = <span style="color: #ff0000;">&quot;16&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>?goin:end<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n<span style="color: #7a0874; font-weight: bold;">&#40;</span>goin<span style="color: #7a0874; font-weight: bold;">&#41;</span>,DeadAGI<span style="color: #7a0874; font-weight: bold;">&#40;</span>callfaillog.py,<span style="color: #800000;">${CALLERID(num)}</span>,<span style="color: #800000;">${EPOCH}</span>,<span style="color: #800000;">${ARG1}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n<span style="color: #7a0874; font-weight: bold;">&#40;</span>end<span style="color: #7a0874; font-weight: bold;">&#41;</span>,NoOp<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>gt; Unknown cause <span style="color: #800000;">${ARG1}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n,Hangup<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p>Код завершения 16 NORMAL_CLEARING  &#8212; есть не что иное как положенная абонентом трубка.</p>
<p>Вызвать его можно в любом контексте, например так..</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> h,<span style="color: #000000;">1</span>,Macro<span style="color: #7a0874; font-weight: bold;">&#40;</span>logfailcall,<span style="color: #800000;">${HANGUPCAUSE}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
...</div></div>
<blockquote><p>a: Вызывается, когда пользователь нажимает &#8216;*&#8217; во время проигрывания приветствия системы голосовой почты.<br />
<strong>h: Вызывается, по завершению вызова. </strong><br />
i: Вызывается, при попытке вызова неизвестного екстеншена.<br />
o: Расширение оператора, используется для обработки нажатия нуля в системе голосовой почты.<br />
s: Стартовое расширение в контексте.<br />
t: Вызывается, при наступлении состояния таймаута.<br />
T: Вызывается, при наступлении состояния абсолютного таймаута, заданного функцией AbsolutTimeout?.<br />
e: Перехват расширений i,t и T для обработки ошибки в едином месте. Для выяснения типа ошибки может быть использована функция EXCEPTION(?)<br />
failed: Используется, если auto-dial out вызов завершился неудачно (который имеет определённый контекст, приоритет и расширение).<br />
fax: Используется для определения факса на Zap каналах.<br />
talk: Используется в конъюнкции с BackgroundDetect?.</p></blockquote>
<p>Полезные ссылки : <a href="http://voip.rus.net/tiki-index.php?page=Asterisk+Variable+HANGUPCAUSE" target="_blank">Коды причин закрытия канала</a></p>
<p>Удачи..</p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/243/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VsFTPD and Virtual users on Debian</title>
		<link>http://sincore.ru/archives/239</link>
		<comments>http://sincore.ru/archives/239#comments</comments>
		<pubDate>Sun, 07 Aug 2011 21:32:58 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Памятки]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[vsftpd]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=239</guid>
		<description><![CDATA[На заметку.. Пакеты: apt-get install libpam-pwdfile vsftpd Предположим, что сайтики лежат в /srv/www/{sitename &#8212; вида www.mysite.ru}/htdocs , соответственно ограничиваем пользователя доступом в корень, т.е. не выше директории www.mysite.ru. И так чистим дефолтный конфиг vsftpd echo &#34;&#34; &#62; /etc/vsftpad.conf И записываем &#8230;<p class="read-more"><a href="http://sincore.ru/archives/239">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>На заметку..</p>
<p>Пакеты:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">apt-get install</span> libpam-pwdfile vsftpd</div></div>
<p>Предположим, что сайтики лежат в /srv/www/{sitename &#8212; вида www.mysite.ru}/htdocs , соответственно ограничиваем пользователя доступом в корень, т.е. не выше директории www.mysite.ru.</p>
<p>И так чистим дефолтный конфиг vsftpd</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>vsftpad.conf</div></div>
<p>И записываем туды следующие..</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #007800;">listen</span>=YES<br />
<span style="color: #007800;">anonymous_enable</span>=NO<br />
<span style="color: #007800;">local_enable</span>=YES<br />
<span style="color: #007800;">write_enable</span>=YES<br />
<span style="color: #007800;">local_umask</span>=022<br />
<span style="color: #666666; font-style: italic;"># пользователя vsftpd нужно создать системным без шела, например useradd -M -r vsftpd</span><br />
<span style="color: #007800;">nopriv_user</span>=vsftpd<br />
<span style="color: #007800;">virtual_use_local_privs</span>=YES<br />
<span style="color: #007800;">guest_enable</span>=YES<br />
<span style="color: #007800;">user_sub_token</span>=<span style="color: #007800;">$USER</span><br />
<span style="color: #666666; font-style: italic;"># Токен $USER предполагает что к пути /srv/www/ будет добавлено имя пользователя, он и будет являться корнем для него. </span><br />
<span style="color: #007800;">local_root</span>=<span style="color: #000000; font-weight: bold;">/</span>srv<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$USER</span><br />
<span style="color: #007800;">chroot_local_user</span>=YES<br />
<span style="color: #007800;">hide_ids</span>=YES<br />
<span style="color: #007800;">guest_username</span>=vsftpd<br />
<span style="color: #007800;">chown_uploads</span>=YES<br />
<span style="color: #666666; font-style: italic;"># От имени и группы www-data пашет Apache.</span><br />
<span style="color: #007800;">chown_username</span>=www-data<br />
<span style="color: #007800;">guest_enable</span>=YES<br />
<span style="color: #007800;">guest_username</span>=www-data<br />
<span style="color: #007800;">chown_upload_mode</span>=0775<br />
<br />
<span style="color: #007800;">use_localtime</span>=YES<br />
<span style="color: #007800;">xferlog_enable</span>=YES<br />
<span style="color: #007800;">xferlog_file</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>vsftpd.log<br />
<span style="color: #007800;">xferlog_std_format</span>=YES<br />
<br />
<span style="color: #007800;">dirmessage_enable</span>=YES<br />
<span style="color: #007800;">ascii_upload_enable</span>=YES<br />
<span style="color: #007800;">ascii_download_enable</span>=YES<br />
<span style="color: #007800;">ftpd_banner</span>=Welcome developer to WWW server<span style="color: #000000; font-weight: bold;">!</span><br />
<span style="color: #007800;">ls_recurse_enable</span>=YES<br />
<span style="color: #007800;">secure_chroot_dir</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>vsftpd<span style="color: #000000; font-weight: bold;">/</span>empty<br />
<br />
<span style="color: #007800;">pasv_enable</span>=YES<br />
<span style="color: #007800;">pasv_min_port</span>=<span style="color: #000000;">62000</span><br />
<span style="color: #007800;">pasv_max_port</span>=<span style="color: #000000;">64000</span></div></div>
<p>Далее надо настроит pam аутентификацию, для сего лезим в /etc/pam.d/vsftpd и комментим все попутно добавив туда две строчки</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">auth required pam_pwdfile.so pwdfile <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd<br />
account required pam_permit.so</div></div>
<p>Собственно создаем файлик /etc/ftpd.passwd командой</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">htpasswd <span style="color: #660033;">-c</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd</div></div>
<p>Добавление пользователя осуществляется аналогично, только без опции -с и с названием корневой директории сайта в качестве пользователя</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">htpasswd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd www.mysite.ru</div></div>
<p>Ребутим vsftpd и радуемся..</p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/239/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asterisk &#8212; запись исходящих звонков.</title>
		<link>http://sincore.ru/archives/225</link>
		<comments>http://sincore.ru/archives/225#comments</comments>
		<pubDate>Mon, 30 May 2011 05:42:17 +0000</pubDate>
		<dc:creator>Valor</dc:creator>
				<category><![CDATA[Asterisk]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Памятки]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://sincore.ru/?p=225</guid>
		<description><![CDATA[Задача: Записывать исходящие звонки от некоторого подмножества абонентов корпоративной телефонной сети. Что есть в наличии: Asterisk 1.4* &#8212; вот с ним то и будем плясать.. Решение:  Список жертв будет храниться в бд, в моем случае это MySQL, для этого сварганим &#8230;<p class="read-more"><a href="http://sincore.ru/archives/225">Читать далее &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>Задача</strong>: Записывать исходящие звонки от некоторого подмножества абонентов корпоративной телефонной сети.</p>
<p><strong>Что есть в наличии</strong>: Asterisk 1.4* &#8212; вот с ним то и будем плясать..</p>
<p><strong>Решение</strong>:  Список жертв будет храниться в бд, в моем случае это MySQL, для этого сварганим не хитрую табличку:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`asterisk`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`callout`</span> <span style="color: #66cc66;">&#40;</span><br />
<span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`callerid`</span> <span style="color: #993333; font-weight: bold;">INT</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">`status`</span> TINYINT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><br />
<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#41;</span><br />
ENGINE <span style="color: #66cc66;">=</span> MyISAM;</div></div>
<p>Поясню: Поле  <strong>callerid</strong> &#8212; будет хронить 4х значный номер внутреннего абонента. <strong>status</strong> &#8212; просто флаг который позволит нам например временно исключать номер из списка записывающихся..</p>
<p>Далее давайте напишим AGI скрипт, который будет пробивать переданный ему в качестве аргумента callerid и если таковой там имеется, то вновь созданный канал будет записан.</p>
<p><strong>Пример скрипта:</strong></p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span><br />
<span style="color: #483d8b;">'''<br />
Created on 26.05.2011<br />
<br />
@author: valor<br />
'''</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<span style="color: #ff7700;font-weight:bold;">from</span> asterisk.<span style="color: black;">agi</span> <span style="color: #ff7700;font-weight:bold;">import</span> AGI<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">class</span> calloutrec:<br />
<br />
DBHOST <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;localhost&quot;</span><br />
DBUSER <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;agi&quot;</span><br />
DBPASS <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;asterisk&quot;</span><br />
DBNAME <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;asterisk&quot;</span><br />
<br />
DEBUG <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">3</span><br />
<br />
agi <span style="color: #66cc66;">=</span> AGI<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> db_init<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
connect <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>db<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBNAME</span><span style="color: #66cc66;">,</span> host<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBHOST</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBUSER</span><span style="color: #66cc66;">,</span> passwd<span style="color: #66cc66;">=</span><span style="color: #008000;">self</span>.<span style="color: black;">DBPASS</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">return</span> connect<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span>arg<span style="color: black;">&#41;</span>:<br />
<br />
&nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">agi</span>.<span style="color: black;">verbose</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&gt;&gt;&gt; start executing AGI script &quot;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">DEBUG</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">db_init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'''SELECT c.callerid FROM callout c WHERE c.status = 1 AND c.callerid =%s'''</span><span style="color: #66cc66;">,</span>arg<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; res <span style="color: #66cc66;">=</span> cursor.<span style="color: black;">fetchone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> res <span style="color: #66cc66;">!=</span> <span style="color: #008000;">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">agi</span>.<span style="color: black;">set_variable</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ISREC&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">agi</span>.<span style="color: black;">set_variable</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;ISREC&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:<br />
app <span style="color: #66cc66;">=</span> calloutrec<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
app.<span style="color: black;">main</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></div>
<p>В основе скрипта лежит мини фреймворк <a href="http://sourceforge.net/projects/pyst/" target="_blank">pyst</a> , один из немногих еще не здохших проектов &#8212; рекомендую, жизнь облегчит.</p>
<p>Теперь осталось подправить extensions.conf , для начала создадим макрос следующего содержания</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>macro-calloutrec<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,<span style="color: #000000;">1</span>,AGI<span style="color: #7a0874; font-weight: bold;">&#40;</span>callaoutrec.py,<span style="color: #800000;">${ARG1}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n,NoOp<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #800000;">${ISREC}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n,GotoIF<span style="color: #7a0874; font-weight: bold;">&#40;</span>$<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;<span style="color: #007800;">${ISREC}</span>&quot;</span> = <span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>?rec:norec<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n<span style="color: #7a0874; font-weight: bold;">&#40;</span>rec<span style="color: #7a0874; font-weight: bold;">&#41;</span>,MixMonitor<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">/</span>raid<span style="color: #000000; font-weight: bold;">/</span>outmonitor<span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${EPOCH}</span>-<span style="color: #800000;">${CALLERID(num)}</span>.wav<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
exten =<span style="color: #000000; font-weight: bold;">&gt;</span> s,n<span style="color: #7a0874; font-weight: bold;">&#40;</span>norec<span style="color: #7a0874; font-weight: bold;">&#41;</span>,NoOp<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #800000;">${CALLERID(num)}</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;&gt;</span> No record call<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p>Вот такой вот нехитрый макрос принимает в качестве аргумента callerid абонента осуществляющего исходящий звонок, далее передает его как аргумент agi скрипту и на основе возвращенного результата решает писать его или нет.</p>
<p>Осталось применить макрос в контексте через который идут исходящие звонки. примерно так:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">exten =<span style="color: #000000; font-weight: bold;">&amp;</span>gt; _XXXXXX.,n,Macro<span style="color: #7a0874; font-weight: bold;">&#40;</span>calloutrec,<span style="color: #800000;">${CALLERID(num)}</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p>Вот и все.. записанные файлики в формате wav будут складываться в директорию  /raid/outmonitor/ с именем фала вида utc-callerid.wav .</p>
<p>ЗЫ. Для сортировки полученных фалов можно использовать скрипт из <a href="http://sincore.ru/archives/219" target="_blank">предыдущей статьи.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sincore.ru/archives/225/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

