Итак, обещанный конкурс на лучший скрипт начат!
Генеральный спонсор конкурса - ГНУ/Линукцентр
Скрипты вы размещаете на pastebin или в комментах под спойлер до 20000 символов.
Конкурс продлится с 21 по 25 февраля 2011.
Правила просты:
1.Скрипты должны быть на человекопонятных языках (bash, perl, python). Скрипты на Delphi или BrainFuck мы не принимаем.
2.Скрипты должны быть оформлены как положено, с комментариями и пр.
3.Скрипты должны быть функционально полезны (проверка почты, открывание двери с реакцией на звонок и пр. Cкрипты, автоматизирующие загрузку порно и взлом сайтов не принимаются. Авторы таких скриптов удостоятся моего специального приза - вечного бана).
Уважаемое жюри - muhas, xT, cppmm и Minoru - выбирают трех победителей, которые получат призы от генерального спонсора конкурса ГНУ/Линукцентра.
В качестве приза будет комплект из фирменной футболки ГНУ/Линукцентра, дистрибутива Mandriva 2010.2 Powerpack и журнала Linux Format.
Удачи, дамы и господа, хороших скриптов и победы:)
UPD Все комменты не по существу конкурса будут стираться
Для флуда повешен специальный топик
UPD2 Уважаемые члены жюри напоминают - однострочники приветствуются :)
-
1. Скрипт wcron
Проблема: задания, запускаемые по крону, иногда накладываются друг на друга, если выполняются слишком долго (со всеми вытекающими последствиями)
Задачи:
- запускать задания только после завершения тех, которые уже работают
- перехватывать вывод программ и вывод их ошибок, писать все это дело в единый лог и уведомлять администратора, если программа завершеилась с ошибками
Сам скрипт:
http://pastebin.com/r4RS25zi
-
-
А можно поинтересоваться, что несёт в себе буква W в названии?
-
-
wrapper
-
У скрипта есть 1 недостаток. Он читает данные стандартный вывод и ошибки в переменные среды перед дальнейшей обработкой. Если процесс выдаст слишком большой вывод (в результате какой критической ошибки например), то скрипт затопчет память и грохнется.
-
-
Для таких вещей есть awk.
-
Посмотрите внимательней :)
Файлики это, а не переменные среды.
-
Или sed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# $1 - префикс,
# $2 - входной файл
function prefix()
{
[ -n "$2" ] || return
[ -e "$2" ] || return
sed "s/^/$1 /" "$2"
}
# ...
function dotask()
{
# ...
prefix "`printf '[%020s] (OO)` '${TASK:0:19}'`" "${OUT_FILE}"
prefix "`printf '[%020s] (EE)` '${TASK:0:19}'`" "${ERR_FILE}"
}
|
Как-то так.
-
-
Только заменить второй символ ` на вызовах prefix на '. Опечаталсо =)
-
-
че-то я ничего не понял, что Вы пытаетесь мне объяснить. :)
о чем речь изначально?
-
-
$1 - это команда, которую нужно выполнить
$2 - в какой папке её нужно выполнить
например:
wcron "git pull origin production" /home/site/www
в скрипте делается cd в нужную папку и выполняется команда.
-
Позиционные параметры локальны в функии.
Попробуй:
this.sh
1
2
3
4
5
6
7
|
#!/bin/bash
function here() {
echo $1
}
here 123 |
$ ./this.sh 567
Получишь 567. Я там описываю прототип функции prefix().
Я говорю о том месте, где ты проверяешь существования файлов с выводом и ошибками ($OUT_FILE, $ERR_FILE), читаешь их в переменные среды $OUT и $ERRORS, удаляешь файлы и работаешь с данными через переменные. Эти данные могут быть очень большими, произвольно большими, и загрузка их в память целиком может потенциально взорвать память.
-
-
* получишь 123 fixed
-
-
Про позиционные параметры то понятно, я просто не сразу понял, на что именно Вы мое внимание обратить пытаетесь :)
-
кажется, наконец то, понял, что Вы имеете в виду. :)
хорошая идея. спасибо. подумаю над этим :)
-
Строчки 82-94 — потенциально взрывают память.
-
Ещё есть бага. При формировании сообщения для отправки админу он каждую порцию данных пишет через «>», в итоге данные перетираются каждый раз и в письмо попадёт только последняя строчка («Подробнее в $LOG_FILE»).
-
-
А за это спасибо. :) Не заметил )
-
Скрипт для плавающих оттенков фона в гноме. Выставляем прозрачный фон (svg/png) или просто цвета, запускаем скрипт. Цвета будут плавно меняться, сохраняя яркость и насыщенность. Смотрится довольно мило (:
http://pastebin.com/Ne7YLVq8 - публиковалось на ресурсе
конечный конкурсный скрипт
-
-
оххх... модсостав поработал на отлично
пояснения к nap потерялись...
SNMP очень стрёмный протокол и надо через 7 колец прыгать каждый раз, поэтому я для своего рабочего проекта сделал оболочку, которая позволяет делать обычные http запросы и получать годный JSON с ответом.
-
Задача: необходимо раз в месяц отсылать почту аудитору, что бы он проверял выполнение заданий Bacula. Захотелось сделать красивое письмо что бы человек мог с ним работать без познаний Bacula.
Получилось что-то такое
http://pastebin.com/iK7NFC3P
-
Скрипт spam-check
Проверяет переданные ip-адерса/доменные имена по списку более чем 100 DSNBL баз и в удобной форме выводит на консоль. Можно писать в лог. Можно проверить только по какому-то конкретному dnsbl. Удобно положить в cron и получать отчеты на мыло/джаббер/etc (wiki).
Взять можно тут, в коде скрипта достаточно комментариев. На домашней страничке есть не много документации.
Конкурсный скрипт на pastebin
-
-
PS: Сначала писал скрипт сам, с нуля. Потом ко мне присоединился Gash и помог реализовать некоторые фичи. Сейчас скрипт временно не развивается, т.к. не хватает времени на его поддержку, но не заброшен: идеи еще не закончились. Последнюю dev-версию можно глянуть в trunk'е (там же есть todo).
-
Эта пара строк не претендует на что-либо, но давно хотел это написать, а тут как раз и повод подвалил. :)
Описание в этот ваш идиотский лимит не влезло, поэтому описание читайте в комментарии в самом скрипте.
http://pastebin.com/rkzt7CLZ
-
-
http://pastebin.com/rkzt7CLZ
-
Conky:DeaDBeeF Current TrackAA
Набор связанных друг с другом скриптов, которые реализует средством conky отображение на рабочем столе информацию о текущей композиции в таком плеере, как deadbeef.
По сути, просто реализация для тех кого по каким-то причинам не устроил covergloobus и не прочь использовать conky. На данном ресурсе по частям уже демонстрировал.
-
-
Итак, все сразу теперь:
[1] sh-скрипт, который реализует всякие проверки и действия с изображением обложки
http://pastebin.com/dsXLg0PH
[2] conkyrc и в нем же shell-подобные команды для запуска скрипта и прочего вывода данных о текущей композиции
http://pastebin.com/TYe6cePA
-
-
[2,5] sh-скрипт для кнопки на панель, при клике по которой будет запускаться либо плеер, либо если запущен уже плеер будет запускать наш конки http://pastebin.com/j6hQSZvz
да, конфиг conky и скрипт должен лежать в следующем каталоге: ~/.config/conky/ddbC/dbc.conkyrc
-
Задача: есть 10 000 продуктов в БД Sqlite. Нужно создать папки для размещения картинок для каждого продукта типа 03/78/32/25
1
2
3
|
echo 'select id from product ;'|sqlite3 data/kiosk.db|while read i; do str="0000000000$i"; b=`echo -n $str|rev`; x1=${b:0:2}; x2=${b:2:2}; x3=${b:4:2}; x4=${b:6:2}; echo "$x1/$x2/$x3/$x4/tcudorp/gmi/bew p- ridkm" |rev; done|bash
|
-
Очень давно стало лень руками дописывать новые домены в bind9, родился скрипт
http://pastebin.com/Zb1Tyfan
-
Скрипт на руби для вытаскивания перевода слов с Яндекс.Словари (которые используют довольно неплохую базу ABBYY Lingvo).
Русский <--> Английский.
Читабельная версия: http://pastebin.com/HY88cGXs
Однострочная (если не считать инклудов): http://pastebin.com/EZKNnmPN
-
-
Я не знаю Ruby, при запуске твоего скрипта получаю следующую ошибку:
1
2
3
4
5
6
|
% ruby1.8 translate hello
translate:12: undefined method `attr' for #<Nokogiri::XML::Element:0xb7187100> (NoMethodError)
from /usr/lib/ruby/1.8/nokogiri/xml/node_set.rb:207:in `each'
from /usr/lib/ruby/1.8/nokogiri/xml/node_set.rb:206:in `upto'
from /usr/lib/ruby/1.8/nokogiri/xml/node_set.rb:206:in `each'
from translate:9 |
Что оно такое и как побороть, не подскажешь?
-
-
Может дело в версии либы nokogiri?
-
-
Может. У меня 1.4.0-4 (Debian Squeeze), если что.
-
Похоже на то, что дело в версии. Если верить changelogу, то attr появился только в 1.4.1. Замени его на [] и все должно быть в порядке.
Кстати, замечу, чтобы в будущем не было вопросов, что этот скрипт тестировался на Ruby 1.9.2p180, Nokogiri 1.4.4, Arch Linux
-
-
Вот перезалил однострочник если не справишься:)
http://pastebin.com/m1n3cntT
-
Да, действительно, помогло. Спасибо! Хотя нужды перезаливать на самом деле не было — не такой уж я и глупый.
-
Вставлю свои 5 копеек. Скрипт-библиотека на перле для описания правил iptables в более-менее декларативнос стиле.
Раз (сама либа Pearlwall.pm):
http://pastebin.com/7C8297L4,
два (вспомогательная либа для написания init-скриптов на перле):
http://pastebin.com/ZrAdvwDQ,
три (пример использования):
http://pastebin.com/SLKihGf3.
-
Даже не знаю. У меня в блоге есть целая рубрика: коммандлайнеры,
Данный
1
2
|
while true; do x=`ifconfig eth0| grep bytes| pcregrep -o "\\(.+?\\)" | head -n1`; echo -ne "$x\r"; sleep 0.2 ;done
|
Данный однострочник показывает обьем скачанного в одну строку через каждые 0.2 секунды. Не забудьте указать интересующий вас интерфейс.
-
for i in `seq 1 12`; do wget -O- -q "http://prostopleer.com/search?q=Beatles&page=$i" | pcregrep -o --color "<li dur.+?\"> <div c" | pcregrep -o --color "duration=\".+\"" | awk -F"\"" '{print "#EXTINF:" $2 "," $6 " - " $8 "\n" "http://prostopleer.com/download/" $4}' ; done
А вот данный скрипт, на stdout выдает m3u плейлист, с песнями полученными из prostopleer, по поиску: Beatles. Выводит все песни с 1ой по 12 страницу. Можно подать на вход в
| mplayer -playlist -
чтобы сразу играть, только нужно дождаться, пока все распарсится.
-
-
http://bkmz.org/194 - здесь есть и для своего плейлиста однострочник.
Для работоспосбности всего этого хозяйства, необходим следущий набор:
pcregrep, awk, seq, grep, wget
И да, какой идиот сделал лимит на комментарии? жутко не удобно писать развернутые каменты.
-
-
-
-
Ясно, не знал =)
-
Сейчас лимит 20000, думаю за глаза хватит)
-
-
отредактируй в 1 пост =)
-
Только что написал, переименовывание музыки по idv3 тегам:
for x in `ls`; do name=`id3v2 -l $x | grep TIT2 | cut -d ":" -f2 | sed 's|^ ||g'`; mv $x "$name.mp3" ;done
Переименовывает все файлы, поэтому в директории должны быть все mp3'шки. Ну и перед запуском, cd лучше сделать
-
-
Ещё бы сделать IFS="\n", чтобы нормально обрабатывались файлы с пробелами.
-
с пробелами в именах как обычно косяки =)
Посмотри, здесь где-то на welinux о $IFS писали, и хитростях прочих
(что бы ничего из твоего не переписывать проще IFS=$'\n' запользовать, а потом убить её через unset IFS или сделать дефолтным (как-раз пробел)
да и id3v2 страшный какой-то, ни разу за всю мою сознательную жизнь я не осилил им utf кодировки в тегах, mutagen-inspect работает как надо (я бы сказал, как мне надо - пакет mutagen обычно), но он очень медленный...
вот что получилось сходу набросать
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#!/bin/sh
IFS=$'\n'
for i in `ls`;do
SONG_TITLE=$(mutagen-inspect "${i}" |grep TIT| cut -d "=" -f2)
AUTOR=$(mutagen-inspect "${i}" |grep TSOP| cut -d "=" -f2)
if [ -z ${AUTOR_TITLE} ];then
mv "${i}" "${SONG_TITLE}.mp3"
else
mv "${x}" "${AUTOR}-${SONG_TITLE}.mp3"
fi
done
unset IFS
|
if/else надо для того что если автора нет, то дефиса нафиг не было бы(он ещё и параметром воспримется и тогда mv не отработает)
работоспособность не проверял, но должно - просто-таки обязано работать =)
-
-
тьфу ты то ${AUTOR_TITLE} то просто ${AUTOR}... надо что бы везде одинакого было =) а то всегда будут название файлов только по именованию композиции
-
/me добрался до каталогов с mp3шками, поправил для красоты - паботает вроде неплохо
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#!/bin/sh
IFS=$'\n'
for x in `ls *.mp3` ;do
SONG_TITLE=$(mutagen-inspect "${x}" |grep TIT| cut -d "=" -f2)
AUTOR=$(mutagen-inspect "${x}" |grep TPE1| cut -d "=" -f2)
if [ -z ${AUTOR} ];then
mv "$x" "${SONG_TITLE}.mp3"
echo "$x >> ${SONG_TITLE}.mp3"
else
mv "$x" "${AUTOR} - ${SONG_TITLE}.mp3"
echo "$x >> ${AUTOR} - ${SONG_TITLE}.mp3"
fi
done
unset IFS
|
-
Ну если уж мутаген, то логично было бы на питоне написать, чтоб избежать накладок на запуск питон-интерпретатора в каждом проходе цикла, тогда должно быстрее работать.
-
-
вообще логичнее всего юзать какой-нить easytag, и если хочется питона то exfalso ^_^
не знаю умеет ли первый по тегам файлы переименовывать, но второй вроде умел
-
-
не знаю умеет ли первый по тегам файлы переименовывать, но второй вроде умел
EasyTag умеет. Причём довольно гибко. Например, я любую новую музыку, которая у меня появляется с его помощью переименовываю по такому шаблону:
/home/cppmm/random/music/%a/(%y) %b/%n - %t
На выходе это выглядит примерно так:
/home/cppmm/random/music/Arch Enemy/(1996) Black Earth/01 - Bury Me An Angel.mp3
-
Скрипт(Даже маленькая программка) я назвал imconv. данная программка написана на python с использованием pygtk для редактирования изображений. С кодом можно ознакомится под спойлером. но программу лучше скачать по ссылке, либо тут.
Для более удобной работы необходимо добавить ссылку на скрипт в Nautilus Action Configurator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
|
#!/usr/bin/env python
#Подключаем модули
import os
import sys
#Модуль для работы с Изображениями
import Image
#Так же через try подключает gtk
try:
import pygtk
pygtk.require("2.0")
import gtk
except:
print "Cant load GTK"
sys.exit(1)
#Эта переменная хранит наименования форматов для конвертирования
formats=[]
#Проверям, есть ли файл с перечнем форматов и загружаем форматы из него, если ли же нет, то используем стд. форматы конвертирования
try:
rc = open(os.path.join(os.environ['HOME'],'.imconvrc'))
for i in rc.readlines():
if len(i.strip())>0: formats.append(i.strip())
except:
formats=['jpg','png','gif','bmp']
#Создаем класс, который будет управлять всеми процессами
class converter():
rotater = 0
new_format = None
sizer = 2
#Функция редактирования изображения
def make_changes(self,widget,data=None):
#Пробегаемся по всем редактируемым изображениям
for i in sys.argv[1:]:
#Открываем изображение
try:
self.im = Image.open(i)
except IOError, x:
self.msgbox(x)
sys.exit(1)
except:
self.msgbox("FATAL ERROR")
sys.exit(1)
#Определяем имя и расширение изображения
self.f = os.path.splitext(i)[0]
self.r = os.path.splitext(i)[1]
#А также размеры
self.x,self.y = self.im.size
#Увеличиваем либо уменьшаем размер, в зависимости от выбранной опции
if self.incr.get_active():
self.x=self.x*self.sizer
self.y=self.y*self.sizer
self.im = self.im.resize((self.x,self.y))
elif self.decr.get_active():
self.x=self.x/self.sizer
self.y=self.y/self.sizer
self.im = self.im.resize((self.x,self.y))
#Также поворачиваем если это требуется
if self.rotater>0:
self.im = self.im.rotate(self.rotater)
#Отражаем по горизонтали
if self.flip_button_lr.get_active():
self.im = self.im.transpose(Image.FLIP_LEFT_RIGHT)
#Отражаем по вертикали
if self.flip_button_tb.get_active():
self.im = self.im.transpose(Image.FLIP_TOP_BOTTOM)
#Конвертируем формат если это требуется
if not self.new_format:
if self.format_radio_other.get_active():
if len(self.format_entry.get_text())>0:
self.new_format = self.format_entry.get_text()
else:
self.new_format = self.r[1:]
else:
self.new_format = self.r[1:]
#Сохраняем полученный результат
try:
self.im.save(self.f+"."+self.new_format)
except:
if lf==1:
self.msgbox("Cant convert")
else:
print "Cant convert"
sys.exit(2)
sys.exit(0)
#Данная функция предназначена что бы выводить ошибки в виде окна
def msgbox(self,msg,title="Warning!"):
self.msgw = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
self.msgw.set_modal(True)
self.msgw.set_border_width(5)
self.msgw.set_position(gtk.WIN_POS_CENTER_ALWAYS)
self.msgw.set_title(title)
self.msgw.set_resizable(False)
self.msgw.connect("delete_event",self.delete_event)
self.msgb = gtk.VBox(True,10)
self.msgw.add(self.msgb)
self.msgl = gtk.Label(msg)
self.msgb.pack_start(self.msgl,True,True,0)
self.msgl.show()
self.msgbb = gtk.HBox(False,0)
self.msgbb.show()
self.msgb.pack_start(self.msgbb,True,True,0)
self.msgbt = gtk.Button("Exit")
self.msgbb.pack_end(self.msgbt,True,False,5)
self.msgbt.connect("clicked",self.delete_event,self.msgw)
self.msgbt.show()
self.msgb.show()
self.msgw.show()
print msg
gtk.main()
#Устанавливаем переменную для увеличения/уменьшения рамера
def set_resize(self,widget,data):
self.sizer=data
#Подгружаем изображение в предпросмотр
def get_image(self,image_name,max_size):
self.pixbuf = gtk.gdk.pixbuf_new_from_file(image_name)
self.w,self.h = self.pixbuf.get_width(),self.pixbuf.get_height()
if self.w>self.h:
self.h=(max_size*self.h)/self.w
self.w=max_size
else:
self.w=(max_size*self.w)/self.h
self.h=max_size
self.pixbuf = self.pixbuf.scale_simple(self.w,self.h,gtk.gdk.INTERP_BILINEAR)
self.im = gtk.Image()
self.im.set_from_pixbuf(self.pixbuf)
return self.im
#Устанавливаем переменную для поворота изображения
def set_rotate(self,widget,data):
self.rotater = data
#Функция для отжимания кнопочного переключателя, если нажаты оба
def flip_check(self,widget,data):
if data=="lr":
if self.flip_button_lr.get_active(): self.flip_button_tb.set_active(False)
else:
if self.flip_button_tb.get_active(): self.flip_button_lr.set_active(False)
#Разрешаем/Запрещаем ввод в текстовое поле формата, в зависимости от выбранной опции
def set_format(self,widget,data):
if data:
self.format_entry.set_editable(False)
self.format_entry.set_text("")
self.new_format = data
else:
if self.format_radio_none.get_active(): self.new_format=None
if self.format_radio_other.get_active():
self.format_entry.set_editable(True)
else:
self.format_entry.set_text("")
self.format_entry.set_editable(False)
#Функция для отжимания кнопочного переключателя, если нажаты оба
def resize(self,widget,data):
if widget.get_active():
if data=="incr":
self.decr.set_active(False)
else:
self.incr.set_active(False)
#Событие при закрытии программы
def delete_event(self,widget,event,Data=None):
gtk.main_quit()
return False
def run(self):
#Создаем окно
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
#Устанавливаем заголовок
self.window.set_title("Converter")
#Устанавливаем рамку
self.window.set_border_width(5)
#Устанавливаем положение окна
self.window.set_position(gtk.WIN_POS_CENTER)
#Ставим запрет на изменение размеров окна
self.window.set_resizable(False)
#Устанавливаем ссылку на фукцию при событии "Закрытие окна"
self.window.connect("delete_event",self.delete_event)
#Создаем вертикальный контейнер
self.mainbox = gtk.VBox(False,0)
#Создаем фреймы(Области с названиями в заголовке)
self.preview_frame = gtk.Frame("Pre-view")
self.resize_frame = gtk.Frame("Resize")
self.flip_frame = gtk.Frame("Flip")
self.rotate_frame = gtk.Frame("Rotate (Throught left side)")
self.format_frame = gtk.Frame("New Format")
#Добавляем фреймы в основной вертикальный контейнер
self.mainbox.pack_start(self.preview_frame,True,True,0)
self.mainbox.pack_start(self.resize_frame,True,True,0)
self.mainbox.pack_start(self.flip_frame,True,True,0)
self.mainbox.pack_start(self.rotate_frame,True,True,0)
self.mainbox.pack_start(self.format_frame,True,True,0)
#Если редактируем больше одной картинке, вместо pre-view устанавливам надпись о том сколько изображений выбрано
if lf>1:
self.preview_content = gtk.Label("Cant preview, because \n"+str(lf)+" images is selected")
self.preview_content.set_justify(gtk.JUSTIFY_CENTER)
else:
self.preview_content = self.get_image(sys.argv[1],180)
#Добавляем либо надпись, либо картинку в предпросмотр в фрейм
self.preview_frame.add(self.preview_content)
#Создаем табличный контейнер
self.resize_t = gtk.Table(2,4,False)
#Создаем ктопочные переключатели
self.incr = gtk.ToggleButton("Increase")
self.decr = gtk.ToggleButton("Decrease")
#Устанавливаем парамметры кнопочных переключатей
self.incr.connect("toggled",self.resize,"incr")
self.decr.connect("toggled",self.resize,"decr")
#Добавляем переключатели в табличный контейнер кнопочные переключатели
self.resize_t.attach(self.incr,0,2,0,1)
self.resize_t.attach(self.decr,2,4,0,1)
#параметры для переключателей
self.parts=[2,3,4,5]
self.radio_parts=[]
#Создаем переключатели с параметрами и добавляем их в табличный контейнер
for i in xrange(len(self.parts)):
if i==0:
self.radio_parts.append(gtk.RadioButton(None,"in "+str(self.parts[i])))
else:
self.radio_parts.append(gtk.RadioButton(self.radio_parts[0],"in "+str(self.parts[i])))
self.radio_parts[i].connect("toggled",self.set_resize,self.parts[i])
self.resize_t.attach(self.radio_parts[i],i,i+1,1,2)
#Добавляем табличный контейнер в фрейм
self.resize_frame.add(self.resize_t)
#Создаем горизонтальный контейнер
self.flip_box = gtk.HBox(False,0)
#Создаем кнопочные переключатели
self.flip_button_lr = gtk.ToggleButton("Left - Right")
self.flip_button_tb = gtk.ToggleButton("Top - Bottom")
#Добавляем кнопочные переключатели в горизонтальный контейнер
self.flip_box.pack_start(self.flip_button_lr,True,False,0)
self.flip_box.pack_start(self.flip_button_tb,True,False,0)
#Добавляем горизонтальный контейнер в фрейм
self.flip_frame.add(self.flip_box)
#Создаем горизонтальный контейнер
self.rotate_box = gtk.HBox(True,0)
#Создаем переключатели и добавляем в контейнер
self.rotates=[90,180,270]
self.rotate_radio = gtk.RadioButton(None,"0")
self.rotate_radio.connect("toggled",self.set_rotate,0)
self.rotate_box.pack_start(self.rotate_radio,True,True,0)
for i in self.rotates:
self.rotate_radio = gtk.RadioButton(self.rotate_radio,str(i))
self.rotate_radio.connect("toggled",self.set_rotate,i)
self.rotate_box.pack_start(self.rotate_radio,True,True,0)
#Добавляем контейнер в фрейм
self.rotate_frame.add(self.rotate_box)
#Если редактируем один файл, удаляем формат файла из предложенных в программе
if lf==1:
try:
formats.remove(os.path.splitext(sys.argv[1])[1][1:])
except:
pass
#Создаем вертикальный контейнер
self.format_box = gtk.VBox(False,0)
#Создаем переключатели с названиями форматов
self.format_radio_none = gtk.RadioButton(None,"None")
self.format_radio_none.connect("toggled",self.set_format,None)
self.format_box.pack_start(self.format_radio_none,True,False,0)
for i in formats:
self.format_radio = gtk.RadioButton(self.format_radio_none,"to "+i)
self.format_radio.connect("toggled",self.set_format,i)
self.format_box.pack_start(self.format_radio,True,False,0)
#А также переключатель для другого расширения, с возможностью ввести свой формат файла
self.format_radio_other = gtk.RadioButton(self.format_radio_none,"Other -->")
self.format_radio_other.connect("toggled",self.set_format,None)
self.format_box.pack_start(self.format_radio_other,True,False,0)
#Создаем горизонтальный контейнер
self.format_other_box = gtk.HBox(False,0)
#Создаем надпись
self.formal_other_label = gtk.Label("Enter other format: ")
#Создаем текстовое поле
self.format_entry = gtk.Entry(5)
#Устанавливаем парамметры текстого поля
self.format_entry.set_size_request(40,self.format_entry.get_size_request()[1])
self.format_entry.set_editable(False)
#Добавляем надпись и текстовое поле в контейнер
self.format_other_box.pack_start(self.formal_other_label,True,True,0)
self.format_other_box.pack_start(self.format_entry,True,True,0)
self.format_box.pack_start(self.format_other_box,True,True,0)
#Добавляем контейнер в фрейм
self.format_frame.add(self.format_box)
#Создаем кнопки управления, применить и отмена
self.control_box = gtk.HBox(False,0)
self.apply_button = gtk.Button("Apply",gtk.STOCK_OK)
self.cancel_button = gtk.Button("Cancel")
#Устанавливаем события на кнопки управления
self.apply_button.connect("clicked",self.make_changes)
self.cancel_button.connect("clicked",self.delete_event,self.window)
#Добавляем в контейнер
self.control_box.pack_start(self.apply_button,False,False,0)
self.control_box.pack_start(self.cancel_button,True,True,0)
#Добавляем кнопки управления в основной контейнер
self.mainbox.pack_start(self.control_box,True,True,0)
#Добавляем основной контейнер к окну
self.window.add(self.mainbox)
#Выводим результат на экран
self.window.show_all()
if __name__ == "__main__":
#создаем экземпляр класса
conv = converter()
#записываем в переменную все файлы, которые собираеся редактировать
lf=len(sys.argv[1:])
#Проверям, существуют ли файлы. и определям дальнешие действие
if lf>0:
for i in sys.argv[1:]:
if not os.path.isfile(i):
print "This is not file:",i
sys.exit(1)
else:
#Запускаем нашу программу
conv.run()
gtk.main()
else:
conv.msgbox("Need image file")
|
-
Когда-то давно писал в обнимку с гуглем нотифер для обновлений генты:
http://pastebin.com/0AYp0N0z — нотификационный скрипт
http://pastebin.com/LgyBji7T — скрипт обновляющий и выкидывающий уведомление
-
Ну и маленький скрипт "для внутреннего использования".
Использовался мной когда я потерял /home со всеми своими ABUILD'ами (скриптами сборки пакетов AgiliaLinux).
http://pastebin.com/su7mr9EM — парсит страницу со списком пакетов, маинтейнещихся юзером (в скрипте — мной), и забирает все build-tree (сборочные дерева с ABUILD'ами) для них через api.agilialinux.ru
|
|
|
Последние посты
|
|
Последние комментарии
|
|
Изменения
|
|
Черновики (все)
|
|
Избранное (всё)
|
|
|