Pull to refresh

Comments 63

Классический AI на регэкспах и рерайтах :)
arg1=string.join(sys.argv[1:],'\\ ') # получаем переменную из соседнего файла bash


Шта?

Автору советую сделать напоминание ;rm -rf /;1 через 15 минут и идти учить питон.
Как бы Вы реализовали передачу текстовой фразы с пробелами из bash в python с учетом того, чтобы программа zenity поняла в атрибуте --entry-text пробелы?
Наверное так же, как и во все остальные интерпретаторы, с\ экранированием\ пробелов как\ то\ так:

rico> cat test.sh
#!/bin/bash
echo $1

rico> ./test.sh all\ you\ need\ is\ love
all you need is love

Только разбор будет сложнее, но это уже к питону вопрос и к zenity.
гуев на сервере не держу, но думаю на все это поисковик ответит — не у Вас одного такая проблема.
arg1 = string.join(sys.argv[1:],'\\ ')

Так ведь я для экранирования пробелов и использую join с подстановкой слэша как разделителя!

P. S. Только функция string здесь может не использоваться:
arg1 = '\\ '.join(sys.argv[1:])
Вообще аргумент можно взять в кавычки и тогда вся строка будет в sys.argv[1]. Если оочень лень вводить кавычки и хочется, чтобы несколько аргументов сливались самим скриптом — делаем " ".join(sys.argv[1:]). Но основная проблема — экранировать нужно не только пробел. Банальные примеры: ; ! () < >. Так что часть аргументов все равно придется брать в кавычки. Это по поводу bash -> python.

Модуль commands Deprecated since version 2.6:. getoutput если и использовать, то только в скриптах для себя. В идееале нужно вызывать subprocess.check_output() с командой в виде списка (если передавать строкой то будет тот же getoutput):
check_output(["zenity", "--entry", "--title=Напоминалка", "--text=Введите напоминание", "--entry-text=%s" % arg1, "--width=400"])

Да, это неудобно, зато аргументы будут переданы корректно и не нужно ничего экранировать. +Нету лишнего вызова bash'а, zenity будет вызван напрямую. +Наверняка есть библиотеки для таких вызовов по типу prepared statements в SQL.

PS: ещё заменчание по регэкспам: [0-9][0-9][0-9][0-9] никто не пишет, надо \d{4}. (Только к строке-регэкспу добавить префикс r, чтобы слеш не утек).
Да, как раз command ломает многое, если GTK выкидывает какой-нибудь warning (уже упоминал ниже).
Разбил код на функции, перевёл на subprocess. Отправил pull request автору.
Запрос на GitHub принял.
В статью внес изменения.
Спасибо!
Для людей, которые работают в офисе с персональным компьютером — бухгалтеров, инженеров, секретарей

Представляю себе секретаршу-блондинку, которая сидит в Линуксе и строчит напоминалку на питоне :)))
Вы молодец. Не для критики а для информации… В Ubuntu использовал Alarm из репозитария. Простая, работает надежно. И этап установки времени, как отдельное действие, мне нравится больше. Так более предсказуемо.
UFO just landed and posted this here
— Играет ли роль, где указывать время: в начале или в конце?
— Не, не играет роли. Когда я писал программу, я подумал об этом.

— Что будет, если опечататься?
— Если сделать опечатку (например, напишите «завтра пройти регистрацию», не указав времени), то появится ошибка «Попробуйте ещё раз..».

— Пробовали ли Вы найти готовую библиотеку, умеющую читать выражения даты/времени в «человеческом» формате?
— Не, не пробовал. В любом случае я перевожу «человеческий» формат на язык программы at.

— Планируется ли в будущем интеграция с календарями?
— Вообще-то не планировал, но идея интересная.
UFO just landed and posted this here
Если написать «затра», то программа поймет это как «что делать», а не как «когда делать» в напоминании.

