TagPy из командной строки

12 Январь 2011 Нет комментариев

Простой скрипт для записи и чтения тегов в UTF с помощью TagPy (taglib) из командной строки.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import tagpy, chardet
import optparse
 
# Как вариант - можно просто сделать 
# def cp(t):
#     return t
# но тогда не будет поддержки utf
 
def cp(t):
    t = t.strip()
    if t == '':
        return ''
    try: 
        s = t.encode('latin1')
    except:
        return t
    try:
        d = chardet.detect(s)
    except:
        d = {}
        d['encoding'] = ''
    if d['encoding'] == 'ascii':
        return s.decode('utf-8')
    if d['encoding'] == 'windows-1251':
        return s.decode('windows-1251')
 
    try:
        return s.decode('utf-8')
    except:
        pass
 
    try:
        return s.decode('windows-1251')
    except:
        pass
    return ''
 
 
class tagger:
    def write(self, to, tag):
        f = tagpy.FileRef(to)
        t = f.tag()
        t.artist = cp(tag['artist'])
        t.title = cp(tag['title'])
        try:
            track = int(tag['track'])
        except:
            track = 0
        t.track = track
        try:
            year = int(tag['year'])
        except:
            try:
                year = int(tag['year'][0:4])
            except:
                year = 0
        t.year = year
        t.album = cp(tag['album'])
        f.save()
    def read(self, to):
        f = tagpy.FileRef(to)
        t = f.tag()
        tag = {}
        tag['artist'] = t.artist
        tag['title'] = t.title
        tag['track'] = str(t.track)
        tag['year'] = str(t.year)
        tag['album'] = t.album
        return tag
 
def main():
    p = optparse.OptionParser()
    p.add_option('--title', '-t', default="")
    p.add_option('--album', '-A', default="")
    p.add_option('--artist', '-a', default="")
    p.add_option('--year', '-y', default=0)
    p.add_option('--track', '-T', default=1)
    p.add_option('--genre', '-g', default='')
    o, a = p.parse_args()
    tag = {}
    tag['title'] = o.title.decode('utf8')
    tag['album'] = o.album.decode('utf8')
    tag['artist'] = o.artist.decode('utf8')
    tag['year'] = o.year
    tag['track'] = o.track
    tg = tagger()
    tg.write(a[0], tag)
    exit(0)
if __name__ == '__main__':
    main()
Share
Tags:

FreeBSD и Sil5723 PM

21 Декабрь 2010 Нет комментариев

Очень долго мучался с определением этого разветвителя на фре.

Чтобы оно определилось нормально, нужно прописать в /boot/loader.conf:
ahci_load="YES"
все по волшебшебству заработало.

Share
Tags:

Как собрать Lame с поддержкой UTF8 во FreeBSD

21 Декабрь 2010 Нет комментариев


# cd /usr/ports/audio/lame
в Makefile добавляем
CONFIGURE_ENV= CFLAGS="${CFLAGS} -DHAVE_ICONV -L/usr/local/lib -liconv"
# make install clean

после этого можно использовать флаги –uTitle –uArtist –uAlbum LAME для записи ID3v2 в корректной кодировке на системе с UTF8 локалью.

Share
Tags:

IE и баг ExternalInterface

Есть div. В него через SWFObject вставляется флеш ролик. Дальше назначаем ему visibility=»hidden» ну или display:hidden, или хоть сдвигаем влево на -10000пикс.
Ну мало ли, вкладки там у нас, еще чего такое – красивое удобное.
Возвращаем элемент, установив visibility=»visible»
Результат:
Адекватные броузеры – все работает.
ИЕ:
Загеристрированные роликом вызовы ExternalInterface (т.е. каллбеки для жаваскриптов) пропали. Нету и все тут.

Решение нашел только одно – персонально детектим ИЕ и перегружаем-с ролик персонально для него SWFObject’ом при переключении на вкладку ))

Share
Tags:

Красивые и простые вкладки jquery

<ul class="prta">
	<li><a href="#one"><span>Первая вкладка</span></a></li>
	<li class="pcurr"><a href="#two"><span>Вторая</span></a></li>
