Merge pull request #168 from Jalakas/master

flake8 suggested fixes
This commit is contained in:
Gobinath 2017-07-06 05:58:55 -04:00 committed by GitHub
commit eedb2c53c7
10 changed files with 83 additions and 105 deletions

View File

@ -18,13 +18,15 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkX11
from gi.repository import Gtk
"""
AboutDialog reads the about_dialog.glade and build the user interface using that file.
It shows the application name with version, a small description, license and the GitHub url.
"""
class AboutDialog:
"""
@ -42,21 +44,18 @@ class AboutDialog:
# Set the version at the runtime
builder.get_object("lbl_app_name").set_label("Safe Eyes " + version)
"""
Show the About dialog.
"""
def show(self):
self.window.show_all()
"""
Window close event handler.
"""
def on_window_delete(self, *args):
self.window.destroy()
"""
Close button click event handler.
"""

View File

@ -16,16 +16,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import gi, signal, sys, threading, logging
from Xlib import Xatom, Xutil
import gi, threading, logging
from Xlib.display import Display, X
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib, GdkX11
from gi.repository import Gtk, Gdk, GLib
"""
The fullscreen window which prevents users from using the computer.
"""
class BreakScreen:
def __init__(self, context, on_skip, on_postpone, glade_file, style_sheet_path):
@ -46,7 +47,6 @@ class BreakScreen:
css_provider.load_from_path(style_sheet_path)
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def initialize(self, config, language):
"""
Initialize the internal properties from configuration
@ -60,7 +60,6 @@ class BreakScreen:
self.keycode_shortcut_postpone = config.get('shortcut_postpone', 65)
self.shortcut_disable_time = config.get('shortcut_disable_time', 2)
def skip_break(self):
"""
Skip the break from the break screen
@ -86,14 +85,12 @@ class BreakScreen:
self.__release_keyboard()
self.close()
def on_skip_clicked(self, button):
"""
Skip button press event handler.
"""
self.skip_break()
def on_postpone_clicked(self, button):
"""
Postpone button press event handler.
@ -109,7 +106,6 @@ class BreakScreen:
timeformat = '{:02d}:{:02d}'.format(mins, secs)
GLib.idle_add(lambda: self.__update_count_down(timeformat))
def show_message(self, message, image_path, plugins_data):
"""
Show the break screen with the given message on all displays.
@ -117,7 +113,6 @@ class BreakScreen:
self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= 0
GLib.idle_add(lambda: self.__show_break_screen(message, image_path, plugins_data))
def close(self):
"""
Hide the break screen from active window and destroy all other windows
@ -128,7 +123,6 @@ class BreakScreen:
# Destroy other windows if exists
GLib.idle_add(lambda: self.__destroy_all_screens())
def __show_break_screen(self, message, image_path, plugins_data):
"""
Show an empty break screen on all screens.
@ -175,14 +169,12 @@ class BreakScreen:
btn_skip.set_visible(True)
box_buttons.pack_start(btn_skip, True, True, 0)
# Set values
if image_path:
img_break.set_from_file(image_path)
lbl_message.set_label(message)
lbl_left.set_markup(plugins_data['left']);
lbl_right.set_markup(plugins_data['right']);
lbl_left.set_markup(plugins_data['left'])
lbl_right.set_markup(plugins_data['right'])
self.windows.append(window)
self.count_labels.append(lbl_count)
@ -199,7 +191,6 @@ class BreakScreen:
window.present()
window.fullscreen()
def __update_count_down(self, count):
"""
Update the countdown on all break screens.
@ -207,7 +198,6 @@ class BreakScreen:
for label in self.count_labels:
label.set_text(count)
def __lock_keyboard(self):
"""
Lock the keyboard to prevent the user from using keyboard shortcuts
@ -217,11 +207,11 @@ class BreakScreen:
display = Display()
root = display.screen().root
# Grap the keyboard
root.grab_keyboard(owner_events = False, pointer_mode = X.GrabModeAsync, keyboard_mode = X.GrabModeAsync, time = X.CurrentTime)
root.grab_keyboard(owner_events=False, pointer_mode=X.GrabModeAsync, keyboard_mode=X.GrabModeAsync, time=X.CurrentTime)
# Consume keyboard events
while self.lock_keyboard:
event = display.next_event()
display.allow_events(mode = X.AsyncBoth, time = X.CurrentTime)
display.allow_events(mode=X.AsyncBoth, time=X.CurrentTime)
if self.enable_shortcut and event.type == X.KeyPress:
if event.detail == self.keycode_shortcut_skip:
self.skip_break()
@ -235,14 +225,12 @@ class BreakScreen:
display.ungrab_keyboard(X.CurrentTime)
display.flush()
def __release_keyboard(self):
"""
Release the locked keyboard.
"""
self.lock_keyboard = False
def __destroy_all_screens(self):
"""
Close all the break screens.