Например, если написать «затра в 11 распечатать файлы», а на часах 10:00, то в этот же день в 11:00 появится напоминание «затра распечатать файлы». Если на часах 12:00, то завтра в 11:00 появится напоминание «затра распечатать файлы».
Для отлова простых опечаток можно использовать difflib.get_close_matches
Вероятно, если указан день без указания времени, стоит не сообщать пользователю об ошибке, а использовать «время по умолчанию», которое возможно изменить в настройках.
Я тут потестировал немного, думал неверный формат даст ошибку, но теперь весь день рандомно выскакивают сообщения вида «выаяыва» :)
UFO just landed and posted this here
Программа At и заложена в основу представленной напоминалки.
Конечно же, без руководства at было бы сложно что-то сделать.
Тогда я совсем ничего не понимаю. Какая проблема была решена тогда? GUI для at?
GUI для at и перевод простого понятного формата установки времени, типа «через 5 минут», «в 10», «завтра в 11-15», «в понедельник в 14-30» в формат at.
Да куда уж проще и понятнее-то?

You can also give times like now + count time-units, where the time-units can be minutes, hours, days, or weeks and you can tell at to run the job today by suffixing the time with today and to run the job tomorrow by suffixing the time with tomorrow.


«Через 5 минут»:
$ at now + 5 minutes
warning: commands will be executed using /bin/sh
at> /bin/ls      
at> <EOT>
job 1 at Wed Oct 15 08:41:00 2014


«Завтра в 11-15»:
$ at 11:15 tomorrow
warning: commands will be executed using /bin/sh
at> /bin/ls
at> <EOT>
job 2 at Thu Oct 16 11:15:00 2014


И так далее.
Можно сделать так:
1. Открыть терминал (например, Ctrl+Alt+T)
2. Ввести строку: at 11:15 tomorrow
3. Нажать Enter
4. Ввести строку: zenity --display=:0 --warning --text='сделать\ отчет'
5. Нажать Ctlr+D

Можно даже так:
1. Открыть терминал (например, Ctrl+Alt+T)
2. Ввести строку: echo DISPLAY=:0 zenity --warning --text='сделать\ отчет' | at 11:15 tomorrow
3. Нажать Enter


Но, мне кажется, проще сделать так:
1. Открыть напоминалку (например, Ctrl+Shift+X)
2. Ввести строку: завтра в 11-15 сделать отчет
3. Нажать Enter

К тому же программа позволяет отложить напоминание, что нельзя сделать в первых двух случаях.
--text='сделать\ отчет'


"\" лишний. Остальное ясно. Спасибо.
Что-то подобное я хотел написать больше 10 лет назад, когда жил в общаге.
Когда ставишь на плиту чайник/пельмени/макароны, идешь в комнату, а там компьютер и интернет…
Ну вы поняли.
Вспоминаешь, когда почувствуешь специфический запах или соседи пнут в дверь, проходя мимо

Правда, у меня была идея выбирать из предзаготовленных вариантов, типа рецептов, а не вводить каждый раз вручную

Зато я освоил команду shutdwn, которая бескомпромиссно отправляла меня спать в 00.00
:)
извините не удержался
image
Ага, именно :)
Бежишь на кухню, а там булькает пузырями один большой пельмень, начиненный множеством маленьких тефтелек
Это, видимо, распространённая проблема :) Заранее настроенная на запуск по таймеру shutdown -h now спасла мне немало драгоценных часов сна на последних курсах университета.
Может, программа at не установлена?
Установлена. Она по-умолчанию в подавляющем большинстве дистрибутивов установлена.
Я перезагрузил файлы по предоставленной ссылке и обновил код в статье.
Проверил, программа работает…

Попробуйте еще раз скачать файлы и положить в папку remindme в домашнем каталоге.
Всё таки тоже самое. Не берите в голову. Дома окажусь — посмотрю. С Python'ом я знаком. :)
Всё на строках и len(). Мозг мой вытек, но если будет работать — хорошо, так как концепт симпатичный.
Если сделать хороший интерфейс с доступом из трея, сделать английскую версию, прикрутить создание событий в календаре, то получится хороший аналог одной популярной утилиты под мак, которая стоит почти 20 баксов (не даю ссылок и названия ибо реклама), и Open Source сообщество будет вам реально благодарно.
>(не даю ссылок и названия ибо реклама)