</ul>
<div id="two" style="width: 760px;">
<table class="pr" style="width: 760px;" border="0">
<tbody>
<tr class="t">
<td class="l" colspan="2"></td>
<td class="m">Заголовок 1</td>
<td class="f" colspan="2"></td>
</tr>
<tr class="m">
<td class="l"></td>
<td class="s"></td>
<td class="m">Текст первой вкладки</td>
<td class="s"></td>
<td class="r"></td>
</tr>
<tr class="b">
<td class="l" colspan="2"></td>
<td class="m"></td>
<td class="r" colspan="2"></td>
</tr>
</tbody></table>
</div>
<div id="two" style="width: 760px;">
<table class="pr" style="width: 760px;" border="0">
<tbody>
<tr class="t">
<td class="l" colspan="2"></td>
<td class="m">Заголовок 2</td>
<td class="f" colspan="2"></td>
</tr>
<tr class="m">
<td class="l"></td>
<td class="s"></td>
<td class="m">Текст второй вкладки</td>
<td class="s"></td>
<td class="r"></td>
</tr>
<tr class="b">
<td class="l" colspan="2"></td>
<td class="m"></td>
<td class="r" colspan="2"></td>
</tr>
</tbody></table>
</div>
<script type="text/javascript"><!--mce:0--></script>
.pr{
border:none;
border-collapse:collapse;
table-layout:fixed;
}
 
.pr td{
vertical-align:top;
}
 
.pr tr.t td.m{
background: url('p-t-m.png') repeat-x top left;
height:24px;
padding-top:3px;
padding-left:10px;
text-align:center;
font-size:13px;
color: #494949;
font-weight:bold;
}
 
.pr tr.t td.l{
background: white url('p-t-l.png') no-repeat top left;
width:12px;
height:27px;
}
 
.pr tr.t td.r{
background: url('p-t-r.png') no-repeat top right;
width:12px;
height:27px;
}
 
.pr tr.t td.f{
background: url('p-t-f.png') no-repeat top right;
width:12px;
height:27px;
}
 
.pr tr.m td.m{
background: white repeat-x repeat-y;
width:100%;
padding:7px;
height:180px;
min-height:180px;
}
 
.pr tr.m td.s{
background-color:white;
width:4px;
}
 
.pr tr.m td.l{
background: #e7e7e7 url('p-side.png') no-repeat top left;
width:6px;
}
 
.pr tr.m td.r{
background: #e7e7e7 url('p-side.png') no-repeat top right;
width:6px;
}
 
.pr tr.b td.l{
background: transparent url('p-b-l.png') no-repeat top left;
width:11px;
height:10px;
}
 
.pr tr.b td.r{
background: transparent url('p-b-r.png') no-repeat top right;
width:11px;
height:10px;
}
 
.pr tr.b td.m{
background: transparent url('p-b-m.png') repeat-x top left;
height:10px;
}
 
ul.prta li{
background: url('t-b-l.png') no-repeat top left;
display:block;
float:right;
height:22px;
margin-left: 3px;
}
 
ul.prta li a{
display:block;
background: url('t-b-r.png') no-repeat top right;
height: 22px;
text-decoration:none;
border-collapse:collapse;
padding-left: 2px;
padding-right: 2px;
}
 
ul.prta li a span{
text-align:center;
display:block;
background: url('t-b-m.png') repeat-x top left;
height: 20px;
font-size:12px;
padding-top:2px;
color:#f3f3f3;
text-decoration:none;
border-collapse:collapse;
padding-left:5px;
padding-right:5px;
}
 
ul.prta li.pcurr{
background: url('t-w-l.png') no-repeat top left;
}
 
ul.prta li.pcurr a{
background: url('t-w-r.png') no-repeat top right;
}
 
ul.prta li.pcurr a span{
background: url('t-w-m.png') repeat-x top left;
color:#333333;
}

Картинки бордеров и углов брать тут, демо тут, скачать тут

Share

Почему сессии – зло?

28 Апрель 2009 Нет комментариев
  • адски тормозят если на файлах
  • адски глючат если в мемкешд
  • рандомно теряются
  • сложно проверить что же там все таки на самом деле есть

Не используйте сессии. Используйте куки, бд и файлы.

Только что два часа промучался с потерями сессии в swfupload. Что только ни делал, а после вызова session_id() – причем с нужным ИД в параметре! – сессия пустая. Так и не нашел где проблема. Возможно где-то в настройках сервера. Забил на все, передаю через POST вместо сессии логин и пароль юзверя…

Share
Tags: ,

Красивая разбивка на страницы в php

28 Апрель 2009 Нет комментариев

28041
28014

Параметры в основном отвечают за разные части урлов.
Из названий параметров почти все понятно, однако код поковырять под себя Вам все равно придется.

css:

div.pagination {
margin:3px;
padding:3px;
}
 
div.pagination a {
border:1px solid #aad;
text-decoration:none;
color:#009;
margin:2px;
padding:2px 5px;
}
 
div.pagination a:hover,div.pagination a:active {
border:1px solid #f8aa44;
color:#000;
}
 
div.pagination span.current {
border:1px solid silver;
font-weight:700;
background-color:silver;
color:#fff;
margin:2px;
padding:2px 5px;
}
 
div.pagination span.disabled {
border:1px solid #eee;
color:#ddd;
margin:2px;
padding:2px 5px;
}

php