View File

@ -24,12 +24,12 @@ from safeeyes import Utility
APPINDICATOR_ID = 'safeeyes'
class Notification:
"""
This class is responsible for the notification to the user before the break.
"""
def __init__(self, context, language):
"""
Initialize the notification.
@ -39,14 +39,12 @@ class Notification:
self.context = context
self.language = language
def initialize(self, language):
"""
Initialize the notification object.
"""
self.language = language
def show(self, warning_time):
"""
Show the notification
@ -66,7 +64,6 @@ class Notification:
except Exception as e:
logging.exception('Error in showing notification', e)
def close(self):
"""
Close the notification if it is not closed by the system already.
@ -78,7 +75,6 @@ class Notification:
# Some Linux systems automatically close the notification.
pass
def quite(self):
"""
Uninitialize the notification. Call this method when closing the application.

View File

@ -23,12 +23,12 @@ from safeeyes import Utility
plugins_directory = os.path.join(Utility.config_directory, 'plugins')
sys.path.append(os.path.abspath(plugins_directory))
class Plugins:
"""
This class manages imports the plugins and calls the methods defined in those plugins.
"""
def __init__(self, config):
"""
Load the plugins.
@ -52,7 +52,6 @@ class Plugins:
if self.__plugins:
self.__thread_pool = ThreadPool(min([4, len(self.__plugins)]))
def start(self, context):
"""
Call the start function of all the plugins in separate thread.
@ -77,7 +76,6 @@ class Plugins:
except Exception as e:
pass
def pre_break(self, context):
"""
Call the pre_break function of all the plugins and provide maximum 1 second to return the result.
@ -105,7 +103,6 @@ class Plugins:
return output
def post_break(self, context):
"""
Call the post_break function of all the plugins in separate thread.
@ -139,8 +136,7 @@ class Plugins:
except Exception as e:
pass
def __has_method(self, module, method_name, no_of_args = 1):
def __has_method(self, module, method_name, no_of_args=1):
"""
Check whether the given function is defined in the module or not.
"""

View File