В комментариях можно, так что давайте ссылку и/или название :)
Если делали для личных целей, т.е. под свою систему, можно было бы оформить в виде аплета на подобии cinnamon-spices.linuxmint.com/applets/view/68
— это удобней и наглядней для пользователя

PS
Вместо
if len(day) is not 0:
пишите
if len(day):

без лишнего отрицания
На самом деле, это не вопрос лишнего отрицания. Автору очень повезло, что его код вообще работает.

Оператор is не проверяет объекты на равенство, он проверяет объекты на идентичность, то есть «указывают ли 2 ссылки на один и тот же объект». Соответственно это не работало бы на целых числах, если бы не оптимизация, примененная в конкретной реализации (CPython): небольшие целые числа являются синглтонами (вопрос на SO). Равенство можно проверять только с помощью ==, тогда как is аподходит для сравнения с синглтонами: None, True и False.

Пример:
a = 1
b = 1
a is b    # -> True
a = 1000
b = 1000
a is b    # -> False


Вообще, в булевом контексте только пустые контейнеры (и только пустые строки) вычисляются в False, поэтому можно писать просто
if day:
Да тут в принципе не на python'е написано:) Но в целом идея понравилась.
Да. Спасибо! Внес соответствующие поправки.
Задумка хорошая. Я бы еще после нажатие «ОК» запускал таймер минут на десять и делал уточнение, выполнена ли задача, а то бывает что могут опять отвлечь.
Поправьте это com = commands.getstatusoutput('echo DISPLAY=:0 ~/remindme/task %s | %s' % (out,x)) на относительный путь. Достаточно разместить в другое место, как работать не будет.
UFO just landed and posted this here
Невозможно отменить добавление задачи. Закрываешь окно или жмёшь Cancel — «попробуйте ещё раз». Только по Ctrl-C в терминале прибивается.
Непонятна причина «попробовать ещё раз». Неверный путь до задачи (указанный ploop), неверный формат даты, или что-то ещё?
Выкладывайте на Github, допилим.
Кстати да, задумка очень интересная, но сыро.
Странно… Такой ошибки у меня не возникает. «Отмена» закрывает всё, независимо от введенного текста. При нажатии на кнопку «Отмена» переменная len(get) получает значение «0», и по логике программного кода переменная «loop» становится равной нулю. Цикл прерывается, программа закрывается.
Честно говоря, не знаю с чем это может быть связано… Возможно, проблема возникает из-за разных версий Python (у меня установлен 2.7.6).

Проект постараюсь выложить на Github сегодня после рабочего дня. Спасибо.

Изменил условие «if len(get) is not 0» на «if get». Возможно, это решит проблему с «Отменой» на Вашем компьютере.
Напомню, что у меня проблемы такой не возникало…
Так и быть, я влез в исходник и поковырял. Дело в совместном использовании zenity и commands.

commands.getstatusoutput(cmd)
Execute the string cmd in a shell with os.popen() and return a 2-tuple (status, output). cmd is actually run as { cmd; } 2>&1, so that the returned output will contain output or error messages. A trailing newline is stripped from the output. The exit status for the command can be interpreted according to the rules for the C function wait().

В итоге в переменную get может прилететь:
  • 'Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.'
  • 'Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
    Через 15 минут '

Могу сам выложить на Github, оставив copyright и указав лицензию, какую выберете. Стоит хотя бы отформатировать код.
Для «простых напоминалок» и других задач лично мне жутко понравились kdialog и zenity.

Получается действительно уйма функционала — всего в пару строк.
Так а тут что используется?
Python же.

Я его тоже люблю, но он тут используется, когда можно было все сделать и без него.
Так он тут используется для разбора фраз. А вывод результата тем же zenity.
Может просто купить смартфон с андроидом:?:))
Все вышеуказанные действия возможны, + можно задавать место напоминания. Например по прибытию на работу, магазин, метро или дом… Устанавливается голосом + два нажатия. Пользуюсь постоянно.
… и там придётся делать тоже самое — ставить напоминания, а потом искать «в каком ухе у меня жужжит».
А компьютер он как бы перед тобой.
А, еще есть любители в наушниках сидеть постоянно.

идея и задумка очень годная.
Sign up to leave a comment.

Articles