<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Я безумен</title>
	<atom:link href="https://itinsanity.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://itinsanity.wordpress.com</link>
	<description>Различные мысли иногда приходящие в голову.</description>
	<lastBuildDate>Mon, 11 Oct 2010 22:17:11 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='itinsanity.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s0.wp.com/i/buttonw-com.png</url>
		<title>Я безумен</title>
		<link>https://itinsanity.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://itinsanity.wordpress.com/osd.xml" title="Я безумен" />
	<atom:link rel='hub' href='https://itinsanity.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Samba и симлинки</title>
		<link>https://itinsanity.wordpress.com/2010/08/01/samba-%d0%b8-%d1%81%d0%b8%d0%bc%d0%bb%d0%b8%d0%bd%d0%ba%d0%b8/</link>
					<comments>https://itinsanity.wordpress.com/2010/08/01/samba-%d0%b8-%d1%81%d0%b8%d0%bc%d0%bb%d0%b8%d0%bd%d0%ba%d0%b8/#comments</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Sun, 01 Aug 2010 14:00:01 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=154</guid>

					<description><![CDATA[Проблема и решение Так как у нас используется самба для расшаривания файлов(печальное наследие когда среда была гетерогенной, но сейчас несмотря на наличие только никсов самба все еще юзается) возникла небольшая проблема, при просмотре ресурса через самбу симлинки не были видны вообще, что было не удобным. Пошел копать что нужно сделать. Как выяснилось все очень просто: [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>Проблема и решение</h2>
<p>Так как у нас используется самба для расшаривания файлов(печальное наследие когда среда была гетерогенной, но сейчас несмотря на наличие только никсов самба все еще юзается) возникла небольшая проблема, при просмотре ресурса через самбу симлинки не были видны вообще, что было не удобным. Пошел копать что нужно сделать. Как выяснилось все очень просто:</p>
<p>Необходимо добавить в [global] секцию файла smb.conf (для убунты он лежит в /etc/samba/smb.conf) три строки:</p>
<pre>
  follow symlinks = yes
  wide links = yes
  unix extensions = no
</pre>
<p>После этого перезапускаем samba <code>/etc/init.d/samba restart</code> и вуаля симлинки теперь отображаются и доступны.</p>
<h2>Источник</h2>
<p><a href='http://ubuntuforums.org/showthread.php?t=352016'>Обсуждение на форуме Ubuntu</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2010/08/01/samba-%d0%b8-%d1%81%d0%b8%d0%bc%d0%bb%d0%b8%d0%bd%d0%ba%d0%b8/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Плагин для Smarty для склонения существительных с числительными</title>
		<link>https://itinsanity.wordpress.com/2010/07/25/%d0%bf%d0%bb%d0%b0%d0%b3%d0%b8%d0%bd-%d0%b4%d0%bb%d1%8f-smarty-%d0%b4%d0%bb%d1%8f-%d1%81%d0%ba%d0%bb%d0%be%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d1%81%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b8%d1%82%d0%b5/</link>
					<comments>https://itinsanity.wordpress.com/2010/07/25/%d0%bf%d0%bb%d0%b0%d0%b3%d0%b8%d0%bd-%d0%b4%d0%bb%d1%8f-smarty-%d0%b4%d0%bb%d1%8f-%d1%81%d0%ba%d0%bb%d0%be%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d1%81%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b8%d1%82%d0%b5/#comments</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Sun, 25 Jul 2010 18:27:12 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=146</guid>

					<description><![CDATA[Тему склонения я уже как то поднимал в Новости на сайте посредством twitter’a, теперь же всплыла задача когда необходимо было реализовать данное склонение в качестве плагина для Smarty. И обертка готова, кому нужно может пользоваться. Нужно сохранить код приведенный ниже в файл function.decliner.php в каталоге с плагинами Smarty &#60;?php /** * Smarty {decliner} function plugin * [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Тему склонения я уже как то поднимал в <a title="Новости на сайте посредством twitter’a" href="https://itinsanity.wordpress.com/2009/07/09/%D0%BD%D0%BE%D0%B2%D0%BE%D1%81%D1%82%D0%B8-%D0%BD%D0%B0-%D1%81%D0%B0%D0%B9%D1%82%D0%B5-%D0%BF%D0%BE%D1%81%D1%80%D0%B5%D0%B4%D1%81%D1%82%D0%B2%D0%BE%D0%BC-twittera/">Новости на сайте посредством twitter’a</a>, теперь же всплыла задача когда необходимо было реализовать данное склонение в качестве плагина для Smarty. И обертка готова, кому нужно может пользоваться.</p>
<p>Нужно сохранить код приведенный ниже в файл function.decliner.php в каталоге с плагинами Smarty</p>
<pre>&lt;?php
/**
 * Smarty {decliner} function plugin
 *
 * Type:     function&lt;br&gt;
 * Name:     decliner&lt;br&gt;
 * Purpose:  handle word declines based on quantity number&lt;br&gt;
 * @author   Dmitriy Soloduhin &lt;darkomen86 at gmail dot com&gt;(credits to http://mcaizer.habrahabr.ru/blog/11555/)
 * @param array $params
 * &lt;pre&gt;
 * Params:  qty: number of items to choose correct declining form
 *          word: declining forms of word. Ex: день, дня, дней.
 * &lt;/pre&gt;
 * @param Smarty
 * @return string
 */
function smarty_function_decliner($params, &amp;$smarty)
{
    // be sure equation parameter is present
    if (<a href="http://www.php.net/empty">empty</a>($params['qty']))
	$params['qty']=0;
    if (<a href="http://www.php.net/empty">empty</a> ($params['word'])) {
        $smarty-&gt;trigger_error("decliner: missing required parameter");
        return;
    }
    $forms=<a href="http://www.php.net/explode">explode</a>(',',$params['word']);
    $params['qty'] = <a href="http://www.php.net/abs">abs</a>($params['qty']) % 100;
    $n1 = $params['qty'] % 10;
    if ( $params['qty'] &gt; 10 &amp;&amp;  $params['qty'] &lt; 20) return $forms[2];
    else if ($n1 &gt; 1 &amp;&amp; $n1 &lt; 5) return $forms[1];
    else if ($n1 == 1) return $forms[0];
    return $forms[2];

}

/* vim: set expandtab: */

?&gt;</pre>
<p>Затем в шаблонах можно использовать вот так.</p>
<pre>{decliner qty=4 word='письма, письма, писем'}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2010/07/25/%d0%bf%d0%bb%d0%b0%d0%b3%d0%b8%d0%bd-%d0%b4%d0%bb%d1%8f-smarty-%d0%b4%d0%bb%d1%8f-%d1%81%d0%ba%d0%bb%d0%be%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d1%81%d1%83%d1%89%d0%b5%d1%81%d1%82%d0%b2%d0%b8%d1%82%d0%b5/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Сохранение файлов с другим именем в 1C-Bitrix</title>
		<link>https://itinsanity.wordpress.com/2010/03/01/%d1%81%d0%be%d1%85%d1%80%d0%b0%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d1%81-%d0%b4%d1%80%d1%83%d0%b3%d0%b8%d0%bc-%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bc-%d0%b2-1c-bitrix/</link>
					<comments>https://itinsanity.wordpress.com/2010/03/01/%d1%81%d0%be%d1%85%d1%80%d0%b0%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d1%81-%d0%b4%d1%80%d1%83%d0%b3%d0%b8%d0%bc-%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bc-%d0%b2-1c-bitrix/#comments</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Mon, 01 Mar 2010 20:10:08 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[bitrix]]></category>
		<category><![CDATA[content-disposition]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=126</guid>

					<description><![CDATA[Введение Недавно мне пришлось опять связаться с так не любимой мной CMS&#8217;кой 1С-Bitrix. При этом встала своеобразная задача, было множество файлов которые необходимо было отдавать с именами отличными от исходных. Было решено использовать описание файла как имя. Для этого был написан небольшой скриптик который принимает в качестве аргумента идентификатор файла. Здесь я попробую рассмотреть те [&#8230;]]]></description>
										<content:encoded><![CDATA[<h3>Введение</h3>
<p>Недавно мне пришлось опять связаться с так не любимой мной CMS&#8217;кой 1С-Bitrix. При этом встала своеобразная задача, было множество файлов которые необходимо было отдавать с именами отличными от исходных. Было решено использовать описание файла как имя. Для этого был написан небольшой скриптик который принимает в качестве аргумента идентификатор файла.</p>
<p>Здесь я попробую рассмотреть те особенности с которыми пришлось столкнуться. Для начала рассмотрим что основной кодировкой ресурса является cp1251. И большинство описаний составлено на русском языке.</p>
<h3>Реализация</h3>
<p>Для начала нам необходимо будет проверять передается ли нам вообще параметр, и если нет нужно мирно завершить работу.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5627/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5627/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#0000ff">if</font> (!<font color="#0000ff">isset</font>(<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>]) || !((int)<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>]) )</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">die</font>();</li>
<li><font color="#cc6633">$file_id</font>=(int)<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>]; </li>
</ol>
<p></font></code></p></blockquote>
<p>Затем определим функцию для определения по юзер-агенту браузера(взял из комментов на сайте <a href='http://php.net/manual/en/function.get-browser.php'> php</a>). Эта функция нам понадобится посколько у IE как всегда все не как у людей, и надо будет под него подстраиваться, as usually.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5628/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5628/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#0000ff">function</font> browser_info(<font color="#cc6633">$agent</font>=<font color="#0000ff">null</font>) {</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Declare&nbsp;known&nbsp;browsers&nbsp;to&nbsp;look&nbsp;for</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$known</font> = <font color="#0000ff">array</font>(<font color="#008000">'msie'</font>, <font color="#008000">'firefox'</font>, <font color="#008000">'safari'</font>, <font color="#008000">'webkit'</font>, <font color="#008000">'opera'</font>, <font color="#008000">'netscape'</font>,</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">'konqueror'</font>, <font color="#008000">'gecko'</font>);</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Clean&nbsp;up&nbsp;agent&nbsp;and&nbsp;build&nbsp;regex&nbsp;that&nbsp;matches&nbsp;phrases&nbsp;for&nbsp;known&nbsp;browsers</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;(e.g.&nbsp;"Firefox/2.0"&nbsp;or&nbsp;"MSIE&nbsp;6.0"&nbsp;(This&nbsp;only&nbsp;matches&nbsp;the&nbsp;major&nbsp;and&nbsp;minor</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;version&nbsp;numbers.&nbsp;&nbsp;E.g.&nbsp;"2.0.0.6"&nbsp;is&nbsp;parsed&nbsp;as&nbsp;simply&nbsp;"2.0"</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$agent</font> = <a href="http://www.php.net/manual/en/function.strtolower.php">strtolower</a>(<font color="#cc6633">$agent</font> ? <font color="#cc6633">$agent</font> : <font color="#cc6633">$_SERVER</font>[<font color="#008000">'HTTP_USER_AGENT'</font>]);</li>
<li>&nbsp;&nbsp;<font color="#cc6633">$pattern</font> = <font color="#008000">'#(?&lt;browser&gt;'</font> . <a href="http://www.php.net/manual/en/function.join.php">join</a>(<font color="#008000">'|'</font>, <font color="#cc6633">$known</font>) .</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">')[/&nbsp;]+(?&lt;version&gt;[0-9]+(?:\.[0-9]+)?)#'</font>;</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Find&nbsp;all&nbsp;phrases&nbsp;(or&nbsp;return&nbsp;empty&nbsp;array&nbsp;if&nbsp;none&nbsp;found)</font></li>
<li>&nbsp;&nbsp;<font color="#0000ff">if</font> (!<a href="http://www.php.net/manual/en/function.preg-match-all.php">preg_match_all</a>(<font color="#cc6633">$pattern</font>, <font color="#cc6633">$agent</font>, <font color="#cc6633">$matches</font>)) <font color="#0000ff">return array</font>();</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Since&nbsp;some&nbsp;UAs&nbsp;have&nbsp;more&nbsp;than&nbsp;one&nbsp;phrase&nbsp;(e.g&nbsp;Firefox&nbsp;has&nbsp;a&nbsp;Gecko&nbsp;phrase,</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Opera&nbsp;7,8&nbsp;have&nbsp;a&nbsp;MSIE&nbsp;phrase),&nbsp;use&nbsp;the&nbsp;last&nbsp;one&nbsp;found&nbsp;(the&nbsp;right-most&nbsp;one</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;in&nbsp;the&nbsp;UA).&nbsp;&nbsp;That's&nbsp;usually&nbsp;the&nbsp;most&nbsp;correct.</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$i</font> = <a href="http://www.php.net/manual/en/function.count.php">count</a>(<font color="#cc6633">$matches</font>[<font color="#008000">'browser'</font>])-<font color="#008000">1</font>;</li>
<li>&nbsp;&nbsp;<font color="#0000ff">return array</font>(<font color="#cc6633">$matches</font>[<font color="#008000">'browser'</font>][<font color="#cc6633">$i</font>] =&gt; <font color="#cc6633">$matches</font>[<font color="#008000">'version'</font>][<font color="#cc6633">$i</font>]);</li>
<li>} </li>
</ol>
<p></font></code></p></blockquote>
<p>Теперь о логике работы, для того чтобы браузер решил что у файла что мы передаем совсем другое имя вы должны ему передать заголовок <code>Content-Disposition: attachment; FILENAME="имя файла";size="размер файла в байтах"</code><br />
Ну и до кучи некоторые другие стандартные заголовки типа Content-Type и Content-Length. Имя файла мы сформируем из описания, его, а также размер файла и путь к нему необходимо будет получить, так что мы подключаем битриксовые библиотеки:</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5629/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5629/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#0000ff">require</font>(<font color="#cc6633">$_SERVER</font>[<font color="#008000">"DOCUMENT_ROOT"</font>].<font color="#008000">"/bitrix/modules/main/include/prolog_before.php"</font>); </li>
</ol>
<p></font></code></p></blockquote>
<p>И получаем путь к файлу, и массив с информацией о файле:</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5630/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5630/h">Copy&nbsp;HTML</a></p>
<ol>
<li>$arr = CFile::MakeFileArray(<font color="#cc6633">$file_id</font>);</li>
<li><font color="#cc6633">$path</font> = CFile::GetPath(<font color="#cc6633">$file_id</font>); </li>
</ol>
<p></font></code></p></blockquote>
<p>Теперь получим расширение файла так как оно нам понадобится при формировании имени.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5631/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5631/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#cc6633">$ext</font> = <a href="http://www.php.net/manual/en/function.explode.php">explode</a>(<font color="#008000">'.'</font>, <font color="#cc6633">$path</font>);</li>
<li><font color="#0000ff">if</font> (<a href="http://www.php.net/manual/en/function.count.php">count</a>(<font color="#cc6633">$ext</font>)&gt;<font color="#008000">1</font>)</li>
<li>&nbsp;&nbsp;&nbsp;<font color="#cc6633">$ext</font> = <font color="#cc6633">$ext</font>[<a href="http://www.php.net/manual/en/function.count.php">count</a>(<font color="#cc6633">$ext</font>)-<font color="#008000">1</font>];</li>
<li><font color="#0000ff">else</font></li>
<li>&nbsp;&nbsp;&nbsp;<font color="#cc6633">$ext</font>=<font color="#008000">''</font>; </li>
</ol>
<p></font></code></p></blockquote>
<p>Теперь займемся формированием имени файла.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5632/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5632/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#cc6633">$description</font>=<font color="#cc6633">$arr</font>[<font color="#008000">'description'</font>];</li>
<li><font color="#696969">//укорачиваем&nbsp;название&nbsp;если&nbsp;оно&nbsp;слишком&nbsp;длинное()</font></li>
<li><font color="#0000ff">if</font> (mb_strlen(<font color="#cc6633">$description</font>)&gt;<font color="#008000">150</font>)</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$description</font>=mb_substr(<font color="#cc6633">$description</font>,<font color="#008000">&nbsp;0</font>,<font color="#008000">150</font>).<font color="#008000">'...'</font>; </li>
</ol>
<p></font></code></p></blockquote>
<p>Описание файла необходимо очистить от символов которые не могут использоваться в именах файлов.<br />
У FAT32,UFS,HFS+ ограничений особых нет, у ext2-3-4 нельзя использовать в названии файла символ &#8216;/&#8217;, но больше всего ограничений накладывается при использовании файловой системы NTFS, где запрещено использовать символов &#8216; &#187; / \ * ?  | : &#8216;, что сильно огорчает <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f626.png" alt="😦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Так что будем рассматривать худший случай, и поэтому преобразуем все встречные символы из этого списка в пробелы. Также в имени не может использоваться NUL, во всех из вышеперечисленных файловых систем.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5633/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5633/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#cc6633">$pattern</font> = <font color="#0000ff">array</font>(<font color="#008000">'"'</font>, <font color="#008000">'/'</font>, <font color="#008000">'\\'</font>, <font color="#008000">'*'</font>,<font color="#008000">'?'</font>,<font color="#008000">'&lt;'</font>,<font color="#008000">'&gt;'</font>,<font color="#008000">'|'</font>,<font color="#008000">':'</font>); </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">for</font> (<font color="#cc6633">$i</font>=<font color="#008000">&nbsp;0</font>; <font color="#cc6633">$i</font>&lt;<a href="http://www.php.net/manual/en/function.sizeof.php">sizeof</a>(<font color="#cc6633">$pattern</font>); <font color="#cc6633">$i</font>++) { </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$description</font> = mb_ereg_replace(<font color="#cc6633">$pattern</font>[<font color="#cc6633">$i</font>], <font color="#008000">'&nbsp;'</font>, <font color="#cc6633">$description</font>); </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;} </li>
</ol>
<p></font></code></p></blockquote>
<p>Как выяснилось с кодировками в которых надо отдавать названия тоже проблема. Так Firefox,Opera,Chrome,Safari понимают если им передать название в кодировке UTF-8, в то время как IE просто жаждет cp-1251.<br />
При этом необходимо не забывать что в случае если описание отсутствует стоит воспользоваться исходным именем файла.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5636/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5636/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#cc6633">$ua</font>=browser_info();</li>
<li><font color="#0000ff">if</font> (<font color="#cc6633">$description</font>)</li>
<li>{</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$fname</font>=mb_convert_encoding(<font color="#cc6633">$description</font>,<font color="#008000">"UTF-8"</font>, <font color="#008000">"Windows-1251"</font> ).<font color="#008000">'.'</font>.<font color="#cc6633">$ext</font>;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font> (<font color="#0000ff">isset</font>(<font color="#cc6633">$ua</font>[<font color="#008000">'msie'</font>])) </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$fname</font>=<font color="#cc6633">$description</font>.<font color="#008000">'.'</font>.<font color="#cc6633">$ext</font>;</li>
<li>}</li>
<li><font color="#0000ff">else</font> <font color="#cc6633">$fname</font>=<a href="http://www.php.net/manual/en/function.basename.php">basename</a>(<font color="#cc6633">$arr</font>[<font color="#008000">'tmp_name'</font>]); </li>
</ol>
<p></font></code></p></blockquote>
<p>Теперь отдаем необходимые заголовки и содержимое файла</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5638/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5638/h">Copy&nbsp;HTML</a></p>
<ol>
<li><a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Type:&nbsp;'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'type'</font>]);</li>
<li><a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Length:&nbsp;'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'size'</font>]);</li>
<li><a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Disposition:&nbsp;attachment;&nbsp;FILENAME="'</font>.<font color="#cc6633">$fname</font>.<font color="#008000">'";&nbsp;size="'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'size'</font>].<font color="#008000">'"'</font>);</li>
<li><font color="#0000ff">echo</font> file_get_contents(<font color="#cc6633">$arr</font>[<font color="#008000">'tmp_name'</font>]); </li>
</ol>
<p></font></code></p></blockquote>
<p>Еще в ходе экспериментов всплыло то что добавление require($_SERVER[&#171;DOCUMENT_ROOT&#187;].&#187;/bitrix/modules/main/include/prolog_after.php&#187;); является чреватым, и инклудить этот файл в конце скрипта не стоит.</p>
<h2>Листинг</h2>
<p>Полный листинг приведен снизу.</p>
<blockquote><p><code><font size="2" face="Consolas, Courier New, Courier, Monospace" color="black"><a href="http://s-c.me/5635/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/5635/h">Copy&nbsp;HTML</a></p>
<ol>
<li><font color="#cc6633">&lt;?</font></li>
<li><font color="#0000ff">if</font> (!<font color="#0000ff">isset</font>(<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>]) || !((int)<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>]) )</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">die</font>();</li>
<li><font color="#0000ff">function</font> browser_info(<font color="#cc6633">$agent</font>=<font color="#0000ff">null</font>) {</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Declare&nbsp;known&nbsp;browsers&nbsp;to&nbsp;look&nbsp;for</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$known</font> = <font color="#0000ff">array</font>(<font color="#008000">'msie'</font>, <font color="#008000">'firefox'</font>, <font color="#008000">'safari'</font>, <font color="#008000">'webkit'</font>, <font color="#008000">'opera'</font>, <font color="#008000">'netscape'</font>,</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">'konqueror'</font>, <font color="#008000">'gecko'</font>);</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Clean&nbsp;up&nbsp;agent&nbsp;and&nbsp;build&nbsp;regex&nbsp;that&nbsp;matches&nbsp;phrases&nbsp;for&nbsp;known&nbsp;browsers</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;(e.g.&nbsp;"Firefox/2.0"&nbsp;or&nbsp;"MSIE&nbsp;6.0"&nbsp;(This&nbsp;only&nbsp;matches&nbsp;the&nbsp;major&nbsp;and&nbsp;minor</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;version&nbsp;numbers.&nbsp;&nbsp;E.g.&nbsp;"2.0.0.6"&nbsp;is&nbsp;parsed&nbsp;as&nbsp;simply&nbsp;"2.0"</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$agent</font> = <a href="http://www.php.net/manual/en/function.strtolower.php">strtolower</a>(<font color="#cc6633">$agent</font> ? <font color="#cc6633">$agent</font> : <font color="#cc6633">$_SERVER</font>[<font color="#008000">'HTTP_USER_AGENT'</font>]);</li>
<li>&nbsp;&nbsp;<font color="#cc6633">$pattern</font> = <font color="#008000">'#(?&lt;browser&gt;'</font> . <a href="http://www.php.net/manual/en/function.join.php">join</a>(<font color="#008000">'|'</font>, <font color="#cc6633">$known</font>) .</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">')[/&nbsp;]+(?&lt;version&gt;[0-9]+(?:\.[0-9]+)?)#'</font>;</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Find&nbsp;all&nbsp;phrases&nbsp;(or&nbsp;return&nbsp;empty&nbsp;array&nbsp;if&nbsp;none&nbsp;found)</font></li>
<li>&nbsp;&nbsp;<font color="#0000ff">if</font> (!<a href="http://www.php.net/manual/en/function.preg-match-all.php">preg_match_all</a>(<font color="#cc6633">$pattern</font>, <font color="#cc6633">$agent</font>, <font color="#cc6633">$matches</font>)) <font color="#0000ff">return array</font>();</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Since&nbsp;some&nbsp;UAs&nbsp;have&nbsp;more&nbsp;than&nbsp;one&nbsp;phrase&nbsp;(e.g&nbsp;Firefox&nbsp;has&nbsp;a&nbsp;Gecko&nbsp;phrase,</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;Opera&nbsp;7,8&nbsp;have&nbsp;a&nbsp;MSIE&nbsp;phrase),&nbsp;use&nbsp;the&nbsp;last&nbsp;one&nbsp;found&nbsp;(the&nbsp;right-most&nbsp;one</font></li>
<li>&nbsp;&nbsp;<font color="#696969">//&nbsp;in&nbsp;the&nbsp;UA).&nbsp;&nbsp;That's&nbsp;usually&nbsp;the&nbsp;most&nbsp;correct.</font></li>
<li>&nbsp;&nbsp;<font color="#cc6633">$i</font> = <a href="http://www.php.net/manual/en/function.count.php">count</a>(<font color="#cc6633">$matches</font>[<font color="#008000">'browser'</font>])-<font color="#008000">1</font>;</li>
<li>&nbsp;&nbsp;<font color="#0000ff">return array</font>(<font color="#cc6633">$matches</font>[<font color="#008000">'browser'</font>][<font color="#cc6633">$i</font>] =&gt; <font color="#cc6633">$matches</font>[<font color="#008000">'version'</font>][<font color="#cc6633">$i</font>]);</li>
<li>}</li>
<li><font color="#cc6633">$file_id</font>=(int)<font color="#cc6633">$_REQUEST</font>[<font color="#008000">'file_id'</font>];</li>
<li><font color="#0000ff">require</font>(<font color="#cc6633">$_SERVER</font>[<font color="#008000">"DOCUMENT_ROOT"</font>].<font color="#008000">"/bitrix/modules/main/include/prolog_before.php"</font>);</li>
<li><font color="#cc6633">$arr</font> = CFile::MakeFileArray(<font color="#cc6633">$file_id</font>);</li>
<li>&nbsp;</li>
<li><font color="#cc6633">$path</font> = CFile::GetPath(<font color="#cc6633">$file_id</font>);</li>
<li><font color="#cc6633">$ext</font> = <a href="http://www.php.net/manual/en/function.explode.php">explode</a>(<font color="#008000">'.'</font>, <font color="#cc6633">$path</font>);</li>
<li><font color="#cc6633">$ext</font> = <font color="#cc6633">$ext</font>[<a href="http://www.php.net/manual/en/function.count.php">count</a>(<font color="#cc6633">$ext</font>)-<font color="#008000">1</font>];</li>
<li>&nbsp;</li>
<li><font color="#cc6633">$description</font>=<font color="#cc6633">$arr</font>[<font color="#008000">'description'</font>];</li>
<li>&nbsp;</li>
<li><font color="#0000ff">if</font> (mb_strlen(<font color="#cc6633">$description</font>)&gt;<font color="#008000">200</font>)</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$description</font>=mb_substr(<font color="#cc6633">$description</font>,<font color="#008000">&nbsp;0</font>,<font color="#008000">200</font>).<font color="#008000">'...'</font>;</li>
<li><font color="#cc6633">$pattern</font> = <font color="#0000ff">array</font>(<font color="#008000">'"'</font>, <font color="#008000">'/'</font>, <font color="#008000">'\\'</font>, <font color="#008000">'*'</font>,<font color="#008000">'?'</font>,<font color="#008000">'&lt;'</font>,<font color="#008000">'&gt;'</font>,<font color="#008000">'|'</font>,<font color="#008000">':'</font>); </li>
<li><font color="#0000ff">for</font> (<font color="#cc6633">$i</font>=<font color="#008000">&nbsp;0</font>; <font color="#cc6633">$i</font>&lt;<a href="http://www.php.net/manual/en/function.sizeof.php">sizeof</a>(<font color="#cc6633">$pattern</font>); <font color="#cc6633">$i</font>++) { </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$description</font> = mb_ereg_replace(<font color="#cc6633">$pattern</font>[<font color="#cc6633">$i</font>], <font color="#008000">'&nbsp;'</font>, <font color="#cc6633">$description</font>); </li>
<li>} </li>
<li><font color="#cc6633">$ua</font>=browser_info();</li>
<li><font color="#0000ff">if</font> (<font color="#cc6633">$description</font>)</li>
<li>{</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$fname</font>=mb_convert_encoding(<font color="#cc6633">$description</font>,<font color="#008000">"UTF-8"</font>, <font color="#008000">"Windows-1251"</font> ).<font color="#008000">'.'</font>.<font color="#cc6633">$ext</font>;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font> (<font color="#0000ff">isset</font>(<font color="#cc6633">$ua</font>[<font color="#008000">'msie'</font>])) </li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#cc6633">$fname</font>=<font color="#cc6633">$description</font>.<font color="#008000">'.'</font>.<font color="#cc6633">$ext</font>;</li>
<li>}</li>
<li><font color="#0000ff">else</font> <font color="#cc6633">$fname</font>=<a href="http://www.php.net/manual/en/function.basename.php">basename</a>(<font color="#cc6633">$arr</font>[<font color="#008000">'tmp_name'</font>]);</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Type:&nbsp;'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'type'</font>]);</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Length:&nbsp;'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'size'</font>]);</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/manual/en/function.header.php">header</a>(<font color="#008000">'Content-Disposition:&nbsp;attachment;&nbsp;FILENAME="'</font>.<font color="#cc6633">$fname</font>.<font color="#008000">'";&nbsp;size="'</font>.<font color="#cc6633">$arr</font>[<font color="#008000">'size'</font>].<font color="#008000">'"'</font>);</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">echo</font> file_get_contents(<font color="#cc6633">$arr</font>[<font color="#008000">'tmp_name'</font>]);</li>
<li><font color="#cc6633">?&gt;</font> </li>
</ol>
<p></font></code></p></blockquote>
<h3>Ссылки по теме</h3>
<p><a href='http://greenbytes.de/tech/tc2231/'>Тесты на поддержку Content-Disposition в разных браузерах</a><br />
<a href='http://www.hanselman.com/blog/TheContentDispositionSagaControllingTheSuggestedFileNameInTheBrowsersSaveAsDialog.aspx'> Проблемы которые всплывают в различных версиях IE</a><br />
<a href='http://ru.wikipedia.org/wiki/Сравнение_файловых_систем'> Сравнение_файловых_систем</a> &#8212; смотрим на ограничения <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />
<a href='http://www.jtricks.com/bits/content_disposition.html'>Еще одно сравнение касательно IE</a><br />
Ну и конечно же <a href='http://www.ietf.org/rfc/rfc1806.txt'> RFC 1806</a> <img src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2010/03/01/%d1%81%d0%be%d1%85%d1%80%d0%b0%d0%bd%d0%b5%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d1%81-%d0%b4%d1%80%d1%83%d0%b3%d0%b8%d0%bc-%d0%b8%d0%bc%d0%b5%d0%bd%d0%b5%d0%bc-%d0%b2-1c-bitrix/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Небольшая доработка jTip</title>
		<link>https://itinsanity.wordpress.com/2009/07/29/%d0%bd%d0%b5%d0%b1%d0%be%d0%bb%d1%8c%d1%88%d0%b0%d1%8f-%d0%b4%d0%be%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-jtip/</link>
					<comments>https://itinsanity.wordpress.com/2009/07/29/%d0%bd%d0%b5%d0%b1%d0%be%d0%bb%d1%8c%d1%88%d0%b0%d1%8f-%d0%b4%d0%be%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-jtip/#comments</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Wed, 29 Jul 2009 11:11:51 +0000</pubDate>
				<category><![CDATA[Разработка]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jtip]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=106</guid>

					<description><![CDATA[Была поставлена задача сделать tooltip на сайте. Причем нужен он был только в одном месте, правда зная подход сегодня не нужно завтра нужно ,решил не заморачиваться, да и в верстке я не особо крут, поэтому решил воспользоваться плагином для jquery &#8212; jTip. Выглядит все симпатично, работает без нареканий, а так как на сайте уже использовался [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Была поставлена задача сделать tooltip на сайте. Причем нужен он был только в одном месте, правда зная подход сегодня не нужно завтра нужно ,решил не заморачиваться, да и в верстке я не особо крут, поэтому решил воспользоваться плагином для jquery  &#8212; <a href='http://codylindley.com/blogstuff/js/jtip/'>jTip</a>. Выглядит все симпатично, работает без нареканий, а так как на сайте уже использовался jQuery, то вообще все хорошо, вот только подгружает он страницы только извне. А меня бы вполне устроил функционал показать содержимое какого то скрытого блока как tooltip&#8217;a. И решил допилить.<br />
Открываем jtip.js и находим там function JT_show(url,linkId,title)<br />
Переходим к последней строчке $(&#8216;#JT_copy&#8217;).load(url);<br />
И заменяем ее на такую конструкцию<br />
<code><br />
	if (params['element_id']!==undefined)<br />
		$('#JT_copy').html($('#'+params['element_id']).html());<br />
	else<br />
	$('#JT_copy').load(url);<br />
</code><br />
Вуаля, теперь чтобы загрузить не содержимое страницы, а содержимое блока, надо всего лишь передать id блока как параметр element_id в любом урле. Я делал вот так<br />
<code><br />
<a href='?element_id=warning'>Warning</a><br />
</code><br />
Авось кому нибудь это поможет.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/07/29/%d0%bd%d0%b5%d0%b1%d0%be%d0%bb%d1%8c%d1%88%d0%b0%d1%8f-%d0%b4%d0%be%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d0%b0-jtip/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Мотиваторы</title>
		<link>https://itinsanity.wordpress.com/2009/07/15/%d0%bc%d0%be%d1%82%d0%b8%d0%b2%d0%b0%d1%82%d0%be%d1%80%d1%8b/</link>
					<comments>https://itinsanity.wordpress.com/2009/07/15/%d0%bc%d0%be%d1%82%d0%b8%d0%b2%d0%b0%d1%82%d0%be%d1%80%d1%8b/#respond</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Wed, 15 Jul 2009 21:28:12 +0000</pubDate>
				<category><![CDATA[Разное]]></category>
		<category><![CDATA[мотиватор]]></category>
		<category><![CDATA[программирование]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=102</guid>

					<description><![CDATA[На работе сделали и повесили пару мотиваторов. Один с &#171;Ты коммитил перед уходом ?&#187; повесили на дверь. и мотиватор &#171;Все ошибки в коде и странности в работе функций &#8212; чаще всего из-за своих КРИВЫХ РУК&#187;, который пришел в голову после убиения кучи времени и переписывания регекспов, когда выяснилось что они работали, но я не так [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>На работе сделали и повесили пару мотиваторов.<br />
Один с &#171;Ты коммитил перед уходом ?&#187; повесили на дверь.<br />
<img src='https://itinsanity.wordpress.com/wp-content/uploads/2009/07/motivator.png' width='100%'></p>
<p>и<br />
мотиватор &#171;Все ошибки в коде и странности в работе функций &#8212; чаще всего из-за своих КРИВЫХ РУК&#187;, который пришел в голову после убиения кучи времени и переписывания регекспов, когда выяснилось что они работали, но я не так проверял их работу.</p>
<p><img src='https://itinsanity.wordpress.com/wp-content/uploads/2009/07/facepalm2.jpg' width='100%'></p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/07/15/%d0%bc%d0%be%d1%82%d0%b8%d0%b2%d0%b0%d1%82%d0%be%d1%80%d1%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>

		<media:content url="https://itinsanity.wordpress.com/wp-content/uploads/2009/07/motivator.png" medium="image" />

		<media:content url="https://itinsanity.wordpress.com/wp-content/uploads/2009/07/facepalm2.jpg" medium="image" />
	</item>
		<item>
		<title>Синтез русской речи в Linux</title>
		<link>https://itinsanity.wordpress.com/2009/07/09/%d1%81%d0%b8%d0%bd%d1%82%d0%b5%d0%b7-%d1%80%d1%83%d1%81%d1%81%d0%ba%d0%be%d0%b9-%d1%80%d0%b5%d1%87%d0%b8-%d0%b2-linux/</link>
					<comments>https://itinsanity.wordpress.com/2009/07/09/%d1%81%d0%b8%d0%bd%d1%82%d0%b5%d0%b7-%d1%80%d1%83%d1%81%d1%81%d0%ba%d0%be%d0%b9-%d1%80%d0%b5%d1%87%d0%b8-%d0%b2-linux/#respond</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Thu, 09 Jul 2009 10:48:18 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=63</guid>

					<description><![CDATA[Кросспост моей статьи с хабра Прочитал статью про SAPI и Powershell (Учим PowerShell разговаривать), и мне стало интересно как же с синтезом русскоязычной речи в родной для меня операционке, Linux&#8217;e. Как выяснилось все далеко не так радужно, да и качество синтеза далеко до голоса Алены, но все же. Для синтеза речи в linux&#8217;e по традиции [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Кросспост моей статьи с <a href='http://habrahabr.ru/blogs/linux/60977/'>хабра </a><br />
Прочитал статью про SAPI и Powershell (<a href="http://habrahabr.ru/blogs/powershell/60965/">Учим PowerShell разговаривать</a>), и мне стало интересно как же с синтезом русскоязычной речи в родной для меня операционке, Linux&#8217;e. Как выяснилось все далеко не так радужно, да и качество синтеза далеко до голоса Алены, но все же. </p>
<p>Для синтеза речи в linux&#8217;e по традиции используется <a href="http://www.cstr.ed.ac.uk/projects/festival/download.html">Festival</a> последняя стабильная версия 1.95, но в поставке нет русского голоса, немного порыскав я набрел на <a href="http://festlang.berlios.de/docu/doku.php?id=russianru">проект по синтезу русской речи посредством Festival</a>, где написано что для работы с русским языком понадобится как минимум версия 1.96 бета. Ну ничего в Ubuntu 9.04 как раз такая и стоит. Дальше есть два варианта, либо собрать пакет самостоятельно, либо для пользователей Debian&#8217;a или Ubuntu поставить отдельный пакет, весит данное чудо ~190 метров, не хило так я бы сказал. Так как у меня Ubuntu решил поставить пакет. <br />
Пакет называется <a href="http://packages.ubuntu.com/karmic/festvox-ru">Festvox-ru</a>, и будет доступен в ubuntu начиная с версии 9.10, так как на руках 9.04, то скачиваем пакет и устанавливаем его в ручную. И тут вскрылась маленькая проблема. <br />
При попытке попросить festival произнести что то по русски он просто молчал, если же указывался язык <br />
<code>echo &quot;Проверка&quot; | festival --tts --language russian</code>, то вываливался c ошибкой:<br />
«Unsupported language, using English»<br />
SIOD ERROR: unbound variable: voice_rab_diphone<br />
festival: fatal error exiting.</p>
<p>Дамс, попробуем сделать так как в мануале, запускаем festival в интерактивном режиме, указываем голос принудительно (voice_msu_ru_nsh_clunits) и просим сказать что нибудь (SayText “Проверка”), вуаля все нормально работает, оформляем это в виде bash script&#8217;a и получаем</p>
<p><code>#!/bin/sh<br />
festival -b &quot;(begin (voice_msu_ru_nsh_clunits) (SayText \&quot;$1\&quot; nil))&quot;<br />
</code></p>
<p>Теперь сохраняем это в файл sayit.sh, назначаем права на запуск chmod a+x sayit.sh и проверяем<br />
./sayit.sh «Проверка»<br />
Ура! все работает. <br />
Если хотим прочить файл используем:</p>
<p><code>#!/bin/sh<br />
festival -b &quot;(begin (voice_msu_ru_nsh_clunits) (tts_file \&quot;$1\&quot; nil))&quot;<br />
</code></p>
<p>Но все же почему же у нас не заработал русский язык по умолчанию, копаем дальше.<br />
Немного гугления и мы находим багрепорт к debian&#8217;овцам от Сергея Кирпичева, <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=516262">вот этот багрепорт</a>. Похоже нам нужно подправить файл languages.scm/<br />
Так что идем в каталог /usr/share/festival где находим этот файл и вносим изменения. <br />
Дописываем вначале:</p>
<p><code>(define (language_russian)<br />
&quot;(language_russian)<br />
Set up language parameters for Russian.&quot;<br />
(set! male1 voice_msu_ru_nsh_clunits)<br />
(male1)<br />
(Parameter.set 'Language 'russian)<br />
)<br />
</code><br />
и в define(select_language language). добавляем пару строчек</p>
<p><code>((equal? language 'russian)<br />
(language_russian))<br />
</code><br />
Все теперь русский язык поддерживается.<br />
Пробуем прочитать файл.<br />
festival &#8212;language russian -tts festival.txt<br />
Ну что же все даже не так уж и плохо, единтвенное «но» это то что Festival достаточно заметно думает перед тем как начать произносить, и иногда ему не нравиться текст, например вместо того чтобы пропускать то что он не может произнести он вываливается с сообщением о <br />
LTS_Ruleset russian_downcase: no rule matches:<br />
LTS_Ruleset: # *here* &lt;a #<br />
Ну что же значит надо поубивать из текст ссылки.<br />
Пока что результат меня не особо радует, в принципе синтез русской речи под Linux с одной стороны возможен, с другой качество этого синтеза оставляет желать лучшего. А у меня появилось два новых шелл скрипта. sayit.sh и readit.sh ^_^<br />
Примеры озвучивания можно посмотреть в статье <a href="http://habrahabr.ru/blogs/apple/59387/">Учим iPod Shuffle G3 говорить по-русски</a></p>
<h5>Используемые источники:</h5>
<p>
<a href="http://www.opennet.ru/docs/RUS/bash_s&#99;ripting_guide/">Искусство программирования на языке сценариев командной оболочки</a><br />
<a href="http://festlang.berlios.de/docu/doku.php?id=russianru">Русский в Festival</a><br />
<a href="http://forum.sources.ru/index.php?showtopic=204030&amp;st=15">Новая база для синтеза речи, и голос для festival</a><br />
<a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=516262">Debian Bug report logs — #516262 festival: Please add support for &#8212;language russian</a><br />
<b>P.S.</b> по совету <a href="http://rengel_system.habrahabr.ru/" class="user_link">rengel_system</a> лучше вместо установки пакета ручками подключить <a href="https://launchpad.net/~sergey-udaltsov/+archive/ppa">этот репозиторий</a><br />
<b>P.P.S</b> по совету <a href="http://eugenex15.habrahabr.ru/" class="user_link">eugenex15</a> решил попробовать espeak. устанавливается очень просто, русский язык сразу из коробки, для сохранения образца голоса можно всего лишь добавить один параметр, но вот качество мне показалось просто ужасным. Наверно можно под строить произношение чтобы получить более менее цивильный результат, но у меня не получилось.<br />
<b>P.P.P.S</b> выложил два примера синтезируемой фразы при дефолтных параметрах в espeak и в festival<br />
<a href="http://narod.ru/disk/9342682000/espeak.wav.html">espeak</a><br />
<a href="http://narod.ru/disk/9342769000/festival.wav.html">festival</a><br />
(если кто может предложить другое место куда будет удобней положить wav&#8217;ки с удовольствием воспользуюсь)<br />
UPD: Ответ от хабраюзера <a href="http://vk2.habrahabr.ru/" class="user_link">vk2</a> <a href="http://www.box.net/shared/ibxoplkqbt">голос Алены</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/07/09/%d1%81%d0%b8%d0%bd%d1%82%d0%b5%d0%b7-%d1%80%d1%83%d1%81%d1%81%d0%ba%d0%be%d0%b9-%d1%80%d0%b5%d1%87%d0%b8-%d0%b2-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Новости на сайте посредством twitter&#8217;a</title>
		<link>https://itinsanity.wordpress.com/2009/07/09/%d0%bd%d0%be%d0%b2%d0%be%d1%81%d1%82%d0%b8-%d0%bd%d0%b0-%d1%81%d0%b0%d0%b9%d1%82%d0%b5-%d0%bf%d0%be%d1%81%d1%80%d0%b5%d0%b4%d1%81%d1%82%d0%b2%d0%be%d0%bc-twittera/</link>
					<comments>https://itinsanity.wordpress.com/2009/07/09/%d0%bd%d0%be%d0%b2%d0%be%d1%81%d1%82%d0%b8-%d0%bd%d0%b0-%d1%81%d0%b0%d0%b9%d1%82%d0%b5-%d0%bf%d0%be%d1%81%d1%80%d0%b5%d0%b4%d1%81%d1%82%d0%b2%d0%be%d0%bc-twittera/#comments</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Thu, 09 Jul 2009 08:55:37 +0000</pubDate>
				<category><![CDATA[Идеи]]></category>
		<category><![CDATA[Разработка]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[twitter]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=56</guid>

					<description><![CDATA[Twitter становится достаточно популярным, но немного не понятно для чего его стоит использовать большинству людей. Сообщать знакомым различные новости это интересно, но возможно можно придумать что то еще. Предположим у нас есть сайт. На котором что то постоянно происходит (пользователи добавляют новые ссылки, какие то небольшие изменения функционала), как на таком сайте должны выглядеть новости [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Twitter становится достаточно популярным, но немного не понятно для чего его стоит использовать большинству людей. Сообщать знакомым различные новости это интересно, но возможно можно придумать что то еще.<br />
Предположим у нас есть сайт. На котором что то постоянно происходит (пользователи добавляют новые ссылки, какие то небольшие изменения функционала), как на таком сайте должны выглядеть новости на главной странице или в боковом блоке? Небольшое описание новости, и если нужно ссылка на более подробный текст. Будет неплохо если про эти новости смогут прочитать в twitter аккаунте вашего сайта, или подпишутся на rss ленту. Так зачем же делать все это у себя, пусть twitter возьмет на себя хранение всех новостей на вашем сайте. Соответственно они будут в твиттере, и rss к ним будет предоставлен. Как мне кажется это удобно. Да и добавлять новость на сайт можно будет почти мгновенно, и при этом даже если сайт ляжет, сообщение об этом можно будет быстро послать в твиттер. Минус данного подхода в ограничение в 140 символов, которое налагает твиттер. Но зато новостям придется быть краткими и ясными. А для более подробного разъяснения можно поместить ссылку.<br />
Теперь рассмотрим несколько вариантов каким образом на главную страницу вашего сайта можно будет привнести твиттер.<br />
Тут можно различать два подхода:<br />
1) При формирование главной страницы скрипт получит список сообщений и выведет их.<br />
2) При открытии страницы пользователь ява скрипт подгрузит новости сам, и покажет их пользователю.<br />
Рассмотрим для начала первый вариант, он удобен тем что пользователь получает уже сформированную страницу, со всеми новостями, минус это то что мы должны устанавливать соединение и постоянно получать новости, что замедляет генерацию страниц, да и траффик дополнительные получается. Если мы реализуем серверную часть на php, то чтобы не разбираться самим с парсингом вывода twitter&#8217;a (а там очень много различных вариант на выбор, вот как надо реализовывать API) мы идем на <a href='http://phpclasses.org'>phpclasses</a>.<br />
Больше всего мне понравился <a href='http://www.phpclasses.org/browse/package/4075.html'>My Twitter</a> класс, даже не потребовалось допиливание. К тому же устанавливать статус все равно понадобится, например если какой либо пользователь добавил статью. Но что делать если у нас нет backend&#8217;a (мифический случай), или же задержка генерации страницы нас не устраивает. Тут мы переходим к способу номер 2.</p>
<p>Этот способ хорош тем что всю работу получения новостей берет на себя браузер пользователя, к тому же если задать интервал обновления то можно сделать так что новые новости пользователь увидет даже если не будет обновлять страницу. Минус в том что если у пользователя выключен js он не увидет новостей. Да и их загрузка через некоторое время после открытия главной страницы тоже может не понравится пользователю, но ведь этот способ можно использовать и для другого, например если у нас есть пользователь с указанным в профиле твиттер аккаунтом, мы можем подгрузить в профиль последние обновления twitter&#8217;а этого пользователя.<br />
Так как в последнее время я немного шаманю с jquery то первым делом я полез искать плагин работы с twitter&#8217;ом для него. Как никак у twitter&#8217;a есть json api и соответственно ничто не мешает реализовать твиттер клиент на js. Так как все придуманно до нас, то решение быстро нашлось, это <a href='http://coda.co.za/blog/2008/10/26/jquery-plugin-for-twitter'>jquery.twitter</a>,причем новая версия вышла вчера. Как удачно. Скачиваем и смотрим что внутри. Рисунок загрузчика, css&#8217;ка, jquery, плагин к нему и страничка с демо.<br />
Для формирования вывода используется Twitter HTML Badge Customizer, для этого в коде подключается внешний js файл. </p>
<pre>
$<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>getScript<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="PURPLE">"http://twitter.com/javascripts/blogger.js"</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT></pre>
<p>там определенны две функции twitterCallback2 которая собственно и формирует HTML код, и relative_time для формирования относительного времени (это запись в виде 5 days ago), я подумал что относительно время это хорошо, но надо пожалуй как то это дело руссифицировать. Встала проблема, так как в русском языке существительные принято склонять. И тут вспомнилась одна статья на хабре: <a href='http://mcaizer.habrahabr.ru/blog/11555/'>Склонение существительных с числительными</a> , косметические изменения и у нас есть такая же функция, но только переписанная на JavaScript.</p>
<pre>
<FONT COLOR="RED"><B>function</B></FONT> plural<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>n<FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT> form1<FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT> form2<FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT> form5<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT>
<FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
	n <FONT COLOR="BLUE" SIZE="+1">=</FONT> Math<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>abs<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>n<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">%</FONT> <FONT COLOR="BROWN">100</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
                n1 <FONT COLOR="BLUE" SIZE="+1">=</FONT> n <FONT COLOR="BLUE" SIZE="+1">%</FONT> <FONT COLOR="BROWN">10</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
                <FONT COLOR="RED"><B>if</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>n <FONT COLOR="BLUE" SIZE="+1">&gt;</FONT> <FONT COLOR="BROWN">10</FONT> <FONT COLOR="BLUE" SIZE="+1"><FONT COLOR="BLUE" SIZE="+1">&amp;</FONT><FONT COLOR="BLUE" SIZE="+1">&amp;</FONT></FONT> n <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BROWN">20</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="RED"><B>return</B></FONT> form5<FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
                <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>n1 <FONT COLOR="BLUE" SIZE="+1">&gt;</FONT> <FONT COLOR="BROWN">1</FONT> <FONT COLOR="BLUE" SIZE="+1"><FONT COLOR="BLUE" SIZE="+1">&amp;</FONT><FONT COLOR="BLUE" SIZE="+1">&amp;</FONT></FONT> n1 <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BROWN">5</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="RED"><B>return</B></FONT> form2<FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
                <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>n1 <FONT COLOR="BLUE" SIZE="+1">=</FONT><FONT COLOR="BLUE" SIZE="+1">=</FONT> <FONT COLOR="BROWN">1</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="RED"><B>return</B></FONT> form1<FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>

        <FONT COLOR="RED"><B>return</B></FONT> form5<FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
<FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT></pre>
<p>Теперь правим функцию relative_time и вуаля у нас теперь все как надо.</p>
<pre>
<FONT COLOR="RED"><B>function</B></FONT> relative_time<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>time_value<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
  <FONT COLOR="RED"><B>var</B></FONT> values <FONT COLOR="BLUE" SIZE="+1">=</FONT> time_value<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>split<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="PURPLE">" "</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  time_value <FONT COLOR="BLUE" SIZE="+1">=</FONT> values<FONT COLOR="BLUE" SIZE="+1"><B>[</B></FONT><FONT COLOR="BROWN">1</FONT><FONT COLOR="BLUE" SIZE="+1"><B>]</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">" "</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> values<FONT COLOR="BLUE" SIZE="+1"><B>[</B></FONT><FONT COLOR="BROWN">2</FONT><FONT COLOR="BLUE" SIZE="+1"><B>]</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">", "</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> values<FONT COLOR="BLUE" SIZE="+1"><B>[</B></FONT><FONT COLOR="BROWN">5</FONT><FONT COLOR="BLUE" SIZE="+1"><B>]</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">" "</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> values<FONT COLOR="BLUE" SIZE="+1"><B>[</B></FONT><FONT COLOR="BROWN">3</FONT><FONT COLOR="BLUE" SIZE="+1"><B>]</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="RED"><B>var</B></FONT> parsed_date <FONT COLOR="BLUE" SIZE="+1">=</FONT> Date<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>parse<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>time_value<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="RED"><B>var</B></FONT> relative_to <FONT COLOR="BLUE" SIZE="+1">=</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>arguments<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>length <FONT COLOR="BLUE" SIZE="+1">&gt;</FONT> <FONT COLOR="BROWN">1</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">?</FONT> arguments<FONT COLOR="BLUE" SIZE="+1"><B>[</B></FONT><FONT COLOR="BROWN">1</FONT><FONT COLOR="BLUE" SIZE="+1"><B>]</B></FONT> <FONT COLOR="BLUE" SIZE="+1">:</FONT> <FONT COLOR="BLUE" SIZE="+1">new</FONT> Date<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="RED"><B>var</B></FONT> delta <FONT COLOR="BLUE" SIZE="+1">=</FONT> parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>relative_to<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>getTime<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">-</FONT> parsed_date<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">1000</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  delta <FONT COLOR="BLUE" SIZE="+1">=</FONT> delta <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>relative_to<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>getTimezoneOffset<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">*</FONT> <FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>

  <FONT COLOR="RED"><B>if</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="PURPLE">'меньше минуты назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BROWN">120</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="PURPLE">'около минуты назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1">*</FONT>60<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">'  '</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> plural<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'минута'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'минуты'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'минут'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">' назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BROWN">120</FONT><FONT COLOR="BLUE" SIZE="+1">*</FONT>60<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="PURPLE">'около часа назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BROWN">24</FONT><FONT COLOR="BLUE" SIZE="+1">*</FONT>60<FONT COLOR="BLUE" SIZE="+1">*</FONT><FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="PURPLE">'около '</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">3600</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">'  '</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> plural<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">3600</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'час'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'часа'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'часов'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">' назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="RED"><B>if</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">&lt;</FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BROWN">48</FONT><FONT COLOR="BLUE" SIZE="+1">*</FONT>60<FONT COLOR="BLUE" SIZE="+1">*</FONT><FONT COLOR="BROWN">60</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="PURPLE">'1 день назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT> <FONT COLOR="RED"><B>else</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
    <FONT COLOR="RED"><B>return</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">86400</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> <FONT COLOR="PURPLE">' '</FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT> plural<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>parseInt<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>delta <FONT COLOR="BLUE" SIZE="+1">/</FONT> <FONT COLOR="BROWN">86400</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>toString<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'день'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'дня'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>,</B></FONT><FONT COLOR="PURPLE">'дней'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1">+</FONT><FONT COLOR="PURPLE">'  назад'</FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
  <FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT>
<FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT></pre>
<p>Теперь у нас на повестке дня ссылка на rss. Что же идем на <a href='http://www.feedicons.com/'>FeedIcons</a> и скачиваем подходящие нам иконки. И делаем небольшую поправку в самом плагине. </p>
<pre>
<FONT COLOR="RED"><B>if</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>o<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>showProfileLink<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT> <FONT COLOR="BLUE" SIZE="+1"><B>{</B></FONT>
	<FONT COLOR="RED"><B>var</B></FONT> profileLinkHTML <FONT COLOR="BLUE" SIZE="+1">=</FONT> <FONT COLOR="PURPLE">"&lt;p class=\"</FONT>profileLink\<FONT COLOR="PURPLE">"&gt;&lt;a href=\"</FONT>http<FONT COLOR="BLUE" SIZE="+1">:</FONT><FONT COLOR="GREEN"><I>//twitter.com/"+o.userName+"\"&gt;http://twitter.com/"+o.userName+"&lt;/a&gt;&amp;nbsp;&lt;a href='http://twitter.com/statuses/user_timeline/"+o.userName+".rss'&gt;&lt;img src='feed-icon.png'/&gt;&lt;/a&gt;&lt;/p&gt;";
</I></FONT>	c<FONT COLOR="BLUE" SIZE="+1"><B>.</B></FONT>append<FONT COLOR="BLUE" SIZE="+1"><B>(</B></FONT>profileLinkHTML<FONT COLOR="BLUE" SIZE="+1"><B>)</B></FONT><FONT COLOR="BLUE" SIZE="+1"><B>;</B></FONT>
<FONT COLOR="BLUE" SIZE="+1"><B>}</B></FONT>
</pre>
<p>Кстати чтобы не подгружать каждый раз blogger.js, да ведь мы и не можем ему менять, я просто закомментировал строку с его загрузкой, а исправленные функции, записал в конец jquery.twitter.js плагина.<br />
Ниже можно скачать то что у меня получилось.<br />
<a href='http://rghost.ru/338662'>Скачать поправленный для себя jquery.twitter</a></p>
<p>Пользователям может не понравится такой способ предоставления новостей, но мне кажется есть ресурсы где это может пригодиться, к тому же так можно оживить даже статичный сайт. Мы же живем в эпоху mash-up&#8217;a, так почему бы и нет.<br />
UPD: еще можно использовать <a href='http://juitter.com/'>Juitter</a> , тоже очень интересный плагин, автоматическое обновление в случае появления новых твиттов, реплаи, показ аватаров, поиск. Но мне почему то jquery.twitter нравится больше, он менее нагружен как мне кажется. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/07/09/%d0%bd%d0%be%d0%b2%d0%be%d1%81%d1%82%d0%b8-%d0%bd%d0%b0-%d1%81%d0%b0%d0%b9%d1%82%d0%b5-%d0%bf%d0%be%d1%81%d1%80%d0%b5%d0%b4%d1%81%d1%82%d0%b2%d0%be%d0%bc-twittera/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Структуризация информации. Контрольная точка 1</title>
		<link>https://itinsanity.wordpress.com/2009/05/09/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8%d0%bd%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%86%d0%b8%d0%b8-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8c/</link>
					<comments>https://itinsanity.wordpress.com/2009/05/09/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8%d0%bd%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%86%d0%b8%d0%b8-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8c/#respond</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Sat, 09 May 2009 21:35:38 +0000</pubDate>
				<category><![CDATA[Идеи]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=31</guid>

					<description><![CDATA[Как я писал мне хотелось бы чтобы вся информация на винте была структурированна, но как это сделать? У меня есть несколько задумок и я потихоньку реализую их. В плане СУБД планирую использовать MySQL, конечно по прикидкам база получается просто огого, мама не горюй, но вроде мускул должен вытянуть, пока не полностью ясно со структурой базы, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Как я писал мне хотелось бы чтобы вся информация на винте была структурированна, но как это сделать? У меня есть несколько задумок и я потихоньку реализую их. В плане СУБД планирую использовать MySQL, конечно по прикидкам база получается просто огого, мама не горюй, но вроде мускул должен вытянуть, пока не полностью ясно со структурой базы, то есть есть структура, и ее даже можно юзать, но вот что то там не так. Не знаю даже, слишком много кода надо чтобы с ней работать, библиотеки конечно писал начал, но не хочется в конце выяснить что фигня получилась. Пока что для импорта информации парсеры делаю, парсер для кинопоиска чтобы фильмы добавлять готов, парсер fb2 тоже.<br />
Есть простенькая библиотека для работы с базой, простой веб интерфейс и небольшая адресная книга накиданная с использованием его. Так что идем в верном направлении.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/05/09/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8%d0%bd%d1%84%d0%be%d1%80%d0%bc%d0%b0%d1%86%d0%b8%d0%b8-%d0%ba%d0%be%d0%bd%d1%82%d1%80%d0%be%d0%bb%d1%8c/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>Организация данных на локальной машине. Мечты.</title>
		<link>https://itinsanity.wordpress.com/2009/04/26/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bd%d0%b0-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d1%88%d0%b8/</link>
					<comments>https://itinsanity.wordpress.com/2009/04/26/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bd%d0%b0-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d1%88%d0%b8/#respond</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Sun, 26 Apr 2009 22:35:45 +0000</pubDate>
				<category><![CDATA[Идеи]]></category>
		<category><![CDATA[Каталогизация и хранение данных]]></category>
		<category><![CDATA[каталогизация]]></category>
		<category><![CDATA[gimao]]></category>
		<category><![CDATA[сортировка]]></category>
		<category><![CDATA[pim]]></category>
		<category><![CDATA[pvd]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/?p=27</guid>

					<description><![CDATA[Ну что же начнем с идей, которые могут показаться безумными, но я верю что их можно реализовать сейчас и работаю над этим. У Сэмми Джэнкиса была такая же проблема, но у него не было настоящей системы. Фильм &#171;Помни&#187;(Memento) Объем жестких дисков растет, и вам требуется способ организовать большое количество данных. Если не следовать какому либо [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Ну что же начнем с идей, которые могут показаться безумными, но я верю что их можно реализовать сейчас и работаю над этим.</p>
<div align='right'><i>У Сэмми Джэнкиса была такая же проблема, но у него не было настоящей системы.</i><br />
Фильм &#171;Помни&#187;(Memento)
</div>
<p>Объем жестких дисков растет, и вам требуется способ организовать большое количество данных. Если не следовать какому либо принципу, системе, то у вас будет всего лишь большущая свалка. И что с ней делать. И однажды наступит момент что вам будет проще найти то что вы ищете в интернете или у друзей чем у себя на винтах или на дисках. И вот тут приходится придумать способ организовывать данные. Если вы не собираетесь использовать никакого специализированного ПО, то возможно стоит постоить систему каталогов, верную для вас и с вашей точки зрения. Например я каталогизирую софт очень просто, у меня в корне лежат папки:</p>
<p><b>_distrs</b> &#8212; здесь лежат различные дистибьютивы windows, linux, reactos и других операционок<br />
<b>_linux</b> &#8212; здесь софт под linux<br />
<b>_macos</b> &#8212; здесь под маки<br />
<b>_pocket pc</b> &#8212; Windows Mobile &#8212; прошивки под разные устройства, софт и игры.<br />
<b>_windows</b> &#8212; тут под винду <br />
<b>_other</b> &#8212; а тут под то что не подпадает в категории выше</p>
<p>Пока были только папки _windows и _linux все было просто. в них шли софт и игры для каждой из осей. Потом дистры решено было вынести и теперь структура усложнилась. Софт разбит по категориям(уровень вложенности бывает очень велик например _net/_messaging/_irc/_client/mIRC)<br />
В папке с программой лежат подпапки версий, скриншоты и описания. Я стараюсь для всех программ поддерживаться этой системы. То что программы могут быть в нескольких категориях одновременно решается посредством симлинков. Но вот _pocket pc каталог это уже небольшой отделение от правил. Ибо прошивки, софт и игры там лежат в одной системе категория, хотя для винды и линукса это все вынесенно отдельно. (Игры лежат на отдельном разделе отсортированные тоже по осям.)</p>
<p>Такая система была достаточно удобно на ранних порах. Но чем сложнее становяться запросы, и чем больше становиться программ, тем менее удобной становится такая система. Получается что надо выдумывать какую то более гибкую структуру. Симлинки конечно помогут, но как быть с удаленнием данных. Надо же будет после этого обновлять все симлинки. Либо писать скрипт который будет оббегать каталоги в поисках симлинков и грохать их.<br />
Еще один подход для хранения использовать папку с кучей файлов, отсортированных как угодно, но для обращения и операциями с ними использовать специальные программы каталогизаторы. Например для фильмов это <a href='http://videodb.info'>Personal Video Database</a>. А что вроде бы все удобно. Но вот что вам делать если вам нужно использовать эту программу например под Linux&#8217;ом. У меня под вайном она идет как то не стабильно. Да и повлиять на ее развитие никак не получится. Но это уже шаг к лучшей системе.</p>
<div align='right'><i>Вам нужна действительно хорошая система,если Вы хотите заставить её работать.</i><br />
Фильм &#171;Помни&#187;(Memento)
</div>
<p>Перейдем к хранению музыки. Например для этого будем использовать плейер с поддержкой медиа библиотек. Amarok, Windows Media Player, Banshee,Songbird, iTunes и т.д. ибо имя им легион, их очень много, но при этом я не могу привязать какую то песню к какому то фильму из коллекции, я не могу посмотрев фильм нажатием кнопки перенести его содержимое в плейер.  Да я понимаю что я хочу невозможного. Я хочу систему где все данные будут взаимосвязанны, где не будет понятия файл, а будет понятие фильм, песня, программа. Где все будет связанно между собой. Я хочу иметь возможность создавать сложные выборки на манер того чтобы получить список всех программ у меня на винте под определенной лицензии и в определенной категории, а затем записать их на диск.</p>
<p>Единственный способ на лету менять условия поиска, это если данные будут занесенны в какую либо систему, где они будут связанны между собой, где будут описаны все их свойства. Похожий подход исповедует проект <a href="http://nepomuk.semanticdesktop.org">Nepomuk</a>(Под сенью KDE хранилищу дали более красивое имя Soprano). Интересное решение, к тому же для хранения используется RDF. Но чем то оно мне не нравится(Может потому что на текущий момент это концепт который непонятно как использовать).</p>
<p>Ну что же получается для того чтобы все было разложенно по полочкам нам нужно занести это все в одну базу данных и написать к ней интерфейс. Но ведь интерфейс будет разный. С музыкой и с фильмами мы работаем по разному. И поля у них разные, и хотелось бы чтобы данные автоматически тянулись с интернета, так как вбивать их все вручную это самоубийство.</p>
<p>Но что то вбивать все равно придется, поэтому до того как будет сделана чудо система позволяющая организовать все, правильней использовать такие имена и пути для файлов, на основе которых можно было бы упростить импорт этих данных в эту мифическую систему. Например в название с файлом фильма указывать не только переведенное название, но и оригинальное и год выпуска. Таким образом можно будет с минимальными вмешательствами обработать все файлы пачкой. Тоже самое с клипами, музыкой. Если у вас есть клипы Iron Maiden пусть они все начинаются с названия группы и затем после пробела и дефиса с еще одним пробелом идем название композиции, в итоге если все соответствует этой структуре можно быстро обработать горы файлов.</p>
<p>На хабре проскакивала <a href='http://habrahabr.ru/company/gimao/blog/51731/'>статья</a> про <a href='http://www.gimao.com'>Gimao</a>. Интересная программа, я думал что возможно будет использовать ее. Но бета есть бета, к тому же если ей удобно организовывать большие объемы информации формировать запросы типо тех что мне хотелось пока сложно если не сказать невозможно. Правда она и не позицинионируется как хранилище данных. Это PIM. </p>
<p>Кстати PIM это вообще отдельный разговор. Как я представляю себе идеальную адресную книгу. В ней есть что то от социальных сетей(куча заполненных данных, связи между записями), она синхронизирует свои данные с интернетом (с аккаунтами в различных социальных сетях), она хранит в себе логи разговоров, время и даты звонков. А еще мне бы хотелось чтобы она интегрировалась с общей системой хранения данных. Я хочу открыв адресную книгу и увидя там знакомого Васю, посмотреть фотки с его последнего отпуска, узнать что у него есть друг Витя, которому нравиться фильм Генетическая опера, увидеть что этот фильм есть у меня, посмотреть трейлер, почитать отзывы, после чего узнав что там неплохая музыка, открыть OST к фильму если он есть у меня на машине и скинуть его на плейер чтобы послушать в дороге. Мне нужно чтобы он автоматом искал его и скачивал, но я хочу чтобы любая информация которая у меня есть лежала по полочкам.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/04/26/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%bd%d0%b0-%d0%bb%d0%be%d0%ba%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d1%88%d0%b8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
		<item>
		<title>.Net CF программное управление bluetooth</title>
		<link>https://itinsanity.wordpress.com/2009/02/02/net-cf-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%bd%d0%be%d0%b5-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-bluetooth/</link>
					<comments>https://itinsanity.wordpress.com/2009/02/02/net-cf-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%bd%d0%be%d0%b5-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-bluetooth/#respond</comments>
		
		<dc:creator><![CDATA[thekillerfox]]></dc:creator>
		<pubDate>Mon, 02 Feb 2009 13:56:00 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Разработка]]></category>
		<category><![CDATA[Windows Mobile]]></category>
		<category><![CDATA[.net cf]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[wm5]]></category>
		<category><![CDATA[wm6]]></category>
		<guid isPermaLink="false">http://itinsanity.wordpress.com/2009/02/02/net-cf-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%bd%d0%be%d0%b5-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-bluetooth/</guid>

					<description><![CDATA[Для начала нам нужно подключить пространство имен System.Runtime.InteropServices using System.Runtime.InteropServices; Теперь создаем свой класс : public class Network&#123;&#160; &#160; &#160;public enum BluetoothMode&#160; &#160; &#160;&#123;&#160; &#160; &#160; &#160; &#160; Off=0,&#160; &#160; &#160; &#160; &#160; Connectable=1,&#160; &#160; &#160; &#160; &#160; Discoverable=2&#160; &#160; &#160;&#125;&#160; &#160; &#160;&#91;DllImport&#40;&#34;BthUtil.dll&#34;&#41;&#93;&#160; &#160; &#160;private static extern int BthGetMode&#40;out BluetoothMode dwMode&#41;;&#160; &#160; &#160;&#91;DllImport&#40;&#34;BthUtil.dll&#34;&#41;&#93;&#160; &#160; &#160;public [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Для начала нам нужно подключить пространство имен System.Runtime.InteropServices</p>
<div class="csharp" style="font-family:monospace;color:#000000;"><span style="color:#0600FF;">using</span> <span style="color:#000000;">System</span>.<span style="color:#0000FF;">Runtime</span>.<span style="color:#0000FF;">InteropServices</span>;</div>
<p>Теперь создаем свой класс :</p>
<div class="csharp" style="font-family:monospace;color:#000000;"><span style="color:#0600FF;">public</span> <span style="color:#FF0000;">class</span> Network<br /><span style="color:#000000;">&#123;</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#0600FF;">public</span> <span style="color:#FF0000;">enum</span> BluetoothMode<br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#123;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Off=<span style="color:#FF0000;">0</span>,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Connectable=<span style="color:#FF0000;">1</span>,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Discoverable=<span style="color:#FF0000;">2</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#125;</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#91;</span>DllImport<span style="color:#000000;">&#40;</span><span style="color:#808080;">&quot;BthUtil.dll&quot;</span><span style="color:#000000;">&#41;</span><span style="color:#000000;">&#93;</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#0600FF;">private</span> <span style="color:#0600FF;">static</span> <span style="color:#0600FF;">extern</span> <span style="color:#FF0000;">int</span> BthGetMode<span style="color:#000000;">&#40;</span><span style="color:#0600FF;">out</span> BluetoothMode dwMode<span style="color:#000000;">&#41;</span>;<br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#91;</span>DllImport<span style="color:#000000;">&#40;</span><span style="color:#808080;">&quot;BthUtil.dll&quot;</span><span style="color:#000000;">&#41;</span><span style="color:#000000;">&#93;</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#0600FF;">public</span> <span style="color:#0600FF;">static</span> <span style="color:#0600FF;">extern</span> <span style="color:#FF0000;">int</span> BthSetMode<span style="color:#000000;">&#40;</span>BluetoothMode dwMode<span style="color:#000000;">&#41;</span>;<br />&nbsp; &nbsp; &nbsp;<span style="color:#0600FF;">public</span> <span style="color:#0600FF;">static</span> <span style="color:#FF0000;">String</span> GetBthMode<span style="color:#000000;">&#40;</span><span style="color:#000000;">&#41;</span><br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#123;</span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BluetoothMode mode;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF0000;">int</span> ret = BthGetMode<span style="color:#000000;">&#40;</span><span style="color:#0600FF;">out</span> mode<span style="color:#000000;">&#41;</span>;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0600FF;">return</span> mode.<span style="color:#0000FF;">ToString</span><span style="color:#000000;">&#40;</span><span style="color:#000000;">&#41;</span>;<br />&nbsp; &nbsp; &nbsp;<span style="color:#000000;">&#125;</span><br /><span style="color:#000000;">&#125;</span></div>
<p>Теперь мы можем попробовать переключить статусы. Например вот так :</p>
<div class="csharp" style="font-family:monospace;color:#000000;"><span style="color:#0600FF;">if</span> <span style="color:#000000;">&#40;</span>Network.<span style="color:#0000FF;">GetBthMode</span><span style="color:#000000;">&#40;</span><span style="color:#000000;">&#41;</span> == <span style="color:#808080;">&quot;Off&quot;</span><span style="color:#000000;">&#41;</span>&nbsp; <span style="color:#008080;font-style:italic;">//Проверяем текущее состояние</span><br />&nbsp; &nbsp; Network.<span style="color:#0000FF;">BthSetMode</span><span style="color:#000000;">&#40;</span>Network.<span style="color:#0000FF;">BluetoothMode</span>.<span style="color:#0000FF;">Connectable</span><span style="color:#000000;">&#41;</span>; <span style="color:#008080;font-style:italic;">//Переводим в состояние Connectable</span><br /><span style="color:#0600FF;">else</span> Network.<span style="color:#0000FF;">BthSetMode</span><span style="color:#000000;">&#40;</span>Network.<span style="color:#0000FF;">BluetoothMode</span>.<span style="color:#0000FF;">Off</span><span style="color:#000000;">&#41;</span>; <span style="color:#008080;font-style:italic;">// или же выключаем</span></div>
]]></content:encoded>
					
					<wfw:commentRss>https://itinsanity.wordpress.com/2009/02/02/net-cf-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%bd%d0%be%d0%b5-%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-bluetooth/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		
		<media:content url="https://1.gravatar.com/avatar/4e56a844460d313255f1fa62439d333c648ae9e903949ca01a6aad462aad33f2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">thekillerfox</media:title>
		</media:content>
	</item>
	</channel>
</rss>