function paginate($total_pages,$perpage,$pagname,$page=1,$plex1="index",$plex="index",$ext=".htm",$return=0,$top=1)
{
    global $leng,$path,$page_content;
$adjacents = 3;                                //количество показываемых смежных страниц
if ($page == 0) $page = 1;                    //Если страница не указана, то по умолчанию 1.
$prev = $page - 1;                            //предыдущая страница
$next = $page + 1;                            //Следующая страница
$lastpage = ceil($total_pages/$perpage);    //последняя страница = все_страницы/элем_на_стр, округленное вверх
$lpm1 = $lastpage - 1;                        //послденяя страница-1
 
$pagination = "";
if($lastpage &gt; 1)
{
    $pagination .= "
<div class="\&quot;pagination\&quot;" style="\">";
    //Кнопка назад
    if ($page &gt; 1)
        if ($prev==1) $pagination.= "<a class="\&quot;ajax" href="\">«</a>";
        else $pagination.= "<a class="\&quot;ajax" href="\">«</a>";
    else
        $pagination.= "<span class="\&quot;disabled\&quot;">«</span>";   
 
    //страницы
    if ($lastpage &lt; 7 + ($adjacents * 2))    //Страниц мало, показать все страницы
    {
        if ($page==1) $pagination.= "<span class="\&quot;current\&quot;">1</span>";
        else $pagination.= "<a class="\&quot;ajax" href="\">1</a>";
        for ($counter = 2; $counter &lt;= $lastpage; $counter++)
        {
            if ($counter == $page)
                $pagination.= "<span class="\&quot;current\&quot;">$counter</span>";
            else
                $pagination.= "<a class="\&quot;ajax" href="\">$counter</a>";
        }
    }
    elseif($lastpage &gt; 5 + ($adjacents * 2))    //Страниц много, некоторые прячем
    {
        //Близко к началу, прячем из конца
        if($page &lt; 1 + ($adjacents * 2))
        {
 
                if ($page==1)
                    $pagination.= "<span class="\&quot;current\&quot;">1</span>";
                else
                    $pagination.= "<a class="\&quot;ajax" href="\">1</a>";
            for ($counter = 2; $counter &lt; 4 + ($adjacents * 2); $counter++)
            {
                if ($counter == $page)
                    $pagination.= "<span class="\&quot;current\&quot;">$counter</span>";
                else
                    $pagination.= "<a class="\&quot;ajax" href="\">$counter</a>";
            }
            $pagination.= "...";
            $pagination.= "<a class="\&quot;ajax" href="\">$lpm1</a>";
            $pagination.= "<a class="\&quot;ajax" href="\">$lastpage</a>";
        }
        //В середине, прячем из начала и из конца
        elseif($lastpage - ($adjacents * 2) &gt; $page &amp;&amp; $page &gt; ($adjacents * 2))
        {
            $pagination.= "<a class="\&quot;ajax" href="\">1</a>";
            $pagination.= "<a class="\&quot;ajax" href="\">2</a>";
            $pagination.= "...";
            for ($counter = $page - $adjacents; $counter &lt;= $page + $adjacents; $counter++)
            {
                if ($counter == $page)
                    $pagination.= "<span class="\&quot;current\&quot;">$counter</span>";
                else
                    $pagination.= "<a class="\&quot;ajax" href="\">$counter</a>";
            }
            $pagination.= "...";
            $pagination.= "<a class="\&quot;ajax" href="\">$lpm1</a>";
            $pagination.= "<a class="\&quot;ajax" href="\">$lastpage</a>";
        }
        //Близко к концу, прячем начальные страницы
        else
        {
            $pagination.= "<a class="\&quot;ajax" href="\">1</a>";
            $pagination.= "<a class="\&quot;ajax" href="\">2</a>";
            $pagination.= "...";
            for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter &lt;= $lastpage; $counter++)
            {
                if ($counter == $page)
                    $pagination.= "<span class="\&quot;current\&quot;">$counter</span>";
                else
                    $pagination.= "<a class="\&quot;ajax" href="\">$counter</a>";
            }
        }
    }
 
    //Кнопка вперед
    if ($page &lt; $counter - 1)
        $pagination.= "<a class="\&quot;ajax" href="\">»</a>";
    else
        $pagination.= "<span class="\&quot;disabled\&quot;">»</span>";
    $pagination.= "</div>
\n";
}
$pagination=''.$pagination.'';
if ($top) $page_content=$pagination.$page_content;
if ($return) return $pagination;
$page_content.=$pagination;
}
Share

Красивые превьюшки (php+imagick)

28 Декабрь 2008 Нет комментариев

Создаем красивые превьюшки. Требует, чтобы на сервере был установлен ImageMagick и расширение для php imagick.