@ -17,13 +17,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import time, datetime, threading, sys, subprocess, logging
import time, datetime, threading, logging
from safeeyes import Utility
"""
Core of Safe Eyes which runs the scheduler and notifies the breaks.
"""
class SafeEyesCore:
"""
@ -48,14 +50,13 @@ class SafeEyesCore:
self.context['skipped'] = False
self.context['postponed'] = False
"""
Initialize the internal properties from configuration
"""
def initialize(self, config, language):
logging.info("Initialize the core")
self.short_break_exercises = [] #language['exercises']['short_break_exercises']
self.long_break_exercises = [] #language['exercises']['long_break_exercises']
self.short_break_exercises = [] # language['exercises']['short_break_exercises']
self.long_break_exercises = [] # language['exercises']['long_break_exercises']
self.no_of_short_breaks_per_long_break = config['no_of_short_breaks_per_long_break']
self.pre_break_warning_time = config['pre_break_warning_time']
@ -111,7 +112,6 @@ class SafeEyesCore:
self.long_break_exercises.append([name, break_time, audible_alert, image])
"""
Start Safe Eyes is it is not running already.
"""
@ -125,7 +125,6 @@ class SafeEyesCore:
if self.context['idle_pause_enabled']:
Utility.start_thread(self.__start_idle_monitor)
"""
Stop Safe Eyes if it is running.
"""
@ -150,7 +149,6 @@ class SafeEyesCore:
self.idle_condition.notify_all()
self.idle_condition.release()
"""
Pause Safe Eyes if it is running.
"""
@ -162,7 +160,6 @@ class SafeEyesCore:
self.notification_condition.notify_all()
self.notification_condition.release()
"""
Resume Safe Eyes if it is not running.
"""
@ -172,7 +169,6 @@ class SafeEyesCore:
self.running = True
Utility.start_thread(self.__scheduler_job)
"""
User skipped the break using Skip button
"""
@ -185,7 +181,6 @@ class SafeEyesCore:
def postpone_break(self):
self.context['postponed'] = True
"""
Scheduler task to execute during every interval
"""
@ -235,7 +230,6 @@ class SafeEyesCore:
self.is_before_break = False
Utility.execute_main_thread(self.__check_active_window)
"""
Show the notification and start the break after the notification.
"""
@ -252,7 +246,6 @@ class SafeEyesCore:
self.is_before_break = True
Utility.execute_main_thread(self.__check_active_window)
"""
Check the active window for full-screen and user defined exceptions.
"""
@ -272,8 +265,6 @@ class SafeEyesCore:
else:
Utility.start_thread(self.__show_notification)
"""
Start the break screen.
"""
@ -327,22 +318,18 @@ class SafeEyesCore:
# Schedule the break again
Utility.start_thread(self.__scheduler_job)
"""
Tells whether Safe Eyes is running or not.
"""
def __is_running(self):
return self.active and self.running
"""
Check if the current break is long break or short current
"""
def __is_long_break(self):
return self.break_count == self.no_of_short_breaks_per_long_break - 1
"""
Continuously check the system idle time and pause/resume Safe Eyes based on it.
"""

View File

@ -18,9 +18,10 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkX11, GObject
from gi.repository import Gtk, GObject
from safeeyes import Utility
class SettingsDialog:
"""
Create and initialize SettingsDialog instance.
@ -129,19 +130,17 @@ class SettingsDialog:
language_index += 1
self.cmb_language.set_model(language_list_store)
self.cmb_language.set_row_separator_func(lambda m,i: m.get_value(i, 0) == '-')
self.cmb_language.set_row_separator_func(lambda m, i: m.get_value(i, 0) == '-')
cell = Gtk.CellRendererText()
self.cmb_language.pack_start(cell, True)
self.cmb_language.add_attribute(cell, 'text', 0)
def show(self):
"""
Show the SettingsDialog.
"""
self.window.show_all()
def on_switch_screen_lock_activate(self, switch, state):
"""
Event handler to the state change of the screen_lock switch.
@ -149,13 +148,12 @@ class SettingsDialog:
"""
self.spin_time_to_screen_lock.set_sensitive(self.switch_screen_lock.get_active())
def on_switch_strict_break_activate(self, switch, state):
"""
Event handler to the state change of the postpone switch.
Enable or disable the self.spin_postpone_duration based on the state of the postpone switch.
"""
strict_break_enable = state #self.switch_strict_break.get_active()
strict_break_enable = state # self.switch_strict_break.get_active()
self.switch_postpone.set_sensitive(not strict_break_enable)
if strict_break_enable:
self.switch_postpone.set_active(False)
@ -183,7 +181,6 @@ class SettingsDialog:
"""
self.window.destroy()
def on_save_clicked(self, button):
"""
Event handler for Save button click.
@ -213,7 +210,6 @@ class SettingsDialog:
self.on_save_settings(self.config) # Call the provided save method
self.window.destroy() # Close the settings window
def on_cancel_clicked(self, button):
"""
Event handler for Cancel button click.

View File

@ -231,7 +231,6 @@ class TrayIcon:
Utility.start_thread(self.__schedule_resume, time_minutes=time_to_wait)
self.item_info.set_label(self.language['messages']['disabled_until_x'].format(Utility.format_time(self.wakeup_time)))
"""
This method is called by the core to prevent user from disabling Safe Eyes after the notification.
"""

View File

@ -18,7 +18,7 @@
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk, Gdk, GLib
from gi.repository import Gdk, GLib
from html.parser import HTMLParser
from distutils.version import LooseVersion
from logging.handlers import RotatingFileHandler
@ -65,7 +65,8 @@ def play_notification():
# Create a sound stream
wrapper = pyaudio.PyAudio()
stream = wrapper.open(format=wrapper.get_format_from_width(sound.getsampwidth()),
stream = wrapper.open(format=wrapper.get_format_from_width(
sound.getsampwidth()),
channels=sound.getnchannels(),
rate=sound.getframerate(),
output=True)
@ -144,7 +145,7 @@ def is_active_window_skipped(skip_break_window_classes, take_break_window_classe
active_window = screen.get_active_window()
if active_window:
active_xid = str(active_window.get_xid())
cmdlist = ['xprop', '-root', '-notype','-id',active_xid, 'WM_CLASS', '_NET_WM_STATE']
cmdlist = ['xprop', '-root', '-notype', '-id', active_xid, 'WM_CLASS', '_NET_WM_STATE']
try:
stdout = subprocess.check_output(cmdlist).decode('utf-8')
@ -206,6 +207,7 @@ def mkdir(path):
logging.error('Error while creating ' + str(path))
raise
def parse_language_code(lang_code):
"""
Convert the user defined language code to a valid one.
@ -273,7 +275,7 @@ def desktop_environment():
current_desktop = os.environ.get('XDG_CURRENT_DESKTOP')
if desktop_session is not None:
desktop_session = desktop_session.lower()
if desktop_session in ['gnome','unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep','trinity', 'kde']:
if desktop_session in ['gnome', 'unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep', 'trinity', 'kde']:
return desktop_session
elif (desktop_session.startswith('xubuntu') or (current_desktop is not None and 'xfce' in current_desktop)):
return 'xfce'
@ -314,14 +316,14 @@ def lock_screen_command():
return ['mate-screensaver-command', '--lock']
elif desktop_session == 'kde' or 'plasma' in desktop_session or desktop_session.startswith('kubuntu') or os.environ.get('KDE_FULL_SESSION') == 'true':
return ['qdbus', 'org.freedesktop.ScreenSaver', '/ScreenSaver', 'Lock']
elif desktop_session in ['gnome','unity', 'budgie-desktop'] or desktop_session.startswith('ubuntu'):
elif desktop_session in ['gnome', 'unity', 'budgie-desktop'] or desktop_session.startswith('ubuntu'):
if command_exist('gnome-screensaver-command'):
return ['gnome-screensaver-command', '--lock']
else:
# From Gnome 3.8 no gnome-screensaver-command
return ['dbus-send', '--type=method_call', '--dest=org.gnome.ScreenSaver', '/org/gnome/ScreenSaver', 'org.gnome.ScreenSaver.Lock']
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
if not 'deprecated' in os.environ.get('GNOME_DESKTOP_SESSION_ID') and command_exist('gnome-screensaver-command'):
if 'deprecated' not in os.environ.get('GNOME_DESKTOP_SESSION_ID') and command_exist('gnome-screensaver-command'):
# Gnome 2
return ['gnome-screensaver-command', '--lock']
return None
@ -417,7 +419,7 @@ def intialize_logging():
log_formatter = logging.Formatter('%(asctime)s [%(levelname)s]:[%(threadName)s] %(message)s')
# Apped the logs and overwrite once reached 5MB
handler = RotatingFileHandler(log_file_path, mode='a', maxBytes=5*1024*1024, backupCount=2, encoding=None, delay=0)
handler = RotatingFileHandler(log_file_path, mode='a', maxBytes=5 * 1024 * 1024, backupCount=2, encoding=None, delay=0)
handler.setFormatter(log_formatter)
handler.setLevel(logging.INFO)
@ -484,7 +486,7 @@ class __HTMLTextExtractor(HTMLParser):
def __init__(self):
self.reset()
self.strict = False
self.convert_charrefs= True
self.convert_charrefs = True
self.fed = []
def handle_data(self, d):

