Add logout button timeout. Add l10n support.
This commit is contained in:
parent
2ea569c7ed
commit
9981f9f6a2
6 changed files with 165 additions and 16 deletions
|
@ -1,8 +1,12 @@
|
||||||
import sys
|
import sys
|
||||||
|
import locale
|
||||||
|
|
||||||
from gi.repository import Gtk, Gdk, GObject, GLib
|
from gi.repository import Gtk, Gdk, GObject, GLib
|
||||||
|
|
||||||
|
|
||||||
|
_ = locale.gettext
|
||||||
|
|
||||||
|
|
||||||
class LockWindow(Gtk.Window):
|
class LockWindow(Gtk.Window):
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
'tryUnlock': (GObject.SIGNAL_RUN_FIRST, None, (str,))
|
'tryUnlock': (GObject.SIGNAL_RUN_FIRST, None, (str,))
|
||||||
|
@ -26,6 +30,7 @@ class LockWindow(Gtk.Window):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
self.unlockWindow = builder.get_object('unlock_window')
|
self.unlockWindow = builder.get_object('unlock_window')
|
||||||
|
self.lockLabel = builder.get_object('lock_label')
|
||||||
self.promptEntry = builder.get_object('prompt_entry')
|
self.promptEntry = builder.get_object('prompt_entry')
|
||||||
self.messageLabel = builder.get_object('message_label')
|
self.messageLabel = builder.get_object('message_label')
|
||||||
self.logoutButton = builder.get_object('logout_button')
|
self.logoutButton = builder.get_object('logout_button')
|
||||||
|
@ -45,15 +50,36 @@ class LockWindow(Gtk.Window):
|
||||||
|
|
||||||
def _tryUnlock(self):
|
def _tryUnlock(self):
|
||||||
self.promptEntry.set_sensitive(False)
|
self.promptEntry.set_sensitive(False)
|
||||||
|
self.unlockButton.set_sensitive(False)
|
||||||
GLib.idle_add(lambda: self.emit('tryUnlock', self.promptEntry.get_text()))
|
GLib.idle_add(lambda: self.emit('tryUnlock', self.promptEntry.get_text()))
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.promptEntry.set_text('')
|
self.promptEntry.set_text('')
|
||||||
self.promptEntry.set_sensitive(True)
|
self.promptEntry.set_sensitive(True)
|
||||||
self.promptEntry.grab_focus()
|
self.promptEntry.grab_focus()
|
||||||
|
|
||||||
|
self.unlockButton.set_sensitive(True)
|
||||||
|
|
||||||
self.messageLabel.set_label('')
|
self.messageLabel.set_label('')
|
||||||
|
|
||||||
def setMessage(self, message):
|
self.logoutButton.set_sensitive(False)
|
||||||
|
|
||||||
|
def updateLockMessage(self, username, logoutTime = None):
|
||||||
|
if logoutTime is None:
|
||||||
|
self.lockLabel.set_markup(_('This computer is currently locked by the user <i>{username}</i>.').format(username=GLib.markup_escape_text(username)))
|
||||||
|
self.logoutButton.set_sensitive(False)
|
||||||
|
elif logoutTime > 0:
|
||||||
|
self.lockLabel.set_markup(
|
||||||
|
_('This computer is currently locked by the user <i>{username}</i>.\nThe user can be logged out in {minutes:02}:{seconds:02} minutes.').format(
|
||||||
|
username=GLib.markup_escape_text(username), minutes=logoutTime//60, seconds=logoutTime%60))
|
||||||
|
self.logoutButton.set_sensitive(False)
|
||||||
|
else:
|
||||||
|
self.lockLabel.set_markup(
|
||||||
|
_('This computer is currently locked by the user <i>{username}</i>.\nThe user can be logged out now.').format(
|
||||||
|
username=GLib.markup_escape_text(username)))
|
||||||
|
self.logoutButton.set_sensitive(True)
|
||||||
|
|
||||||
|
def setAuthMessage(self, message):
|
||||||
self.messageLabel.set_label(message)
|
self.messageLabel.set_label(message)
|
||||||
|
|
||||||
def lock(self):
|
def lock(self):
|
||||||
|
|
24
Locker.py
24
Locker.py
|
@ -4,17 +4,18 @@ import Idle
|
||||||
|
|
||||||
|
|
||||||
class Locker(object):
|
class Locker(object):
|
||||||
def __init__(self, lockTimeout, doLock, doUnlock, logoutTimeout = 0, doLogout = None):
|
def __init__(self, lockTimeout, doLock, doUnlock, logoutTimeout = 0, doLogout = None, updateLogoutTimeout = None):
|
||||||
self.locked = False
|
self.locked = False
|
||||||
self.lockTimeout = lockTimeout
|
self.lockTimeout = lockTimeout
|
||||||
self.logoutTimeout = logoutTimeout
|
self.logoutTimeout = logoutTimeout
|
||||||
self.doLock = doLock
|
self.doLock = doLock
|
||||||
self.doUnlock = doUnlock
|
self.doUnlock = doUnlock
|
||||||
self.doLogout = doLogout
|
self.doLogout = doLogout
|
||||||
|
self.updateLogoutTimeout = updateLogoutTimeout
|
||||||
|
|
||||||
GLib.timeout_add_seconds(1, self.checkLock)
|
GLib.timeout_add_seconds(1, self._checkLock)
|
||||||
|
|
||||||
def checkLock(self):
|
def _checkLock(self):
|
||||||
if self.locked:
|
if self.locked:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -25,14 +26,27 @@ class Locker(object):
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _checkLogout(self):
|
||||||
|
self.currentLogoutTimeout = self.currentLogoutTimeout - 1
|
||||||
|
if self.updateLogoutTimeout is not None:
|
||||||
|
self.updateLogoutTimeout(self.currentLogoutTimeout)
|
||||||
|
|
||||||
|
return self.currentLogoutTimeout > 0
|
||||||
|
|
||||||
def lock(self):
|
def lock(self):
|
||||||
if not self.locked:
|
if not self.locked:
|
||||||
self.doLock()
|
self.doLock(self.logoutTimeout)
|
||||||
self.locked = True
|
self.locked = True
|
||||||
|
|
||||||
|
if self.doLogout is not None:
|
||||||
|
self.currentLogoutTimeout = self.logoutTimeout
|
||||||
|
|
||||||
|
if self.currentLogoutTimeout > 0:
|
||||||
|
GLib.timeout_add_seconds(1, self._checkLogout)
|
||||||
|
|
||||||
def unlock(self):
|
def unlock(self):
|
||||||
if self.locked:
|
if self.locked:
|
||||||
self.doUnlock()
|
self.doUnlock()
|
||||||
self.locked = False
|
self.locked = False
|
||||||
|
|
||||||
GLib.timeout_add(100, self.checkLock)
|
GLib.timeout_add_seconds(1, self._checkLock)
|
||||||
|
|
49
po/de.po
Normal file
49
po/de.po
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# Pylock german translation
|
||||||
|
# Copyright (C) 2012 Matthias Schiffer
|
||||||
|
# This file is distributed under the same license as the pylock package.
|
||||||
|
# Matthias Schiffer <mschiffer@universe-factory.net>, 2012.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: pylock 0.1\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2012-02-01 19:25+0100\n"
|
||||||
|
"PO-Revision-Date: 2012-02-01 19:30+0100\n"
|
||||||
|
"Last-Translator: Matthias Schiffer <mschiffer@universe-factory.net>\n"
|
||||||
|
"Language-Team: German <de@li.org>\n"
|
||||||
|
"Language: de\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: unlock.ui:115 unlock.ui:113
|
||||||
|
msgid "Unlock"
|
||||||
|
msgstr "Entsperren"
|
||||||
|
|
||||||
|
#: unlock.ui:132 unlock.ui:129
|
||||||
|
msgid "Logout"
|
||||||
|
msgstr "Ausloggen"
|
||||||
|
|
||||||
|
#: LockWindow.py:69
|
||||||
|
msgid "This computer is currently locked by the user <i>{username}</i>."
|
||||||
|
msgstr "Dieser Computer ist zur Zeit vom Benutzer <i>{username}</i> gesperrt."
|
||||||
|
|
||||||
|
#: LockWindow.py:73
|
||||||
|
msgid ""
|
||||||
|
"This computer is currently locked by the user <i>{username}</i>.\n"
|
||||||
|
"The user can be logged out in {minutes:02}:{seconds:02} minutes."
|
||||||
|
msgstr ""
|
||||||
|
"Dieser Computer ist zur Zeit vom Benutzer <i>{username}</i> gesperrt.\n"
|
||||||
|
"Der Benutzer kann in {minutes:02}:{seconds:02} Minuten ausgeloggt werden."
|
||||||
|
|
||||||
|
#: LockWindow.py:78
|
||||||
|
msgid ""
|
||||||
|
"This computer is currently locked by the user <i>{username}</i>.\n"
|
||||||
|
"The user can be logged out now."
|
||||||
|
msgstr ""
|
||||||
|
"Dieser Computer ist zur Zeit vom Benutzer <i>{username}</i> gesperrt.\n"
|
||||||
|
"Der Benutzer kann jetzt ausgeloggt werden."
|
||||||
|
|
||||||
|
#: unlock.ui:63
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Passwort:"
|
46
po/pylock.pot
Normal file
46
po/pylock.pot
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2012-02-01 19:25+0100\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: unlock.ui:115 unlock.ui:113
|
||||||
|
msgid "Unlock"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: unlock.ui:132 unlock.ui:129
|
||||||
|
msgid "Logout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: LockWindow.py:69
|
||||||
|
msgid "This computer is currently locked by the user <i>{username}</i>."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: LockWindow.py:73
|
||||||
|
msgid ""
|
||||||
|
"This computer is currently locked by the user <i>{username}</i>.\n"
|
||||||
|
"The user can be logged out in {minutes:02}:{seconds:02} minutes."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: LockWindow.py:78
|
||||||
|
msgid ""
|
||||||
|
"This computer is currently locked by the user <i>{username}</i>.\n"
|
||||||
|
"The user can be logged out now."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: unlock.ui:63
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr ""
|
22
pylock.py
22
pylock.py
|
@ -4,6 +4,7 @@ import signal
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
|
import locale
|
||||||
|
|
||||||
from gi.repository import Gtk, Gdk
|
from gi.repository import Gtk, Gdk
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ def get_username():
|
||||||
|
|
||||||
theme = 'UzL-login'
|
theme = 'UzL-login'
|
||||||
timeout = 5
|
timeout = 5
|
||||||
|
logoutTimeout = 15
|
||||||
username = get_username()
|
username = get_username()
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,10 +32,26 @@ signal.signal(signal.SIGTERM, handler)
|
||||||
signal.signal(signal.SIGQUIT, handler)
|
signal.signal(signal.SIGQUIT, handler)
|
||||||
|
|
||||||
|
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
locale.bindtextdomain('pylock', '/home/neoraider/Devel/Python/pylock/locale')
|
||||||
|
locale.textdomain('pylock')
|
||||||
|
|
||||||
Gtk.Settings.get_default().set_property('gtk-theme-name', theme)
|
Gtk.Settings.get_default().set_property('gtk-theme-name', theme)
|
||||||
|
|
||||||
|
|
||||||
window = LockWindow()
|
window = LockWindow()
|
||||||
locker = Locker(timeout, lambda: window.lock(), lambda: window.unlock())
|
|
||||||
|
def lock(timeLeft):
|
||||||
|
window.updateLockMessage(username, timeLeft)
|
||||||
|
window.lock()
|
||||||
|
|
||||||
|
def logout():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def updateTimeout(timeLeft):
|
||||||
|
window.updateLockMessage(username, timeLeft)
|
||||||
|
|
||||||
|
locker = Locker(timeout, lock, window.unlock, logoutTimeout, logout, updateTimeout)
|
||||||
pamAuth = pam.pam()
|
pamAuth = pam.pam()
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +60,7 @@ def tryUnlock(w, password):
|
||||||
locker.unlock()
|
locker.unlock()
|
||||||
else:
|
else:
|
||||||
window.reset()
|
window.reset()
|
||||||
window.setMessage(pamAuth.reason)
|
window.setAuthMessage(pamAuth.reason)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
12
unlock.ui
12
unlock.ui
|
@ -37,13 +37,10 @@
|
||||||
<property name="border_width">12</property>
|
<property name="border_width">12</property>
|
||||||
<property name="spacing">12</property>
|
<property name="spacing">12</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="hostname_label">
|
<object class="GtkLabel" id="lock_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="label" comments="This is a placeholder string and will be replaced with the hostname of the system">[hostname]</property>
|
<property name="label" comments="This is a placeholder string and will be replaced with the hostname of the system">[lock]</property>
|
||||||
<attributes>
|
|
||||||
<attribute name="font-desc" value="Sans 18"/>
|
|
||||||
</attributes>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
|
@ -97,10 +94,11 @@
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="message_label">
|
<object class="GtkLabel" id="message_label">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="yalign">0</property>
|
||||||
<property name="label" comments="This is a placeholder string and will be replaced with a message from PAM">[message]</property>
|
<property name="label" comments="This is a placeholder string and will be replaced with a message from PAM">[message]</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
|
@ -118,7 +116,6 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_action_appearance">False</property>
|
<property name="use_action_appearance">False</property>
|
||||||
<signal name="clicked" handler="login_cb" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
|
@ -135,7 +132,6 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="use_action_appearance">False</property>
|
<property name="use_action_appearance">False</property>
|
||||||
<signal name="clicked" handler="cancel_cb" swapped="no"/>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
|
|
Reference in a new issue