2016-03-15 18:05:19 +01:00
import sys
2016-02-18 17:15:38 +01:00
from loginscreen import LoginScreen
2016-07-05 20:43:51 +02:00
import profile_
2016-04-03 22:51:46 +02:00
from settings import *
2016-05-24 20:22:21 +02:00
try :
from PySide import QtCore , QtGui
except ImportError :
from PyQt4 import QtCore , QtGui
2016-03-15 18:05:19 +01:00
from bootstrap import node_generator
2016-02-19 11:41:54 +01:00
from mainscreen import MainWindow
2016-02-22 22:18:58 +01:00
from callbacks import init_callbacks
2016-07-05 20:43:51 +02:00
from util import curr_directory , program_version
2016-03-21 11:55:50 +01:00
import styles . style
2016-05-15 16:39:49 +02:00
import toxencryptsave
2016-07-02 14:40:06 +02:00
from passwordscreen import PasswordScreen , UnlockAppScreen
2016-05-28 12:06:13 +02:00
from plugin_support import PluginLoader
2016-02-18 17:15:38 +01:00
2016-06-22 13:35:22 +02:00
class Toxygen :
2016-02-19 16:04:53 +01:00
2016-06-06 12:29:17 +02:00
def __init__ ( self , path_or_uri = None ) :
2016-03-15 18:05:19 +01:00
super ( Toxygen , self ) . __init__ ( )
2016-04-24 12:45:11 +02:00
self . tox = self . ms = self . init = self . mainloop = self . avloop = None
2016-06-06 12:29:17 +02:00
if path_or_uri is None :
self . uri = self . path = None
elif path_or_uri . startswith ( ' tox: ' ) :
self . path = None
self . uri = path_or_uri [ 4 : ]
else :
self . path = path_or_uri
self . uri = None
2016-02-19 11:41:54 +01:00
2016-05-15 18:54:44 +02:00
def enter_pass ( self , data ) :
2016-05-15 16:39:49 +02:00
"""
Show password screen
"""
2016-05-15 18:54:44 +02:00
tmp = [ data ]
2016-07-01 22:15:00 +02:00
p = PasswordScreen ( toxencryptsave . ToxEncryptSave . get_instance ( ) , tmp )
2016-05-15 18:54:44 +02:00
p . show ( )
self . app . connect ( self . app , QtCore . SIGNAL ( " lastWindowClosed() " ) , self . app , QtCore . SLOT ( " quit() " ) )
self . app . exec_ ( )
if tmp [ 0 ] == data :
raise SystemExit ( )
else :
return tmp [ 0 ]
2016-05-15 16:39:49 +02:00
2016-03-15 18:05:19 +01:00
def main ( self ) :
2016-02-19 16:04:53 +01:00
"""
2016-04-03 22:51:46 +02:00
Main function of app . loads login screen if needed and starts main screen
2016-03-15 18:05:19 +01:00
"""
app = QtGui . QApplication ( sys . argv )
app . setWindowIcon ( QtGui . QIcon ( curr_directory ( ) + ' /images/icon.png ' ) )
2016-05-15 18:54:44 +02:00
self . app = app
2016-03-21 15:23:34 +01:00
# application color scheme
with open ( curr_directory ( ) + ' /styles/style.qss ' ) as fl :
dark_style = fl . read ( )
app . setStyleSheet ( dark_style )
2016-05-15 16:39:49 +02:00
2016-07-01 22:15:00 +02:00
encrypt_save = toxencryptsave . ToxEncryptSave ( )
2016-05-15 16:39:49 +02:00
2016-05-06 12:31:18 +02:00
if self . path is not None :
2016-06-23 14:04:36 +02:00
path = os . path . dirname ( self . path ) + ' / '
name = os . path . basename ( self . path ) [ : - 4 ]
2016-05-14 12:18:17 +02:00
data = ProfileHelper ( path , name ) . open_profile ( )
2016-05-15 16:39:49 +02:00
if encrypt_save . is_data_encrypted ( data ) :
data = self . enter_pass ( data )
2016-04-03 22:51:46 +02:00
settings = Settings ( name )
2016-07-05 20:43:51 +02:00
self . tox = profile_ . tox_factory ( data , settings )
2016-05-06 12:31:18 +02:00
else :
auto_profile = Settings . get_auto_profile ( )
2016-06-18 21:32:14 +02:00
if not auto_profile [ 0 ] :
2016-05-06 12:31:18 +02:00
# show login screen if default profile not found
current_locale = QtCore . QLocale ( )
curr_lang = current_locale . languageToString ( current_locale . language ( ) )
langs = Settings . supported_languages ( )
2016-06-18 22:50:12 +02:00
if curr_lang in langs :
lang_path = langs [ curr_lang ]
2016-05-06 12:31:18 +02:00
translator = QtCore . QTranslator ( )
translator . load ( curr_directory ( ) + ' /translations/ ' + lang_path )
app . installTranslator ( translator )
app . translator = translator
ls = LoginScreen ( )
ls . setWindowIconText ( " Toxygen " )
profiles = ProfileHelper . find_profiles ( )
ls . update_select ( map ( lambda x : x [ 1 ] , profiles ) )
_login = self . Login ( profiles )
ls . update_on_close ( _login . login_screen_close )
ls . show ( )
app . connect ( app , QtCore . SIGNAL ( " lastWindowClosed() " ) , app , QtCore . SLOT ( " quit() " ) )
app . exec_ ( )
if not _login . t :
return
elif _login . t == 1 : # create new profile
2016-06-23 14:04:36 +02:00
_login . name = _login . name . strip ( )
2016-05-06 12:31:18 +02:00
name = _login . name if _login . name else ' toxygen_user '
2016-07-05 20:43:51 +02:00
self . tox = profile_ . tox_factory ( )
2016-06-23 14:04:36 +02:00
self . tox . self_set_name ( bytes ( _login . name , ' utf-8 ' ) if _login . name else b ' Toxygen User ' )
self . tox . self_set_status_message ( b ' Toxing on Toxygen ' )
2016-05-14 12:18:17 +02:00
ProfileHelper ( Settings . get_default_path ( ) , name ) . save_profile ( self . tox . get_savedata ( ) )
2016-05-06 12:31:18 +02:00
path = Settings . get_default_path ( )
settings = Settings ( name )
2016-07-03 23:41:37 +02:00
if curr_lang in langs :
settings [ ' language ' ] = curr_lang
settings . save ( )
2016-05-06 12:31:18 +02:00
else : # load existing profile
path , name = _login . get_data ( )
if _login . default :
Settings . set_auto_profile ( path , name )
2016-05-14 12:18:17 +02:00
data = ProfileHelper ( path , name ) . open_profile ( )
2016-05-15 16:39:49 +02:00
if encrypt_save . is_data_encrypted ( data ) :
data = self . enter_pass ( data )
2016-05-06 12:31:18 +02:00
settings = Settings ( name )
2016-07-05 20:43:51 +02:00
self . tox = profile_ . tox_factory ( data , settings )
2016-05-06 12:31:18 +02:00
else :
path , name = auto_profile
2016-05-14 12:18:17 +02:00
data = ProfileHelper ( path , name ) . open_profile ( )
2016-05-15 16:39:49 +02:00
if encrypt_save . is_data_encrypted ( data ) :
data = self . enter_pass ( data )
2016-05-06 12:31:18 +02:00
settings = Settings ( name )
2016-07-05 20:43:51 +02:00
self . tox = profile_ . tox_factory ( data , settings )
2016-03-10 21:04:43 +01:00
2016-06-18 21:32:14 +02:00
if Settings . is_active_profile ( path , name ) : # profile is in use
2016-04-03 22:51:46 +02:00
reply = QtGui . QMessageBox . question ( None ,
' Profile {} ' . format ( name ) ,
2016-07-03 23:41:37 +02:00
QtGui . QApplication . translate ( " login " , ' Other instance of Toxygen uses this profile or profile was not properly closed. Continue? ' , None , QtGui . QApplication . UnicodeUTF8 ) ,
2016-04-03 22:51:46 +02:00
QtGui . QMessageBox . Yes ,
QtGui . QMessageBox . No )
if reply != QtGui . QMessageBox . Yes :
return
else :
settings . set_active_profile ( )
2016-06-18 22:50:12 +02:00
lang = Settings . supported_languages ( ) [ settings [ ' language ' ] ]
2016-04-04 11:20:32 +02:00
translator = QtCore . QTranslator ( )
2016-06-19 18:07:42 +02:00
translator . load ( curr_directory ( ) + ' /translations/ ' + lang )
2016-04-04 11:20:32 +02:00
app . installTranslator ( translator )
app . translator = translator
2016-03-15 20:12:37 +01:00
# tray icon
self . tray = QtGui . QSystemTrayIcon ( QtGui . QIcon ( curr_directory ( ) + ' /images/icon.png ' ) )
2016-04-04 11:20:32 +02:00
self . tray . setObjectName ( ' tray ' )
2016-04-04 13:00:50 +02:00
2016-06-03 12:48:41 +02:00
self . ms = MainWindow ( self . tox , self . reset , self . tray )
2016-04-04 13:00:50 +02:00
class Menu ( QtGui . QMenu ) :
2016-05-24 20:08:52 +02:00
def newStatus ( self , status ) :
2016-07-05 20:43:51 +02:00
profile_ . Profile . get_instance ( ) . set_status ( status )
2016-05-24 20:08:52 +02:00
self . aboutToShow ( )
self . hide ( )
def aboutToShow ( self ) :
2016-07-05 20:43:51 +02:00
status = profile_ . Profile . get_instance ( ) . status
2016-05-24 20:08:52 +02:00
act = self . act
2016-07-02 14:40:06 +02:00
if status is None or Settings . get_instance ( ) . locked :
2016-05-24 20:08:52 +02:00
self . actions ( ) [ 1 ] . setVisible ( False )
else :
self . actions ( ) [ 1 ] . setVisible ( True )
act . actions ( ) [ 0 ] . setChecked ( False )
act . actions ( ) [ 1 ] . setChecked ( False )
act . actions ( ) [ 2 ] . setChecked ( False )
act . actions ( ) [ status ] . setChecked ( True )
2016-07-02 14:40:06 +02:00
self . actions ( ) [ 2 ] . setVisible ( not Settings . get_instance ( ) . locked )
2016-05-24 20:08:52 +02:00
2016-04-04 13:00:50 +02:00
def languageChange ( self , * args , * * kwargs ) :
self . actions ( ) [ 0 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Open Toxygen ' , None , QtGui . QApplication . UnicodeUTF8 ) )
2016-05-24 20:08:52 +02:00
self . actions ( ) [ 1 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Set status ' , None , QtGui . QApplication . UnicodeUTF8 ) )
self . actions ( ) [ 2 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Exit ' , None , QtGui . QApplication . UnicodeUTF8 ) )
self . act . actions ( ) [ 0 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Online ' , None , QtGui . QApplication . UnicodeUTF8 ) )
self . act . actions ( ) [ 1 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Away ' , None , QtGui . QApplication . UnicodeUTF8 ) )
self . act . actions ( ) [ 2 ] . setText ( QtGui . QApplication . translate ( ' tray ' , ' Busy ' , None , QtGui . QApplication . UnicodeUTF8 ) )
2016-04-04 13:00:50 +02:00
m = Menu ( )
2016-04-04 11:20:32 +02:00
show = m . addAction ( QtGui . QApplication . translate ( ' tray ' , ' Open Toxygen ' , None , QtGui . QApplication . UnicodeUTF8 ) )
2016-05-24 20:08:52 +02:00
sub = m . addMenu ( QtGui . QApplication . translate ( ' tray ' , ' Set status ' , None , QtGui . QApplication . UnicodeUTF8 ) )
onl = sub . addAction ( QtGui . QApplication . translate ( ' tray ' , ' Online ' , None , QtGui . QApplication . UnicodeUTF8 ) )
away = sub . addAction ( QtGui . QApplication . translate ( ' tray ' , ' Away ' , None , QtGui . QApplication . UnicodeUTF8 ) )
busy = sub . addAction ( QtGui . QApplication . translate ( ' tray ' , ' Busy ' , None , QtGui . QApplication . UnicodeUTF8 ) )
onl . setCheckable ( True )
away . setCheckable ( True )
busy . setCheckable ( True )
m . act = sub
2016-04-04 11:20:32 +02:00
exit = m . addAction ( QtGui . QApplication . translate ( ' tray ' , ' Exit ' , None , QtGui . QApplication . UnicodeUTF8 ) )
2016-04-01 16:38:24 +02:00
def show_window ( ) :
2016-07-02 14:40:06 +02:00
def show ( ) :
if not self . ms . isActiveWindow ( ) :
self . ms . setWindowState ( self . ms . windowState ( ) & ~ QtCore . Qt . WindowMinimized | QtCore . Qt . WindowActive )
self . ms . activateWindow ( )
self . ms . show ( )
if not Settings . get_instance ( ) . locked :
show ( )
else :
def correct_pass ( ) :
show ( )
Settings . get_instance ( ) . locked = False
self . p = UnlockAppScreen ( toxencryptsave . ToxEncryptSave . get_instance ( ) , correct_pass )
self . p . show ( )
2016-04-01 16:38:24 +02:00
m . connect ( show , QtCore . SIGNAL ( " triggered() " ) , show_window )
2016-04-01 16:09:45 +02:00
m . connect ( exit , QtCore . SIGNAL ( " triggered() " ) , lambda : app . exit ( ) )
2016-05-24 20:08:52 +02:00
m . connect ( m , QtCore . SIGNAL ( " aboutToShow() " ) , lambda : m . aboutToShow ( ) )
sub . connect ( onl , QtCore . SIGNAL ( " triggered() " ) , lambda : m . newStatus ( 0 ) )
sub . connect ( away , QtCore . SIGNAL ( " triggered() " ) , lambda : m . newStatus ( 1 ) )
sub . connect ( busy , QtCore . SIGNAL ( " triggered() " ) , lambda : m . newStatus ( 2 ) )
2016-06-03 12:48:41 +02:00
2016-04-01 16:09:45 +02:00
self . tray . setContextMenu ( m )
2016-03-15 20:12:37 +01:00
self . tray . show ( )
2016-03-15 18:05:19 +01:00
self . ms . show ( )
2016-03-10 21:04:43 +01:00
2016-05-28 12:06:13 +02:00
plugin_helper = PluginLoader ( self . tox , settings ) # plugin support
plugin_helper . load ( )
2016-03-15 18:05:19 +01:00
# init thread
2016-03-15 20:12:37 +01:00
self . init = self . InitThread ( self . tox , self . ms , self . tray )
2016-03-15 18:05:19 +01:00
self . init . start ( )
2016-02-19 22:10:24 +01:00
2016-04-24 12:45:11 +02:00
# starting threads for tox iterate and toxav iterate
2016-03-15 18:05:19 +01:00
self . mainloop = self . ToxIterateThread ( self . tox )
self . mainloop . start ( )
2016-04-24 12:45:11 +02:00
self . avloop = self . ToxAVIterateThread ( self . tox . AV )
self . avloop . start ( )
2016-05-28 12:06:13 +02:00
2016-06-06 12:29:17 +02:00
if self . uri is not None :
self . ms . add_contact ( self . uri )
2016-03-15 18:05:19 +01:00
app . connect ( app , QtCore . SIGNAL ( " lastWindowClosed() " ) , app , QtCore . SLOT ( " quit() " ) )
app . exec_ ( )
2016-03-15 21:35:15 +01:00
self . init . stop = True
2016-03-15 18:05:19 +01:00
self . mainloop . stop = True
2016-04-24 12:45:11 +02:00
self . avloop . stop = True
2016-05-28 12:06:13 +02:00
plugin_helper . stop ( )
2016-03-15 18:05:19 +01:00
self . mainloop . wait ( )
2016-03-15 21:35:15 +01:00
self . init . wait ( )
2016-04-24 12:45:11 +02:00
self . avloop . wait ( )
2016-03-15 18:05:19 +01:00
data = self . tox . get_savedata ( )
2016-05-14 12:18:17 +02:00
ProfileHelper . get_instance ( ) . save_profile ( data )
2016-04-12 15:11:10 +02:00
settings . close ( )
2016-03-15 18:05:19 +01:00
del self . tox
2016-02-19 16:04:53 +01:00
2016-03-15 18:05:19 +01:00
def reset ( self ) :
"""
Create new tox instance ( new network settings )
: return : tox instance
"""
self . mainloop . stop = True
2016-03-15 20:42:24 +01:00
self . init . stop = True
2016-04-24 12:45:11 +02:00
self . avloop . stop = True
2016-03-15 18:05:19 +01:00
self . mainloop . wait ( )
2016-03-15 20:42:24 +01:00
self . init . wait ( )
2016-04-24 12:45:11 +02:00
self . avloop . wait ( )
2016-03-15 18:05:19 +01:00
data = self . tox . get_savedata ( )
2016-05-14 12:18:17 +02:00
ProfileHelper . get_instance ( ) . save_profile ( data )
2016-03-15 18:05:19 +01:00
del self . tox
# create new tox instance
2016-07-05 20:43:51 +02:00
self . tox = profile_ . tox_factory ( data , Settings . get_instance ( ) )
2016-03-15 18:05:19 +01:00
# init thread
2016-03-15 20:12:37 +01:00
self . init = self . InitThread ( self . tox , self . ms , self . tray )
2016-03-15 18:05:19 +01:00
self . init . start ( )
2016-04-24 12:45:11 +02:00
# starting threads for tox iterate and toxav iterate
2016-03-15 18:05:19 +01:00
self . mainloop = self . ToxIterateThread ( self . tox )
self . mainloop . start ( )
2016-04-24 12:45:11 +02:00
self . avloop = self . ToxAVIterateThread ( self . tox . AV )
self . avloop . start ( )
2016-05-28 12:06:13 +02:00
plugin_helper = PluginLoader . get_instance ( )
plugin_helper . set_tox ( self . tox )
2016-03-15 18:05:19 +01:00
return self . tox
2016-03-15 21:54:01 +01:00
# -----------------------------------------------------------------------------------------------------------------
# Inner classes
# -----------------------------------------------------------------------------------------------------------------
2016-03-15 18:05:19 +01:00
class InitThread ( QtCore . QThread ) :
2016-03-15 20:12:37 +01:00
def __init__ ( self , tox , ms , tray ) :
2016-03-15 18:05:19 +01:00
QtCore . QThread . __init__ ( self )
2016-03-15 20:12:37 +01:00
self . tox , self . ms , self . tray = tox , ms , tray
2016-03-15 20:42:24 +01:00
self . stop = False
2016-03-15 18:05:19 +01:00
def run ( self ) :
# initializing callbacks
2016-03-15 20:12:37 +01:00
init_callbacks ( self . tox , self . ms , self . tray )
2016-03-15 18:05:19 +01:00
# bootstrap
2016-03-16 16:15:55 +01:00
try :
2016-03-15 18:05:19 +01:00
for data in node_generator ( ) :
2016-04-03 22:51:46 +02:00
if self . stop :
return
2016-03-15 18:05:19 +01:00
self . tox . bootstrap ( * data )
2016-03-16 16:15:55 +01:00
except :
pass
2016-06-21 13:58:11 +02:00
for _ in range ( 10 ) :
2016-04-03 22:51:46 +02:00
if self . stop :
return
self . msleep ( 1000 )
while not self . tox . self_get_connection_status ( ) :
2016-03-16 16:15:55 +01:00
try :
for data in node_generator ( ) :
2016-04-03 22:51:46 +02:00
if self . stop :
return
2016-03-16 16:15:55 +01:00
self . tox . bootstrap ( * data )
except :
pass
finally :
self . msleep ( 5000 )
2016-03-15 18:05:19 +01:00
class ToxIterateThread ( QtCore . QThread ) :
def __init__ ( self , tox ) :
QtCore . QThread . __init__ ( self )
self . tox = tox
self . stop = False
def run ( self ) :
while not self . stop :
self . tox . iterate ( )
self . msleep ( self . tox . iteration_interval ( ) )
2016-04-24 12:45:11 +02:00
class ToxAVIterateThread ( QtCore . QThread ) :
def __init__ ( self , toxav ) :
QtCore . QThread . __init__ ( self )
self . toxav = toxav
self . stop = False
def run ( self ) :
while not self . stop :
self . toxav . iterate ( )
self . msleep ( self . toxav . iteration_interval ( ) )
2016-06-22 13:35:22 +02:00
class Login :
2016-03-15 18:05:19 +01:00
def __init__ ( self , arr ) :
self . arr = arr
def login_screen_close ( self , t , number = - 1 , default = False , name = None ) :
""" Function which processes data from login screen
: param t : 0 - window was closed , 1 - new profile was created , 2 - profile loaded
2016-04-14 14:01:59 +02:00
: param number : num of chosen profile in list ( - 1 by default )
: param default : was or not chosen profile marked as default
2016-03-15 18:05:19 +01:00
: param name : name of new profile
"""
self . t = t
self . num = number
self . default = default
self . name = name
def get_data ( self ) :
return self . arr [ self . num ]
2016-02-19 11:41:54 +01:00
2016-07-05 20:43:51 +02:00
def main ( ) :
2016-05-06 12:31:18 +02:00
if len ( sys . argv ) == 1 :
toxygen = Toxygen ( )
2016-07-05 20:43:51 +02:00
else : # path to profile or tox: uri or --version or --help
arg = sys . argv [ 1 ]
if arg == ' --version ' :
print ( ' Toxygen ' + program_version )
return
elif arg == ' --help ' :
print ( ' Usage: \n toxygen path_to_profile \n toxygen tox_id \n toxygen --version ' )
return
else :
toxygen = Toxygen ( arg )
2016-03-15 18:05:19 +01:00
toxygen . main ( )
2016-07-05 20:43:51 +02:00
if __name__ == ' __main__ ' :
main ( )