View File

@ -18,7 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os, gi, json, dbus, logging, operator, psutil, sys
import os, gi, json, dbus, logging, psutil, sys
from threading import Timer
from dbus.mainloop.glib import DBusGMainLoop
gi.require_version('Gtk', '3.0')
@ -41,6 +41,7 @@ about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.gla
is_active = True
SAFE_EYES_VERSION = "1.2.1"
"""
Listen to tray icon Settings action and send the signal to Settings dialog.
"""
@ -52,6 +53,7 @@ def show_settings():
settings_dialog = SettingsDialog(config, language, Utility.read_lang_files(), able_to_lock_screen, save_settings, settings_dialog_glade)
settings_dialog.show()
"""
Listen to tray icon About action and send the signal to About dialog.
"""
@ -60,6 +62,7 @@ def show_about():
about_dialog = AboutDialog(about_dialog_glade, SAFE_EYES_VERSION, language)
about_dialog.show()
"""
Receive the signal from core and pass it to the Notification.
"""
@ -69,6 +72,7 @@ def show_notification():
plugins.pre_notification(context)
notification.show(config['pre_break_warning_time'])
"""
Receive the break signal from core and pass it to the break screen.
"""
@ -80,6 +84,7 @@ def show_alert(message, image_name):
if config['strict_break'] and is_active:
Utility.execute_main_thread(tray_icon.unlock_menu)
"""
Receive the stop break signal from core and pass it to the break screen.
"""
@ -101,9 +106,10 @@ def on_quit():
logging.info("Quit Safe Eyes")
plugins.exit(context)
core.stop()
notification.quite();
notification.quite()
Gtk.main_quit()
"""
If the system goes to sleep, Safe Eyes stop the core if it is already active.
If it was active, Safe Eyes will become active after wake up.
@ -120,6 +126,7 @@ def handle_suspend_callback(sleeping):
core.start()
logging.info("Resumed Safe Eyes after system wakeup")
"""
Setup system suspend listener.
"""
@ -128,6 +135,7 @@ def handle_system_suspend():
bus = dbus.SystemBus()
bus.add_signal_receiver(handle_suspend_callback, 'PrepareForSleep', 'org.freedesktop.login1.Manager', 'org.freedesktop.login1')
"""
Listen to break screen Skip action and send the signal to core.
"""
@ -139,6 +147,7 @@ def on_skipped():
core.skip_break()
plugins.post_break(context)
"""
Listen to break screen Postpone action and send the signal to core.
"""
@ -149,6 +158,7 @@ def on_postponed():
Utility.lock_desktop(system_lock_command)
core.postpone_break()
"""
Listen to Settings dialog Save action and write to the config file.
"""
@ -180,6 +190,7 @@ def save_settings(config):
# 1 sec delay is required to give enough time for core to be stopped
Timer(1.0, core.start).start()
"""
Listen to tray icon enable action and send the signal to core.
"""
@ -188,6 +199,7 @@ def enable_safeeyes():
is_active = True
core.start()
"""
Listen to tray icon disable action and send the signal to core.
"""
@ -203,7 +215,8 @@ def running():
"""
process_count = 0
for proc in psutil.process_iter():
if not proc.cmdline: continue
if not proc.cmdline:
continue
try:
# Check if safeeyes is in process arguments
if callable(proc.cmdline):
@ -257,7 +270,6 @@ def main():
else:
system_lock_command = Utility.lock_screen_command()
# Initialize the Safe Eyes Context
context['version'] = SAFE_EYES_VERSION
context['desktop'] = Utility.desktop_environment()
@ -279,5 +291,6 @@ def main():
logging.info('Another instance of safeeyes is already running')
sys.exit(0)
if __name__ == '__main__':
main()

View File

@ -9,7 +9,7 @@ requires = [
extras = {
'audible_alert': ['pyaudio']
}
}
here = os.path.abspath(os.path.dirname(__file__))
@ -17,12 +17,14 @@ here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.md')) as f:
long_description = '\n' + f.read()
def _data_files(path):
for root, dirs, files in os.walk(path):
if not files:
continue
yield (os.path.join('/usr', root), [os.path.join(root, f) for f in files])
setuptools.setup(
name="safeeyes",
version="1.2.1",