// Функция для нахождения размера новой картинки при данном
// минимальном и максимальном размере.
function scaleImage($x,$y,$cx,$cy) {
    list($nx,$ny)=array($x,$y);   
    if ($x>=$cx || $y>=$cx) {
        if ($x>0) $rx=$cx/$x;
        if ($y>0) $ry=$cy/$y;
        if ($rx>$ry) {
            $r=$ry;
        } else {
            $r=$rx;
        }
        $nx=intval($x*$r);
        $ny=intval($y*$r);
    }   
    return array($nx,$ny);
}
// Получаем имя файла картинки и ее папку, менять по вкусу
$img=stripslashes($_GET['img']);
$fold=stripslashes($_GET['fold']);
// Заметьте, в целях безопасности расширение jpg
// прописано жестко - можете это убрать если нужно.
$fullpath='/home/user/img/'.$fold.'/'.$img.'.jpg';
// Проверяем, что картинка на месте.
if (!file_exists($fullpath)) die ('Файл не существует');
$thumb = new Imagick($fullpath);
//Белый фон
$canvas = new Imagick();
//Eсли нужно не белый 
//$canvas ->setImageBackgroundColor(new ImagickPixel('black'));
list($newX,$newY)=scaleImage(
        $thumb->getImageWidth(),
        $thumb->getImageHeight(),
        150, 150);
// последние две цифры - размер самой превьюшки,
// НЕ СЧИТАЯ ТЕНЬ. (т.е. надо указать нужный размер-10пикс.)
 
$canvas->newImage($newX+10, $newY+10, new ImagickPixel("white"));
//Собственно делаем превьюшку
$thumb->thumbnailImage($newX,$newY);
 
//Немного улучшает маленькие превьюшки
if ($width < 300) $thumb->sharpenImage(4, 1);
//Скругляем углы
$thumb->roundCorners(5, 5);
//Клонируем картинку чтобы получить тень
$shadow = $thumb->clone();
//Цвет тени = black, при желании меняем по вкусу
$shadow->setImageBackgroundColor(new ImagickPixel('black'));
//Создаем тень
$shadow->shadowImage(80, 2.5, 5, 5);
//Накладываем тень на полотно
$canvas->compositeImage($shadow, $shadow->getImageCompose(),0,0);
//Накладываем превьюшку на полотно
$canvas->compositeImage($thumb, $thumb->getImageCompose(),0,0);
$canvas->stripImage();
 
// тип картинки
header( "Content-Type: image/jpg" );
// если не нужен непосредственный вывод предыдущую строчку нужно убрать.
 
$canvas->setImageFormat('jpg');
$canvas->setImageDepth(8);
 
// Это - непосредственно вывод картинки в броузер пользователя.
// дальнейшее отвечает за кеширование (etag, last-modified, expires)
// При желании это все можно убрать, вплоть до вывода картинки, но я не советую.
$last_modified_time = filemtime($fullpath); 
// Время кеширования, если картинка статичная, смело ставьте побольше (например 360000000)
$time = time() + 3600;
 
header('Expires: '.gmdate('D, d M Y H:i:s', $time).' GMT');
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
$etag = md5($canvas); 
header("Etag: $etag"); 
 
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||
    trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
    header("HTTP/1.1 304 Not Modified");
    exit; 
	}
 
echo $canvas;
 
//Если хотим сохранить полученную превьюшку в файл
//$canvas->writeImage($writeTo);
//приберемся
$canvas->destroy();
$shadow->destroy();
$thumb->destroy();

Готовая превьюшка

Share
Tags:

Табы в MooTools

28 Декабрь 2008 Нет комментариев

MorphTabs

Демо Страница

Вариант MooTabs для версии 1.2 MooTools. Полезно для выдачи небольшой или среднего размера части страницы так чтобы для поисковиков она выглядела как одна страница, а для пользователя – как несколько. Также возможен AJAX вариант, т.е. содержание подгружается при нажатии. Однако, это не лучшим образом скажется на индексируемости в поиске.

6

Share
Tags:

Красивые менюшки на JavaScript

28 Декабрь 2008 Нет комментариев

1. Красивый аккордеон

Страница

Выглядит красиво, анимация тоже ничего, однако, немного неаккуратно.

nice-acc

2. ImageMenu

Страница

Красивая переключающаяся менюшка из картинок. Работает на MooTools, однако использует старую версию, 1.11.

2

3. Выпадающее меню

Демо Страница

Простая выпадающая менюшка на MooTools. Выглядит на четверочку, можно попользовать если переделать.

3

4. Simple

Страница

Самая обычная менюшка, куча css, явы совсем немного.

41

5. Sliding

Демо Страница

Очень красивая ява менюшка с полупрозрачностью и приятными переходами. Также есть вертикальный вариант, и многоуровневый вариант.

5

Share
Tags: