Compare commits

...

10 Commits

Author SHA1 Message Date
ingvar1995 07b0401a43 pyqt5 fixes 2017-10-21 21:07:05 +03:00
ingvar1995 12a395616c initial 2017-06-20 20:55:11 +03:00
ingvar1995 937b577cee chess plugin - repaint, move resending and improvements 2017-03-15 22:44:55 +03:00
ingvar1995 0afde5faf7 avatars encryption plugin 2017-02-20 23:44:59 +03:00
ingvar1995 968d43affe utox send inline plugin 2016-11-05 17:03:22 +03:00
ingvar1995 dd4634c1a7 2 new plugins 2016-10-29 17:26:05 +03:00
ingvar1995 caa98208d5 chess plugin 2016-10-15 20:08:56 +03:00
ingvar1995 a8c1bd188f None status fix 2016-08-30 20:31:25 +03:00
ingvar1995 7708ce1d24 auto away status update 2016-08-29 20:59:22 +03:00
ingvar1995 5002dbe33f autoaway linux 2016-08-01 21:27:05 +03:00
30 changed files with 2360 additions and 66 deletions

45
AutoAnswer/aans.py Normal file
View File

@ -0,0 +1,45 @@
import plugin_super_class
from PyQt5 import QtGui, QtWidgets
import json
class AutoAnswer(plugin_super_class.PluginSuperClass):
def __init__(self, *args):
super(AutoAnswer, self).__init__('AutoAnswer', 'aans', *args)
self._data = json.loads(self.load_settings())
self._tmp = None
def get_description(self):
return QtWidgets.QApplication.translate("aans", 'Plugin which allows you to auto answer on calls.')
def start(self):
self._tmp = self._profile.incoming_call
def func(audio, video, friend_number):
if self._profile.get_friend_by_number(friend_number).tox_id in self._data['id']:
self._profile.accept_call(friend_number, audio, video)
else:
self._tmp(friend_number, audio, video)
self._profile.incoming_call = func
def stop(self):
self._profile.incoming_call = self._tmp
def get_menu(self, menu, num):
friend = self._profile.get_friend(num)
if friend.tox_id in self._data['id']:
text = 'Disallow auto answer'
else:
text = 'Allow auto answer'
act = QtWidgets.QAction(QtWidgets.QApplication.translate("aans", text), menu)
act.triggered.connect(lambda: self.toggle(friend.tox_id))
return [act]
def toggle(self, tox_id):
if tox_id in self._data['id']:
self._data['id'].remove(tox_id)
else:
self._data['id'].append(tox_id)
self.save_settings(json.dumps(self._data))

View File

@ -0,0 +1 @@
{"id": ["20E3E1DEB598C1A6B49B2D2F6BF1C181F4FE9C977B9098903F176269F32CEF1D"]}

View File

@ -0,0 +1,105 @@
import plugin_super_class
import threading
import time
from PyQt5 import QtCore, QtWidgets
from subprocess import check_output
import json
class InvokeEvent(QtCore.QEvent):
EVENT_TYPE = QtCore.QEvent.Type(QtCore.QEvent.registerEventType())
def __init__(self, fn, *args, **kwargs):
QtCore.QEvent.__init__(self, InvokeEvent.EVENT_TYPE)
self.fn = fn
self.args = args
self.kwargs = kwargs
class Invoker(QtCore.QObject):
def event(self, event):
event.fn(*event.args, **event.kwargs)
return True
_invoker = Invoker()
def invoke_in_main_thread(fn, *args, **kwargs):
QtCore.QCoreApplication.postEvent(_invoker, InvokeEvent(fn, *args, **kwargs))
class AutoAwayStatusLinux(plugin_super_class.PluginSuperClass):
def __init__(self, *args):
super().__init__('AutoAwayStatusLinux', 'awayl', *args)
self._thread = None
self._exec = None
self._active = False
self._time = json.loads(self.load_settings())['time']
self._prev_status = 0
def close(self):
self.stop()
def stop(self):
self._exec = False
if self._active:
self._thread.join()
def start(self):
self._exec = True
self._thread = threading.Thread(target=self.loop)
self._thread.start()
def save(self):
self.save_settings('{"time": ' + str(self._time) + '}')
def change_status(self, status=1):
if self._profile.status in (0, 2):
self._prev_status = self._profile.status
if status is not None:
invoke_in_main_thread(self._profile.set_status, status)
def get_window(self):
inst = self
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(QtCore.QRect(450, 300, 350, 100))
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(20, 0, 310, 35))
self.label.setText(QtWidgets.QApplication.translate("AutoAwayStatusLinux", "Auto away time in minutes\n(0 - to disable)"))
self.time = QtWidgets.QLineEdit(self)
self.time.setGeometry(QtCore.QRect(20, 40, 310, 25))
self.time.setText(str(inst._time))
self.setWindowTitle("AutoAwayStatusLinux")
self.ok = QtWidgets.QPushButton(self)
self.ok.setGeometry(QtCore.QRect(20, 70, 310, 25))
self.ok.setText(
QtWidgets.QApplication.translate("AutoAwayStatusLinux", "Save"))
self.ok.clicked.connect(self.update)
def update(self):
try:
t = int(self.time.text())
except:
t = 0
inst._time = t
inst.save()
self.close()
return Window()
def loop(self):
self._active = True
while self._exec:
time.sleep(5)
d = check_output(['xprintidle'])
d = int(d) // 1000
if self._time:
if d > 60 * self._time:
self.change_status()
elif self._profile.status == 1:
self.change_status(self._prev_status)

View File

@ -0,0 +1 @@
Required package: xprintidle (sudo apt-get install xprintidle)

View File

@ -0,0 +1 @@
{"time": 5}

View File

@ -1,7 +1,7 @@
import plugin_super_class
import threading
import time
from PySide import QtCore, QtGui
from PyQt5 import QtCore, QtWidgets
from ctypes import Structure, windll, c_uint, sizeof, byref
import json
@ -49,6 +49,7 @@ class AutoAwayStatusWindows(plugin_super_class.PluginSuperClass):
self._exec = None
self._active = False
self._time = json.loads(self.load_settings())['time']
self._prev_status = 0
def close(self):
self.stop()
@ -66,27 +67,29 @@ class AutoAwayStatusWindows(plugin_super_class.PluginSuperClass):
def save(self):
self.save_settings('{"time": ' + str(self._time) + '}')
def change_status(self):
invoke_in_main_thread(self._profile.set_status, 1)
def change_status(self, status=1):
if self._profile.status != 1:
self._prev_status = self._profile.status
invoke_in_main_thread(self._profile.set_status, status)
def get_window(self):
inst = self
class Window(QtGui.QWidget):
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(QtCore.QRect(450, 300, 350, 100))
self.label = QtGui.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(20, 0, 310, 35))
self.label.setText(QtGui.QApplication.translate("AutoAwayStatusWindows", "Auto away time in minutes\n(0 - to disable)", None, QtGui.QApplication.UnicodeUTF8))
self.time = QtGui.QLineEdit(self)
self.label.setText(QtWidgets.QApplication.translate("AutoAwayStatusWindows", "Auto away time in minutes\n(0 - to disable)"))
self.time = QtWidgets.QLineEdit(self)
self.time.setGeometry(QtCore.QRect(20, 40, 310, 25))
self.time.setText(str(inst._time))
self.setWindowTitle("AutoAwayStatusWindows")
self.ok = QtGui.QPushButton(self)
self.ok = QtWidgets.QPushButton(self)
self.ok.setGeometry(QtCore.QRect(20, 70, 310, 25))
self.ok.setText(
QtGui.QApplication.translate("AutoAwayStatusWindows", "Save", None, QtGui.QApplication.UnicodeUTF8))
QtWidgets.QApplication.translate("AutoAwayStatusWindows", "Save"))
self.ok.clicked.connect(self.update)
def update(self):
@ -103,7 +106,10 @@ class AutoAwayStatusWindows(plugin_super_class.PluginSuperClass):
def loop(self):
self._active = True
while self._exec:
time.sleep(30)
time.sleep(5)
d = get_idle_duration()
if self._time and d > 60 * self._time:
self.change_status()
if self._time:
if d > 60 * self._time:
self.change_status()
elif self._profile.status == 1:
self.change_status(self._prev_status)

75
AvatarEncryption/ae.py Normal file
View File

@ -0,0 +1,75 @@
import plugin_super_class
import json
import settings
import os
class AvatarEncryption(plugin_super_class.PluginSuperClass):
def __init__(self, *args):
super(AvatarEncryption, self).__init__('AvatarEncryption', 'ae', *args)
self._path = settings.ProfileHelper.get_path() + 'avatars/'
self._contacts = self._profile._contacts[:]
def close(self):
if not self._encrypt_save.has_password():
return
i, data = 1, {}
self.save_contact_avatar(data, self._profile, 0)
for friend in self._contacts:
self.save_contact_avatar(data, friend, i)
i += 1
self.save_settings(json.dumps(data))
def start(self):
if not self._encrypt_save.has_password():
return
data = json.loads(self.load_settings())
self.load_contact_avatar(data, self._profile)
for friend in self._contacts:
self.load_contact_avatar(data, friend)
self._profile.update()
def save_contact_avatar(self, data, contact, i):
tox_id = contact.tox_id[:64]
data[str(tox_id)] = str(i)
path = self._path + tox_id + '.png'
if os.path.isfile(path):
with open(path, 'rb') as fl:
avatar = fl.read()
encr_avatar = self._encrypt_save.pass_encrypt(avatar)
with open(self._path + self._settings.name + '_' + str(i) + '.png', 'wb') as fl:
fl.write(encr_avatar)
os.remove(path)
def load_contact_avatar(self, data, contact):
tox_id = str(contact.tox_id[:64])
if tox_id not in data:
return
path = self._path + self._settings.name + '_' + data[tox_id] + '.png'
if os.path.isfile(path):
with open(path, 'rb') as fl:
avatar = fl.read()
decr_avatar = self._encrypt_save.pass_decrypt(avatar)
with open(self._path + str(tox_id) + '.png', 'wb') as fl:
fl.write(decr_avatar)
os.remove(path)
contact.load_avatar()
def load_settings(self):
try:
with open(plugin_super_class.path_to_data(self._short_name) + self._settings.name + '.json', 'rb') as fl:
data = fl.read()
return str(self._encrypt_save.pass_decrypt(data), 'utf-8') if data else '{}'
except:
return '{}'
def save_settings(self, data):
try:
data = self._encrypt_save.pass_encrypt(bytes(data, 'utf-8'))
with open(plugin_super_class.path_to_data(self._short_name) + self._settings.name + '.json', 'wb') as fl:
fl.write(data)
except:
pass

View File

@ -0,0 +1,2 @@
Plugin for avatars encryption. Works with encrypted profiles only.
Note that it breaks compability with other clients.

View File

@ -1,5 +1,5 @@
import plugin_super_class
from PySide import QtGui, QtCore
from PyQt5 import QtWidgets, QtCore
import json
import importlib
@ -22,9 +22,8 @@ class BirthDay(plugin_super_class.PluginSuperClass):
if int(arr[0]) == now.day and int(arr[1]) == now.month:
today[key] = now.year - int(arr[2])
if len(today):
msgbox = QtGui.QMessageBox()
title = QtGui.QApplication.translate('BirthDay', "Birthday!", None,
QtGui.QApplication.UnicodeUTF8)
msgbox = QtWidgets.QMessageBox()
title = QtWidgets.QApplication.translate('BirthDay', "Birthday!")
msgbox.setWindowTitle(title)
text = ', '.join(self._profile.get_friend_by_number(self._tox.friend_by_public_key(x)).name + ' ({})'.format(today[x]) for x in today)
msgbox.setText('Birthdays: ' + text)
@ -34,23 +33,23 @@ class BirthDay(plugin_super_class.PluginSuperClass):
inst = self
x = self._profile.tox_id[:64]
class Window(QtGui.QWidget):
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(QtCore.QRect(450, 300, 350, 150))
self.send = QtGui.QCheckBox(self)
self.send = QtWidgets.QCheckBox(self)
self.send.setGeometry(QtCore.QRect(20, 10, 310, 25))
self.send.setText(QtGui.QApplication.translate('BirthDay', "Send my birthday date to contacts", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtGui.QApplication.translate('BirthDay', "Birthday", None, QtGui.QApplication.UnicodeUTF8))
self.send.setText(QtWidgets.QApplication.translate('BirthDay', "Send my birthday date to contacts"))
self.setWindowTitle(QtWidgets.QApplication.translate('BirthDay', "Birthday"))
self.send.clicked.connect(self.update)
self.send.setChecked(inst._data['send_date'])
self.date = QtGui.QLineEdit(self)
self.date = QtWidgets.QLineEdit(self)
self.date.setGeometry(QtCore.QRect(20, 50, 310, 25))
self.date.setPlaceholderText(QtGui.QApplication.translate('BirthDay', "Date in format dd.mm.yyyy", None, QtGui.QApplication.UnicodeUTF8))
self.set_date = QtGui.QPushButton(self)
self.date.setPlaceholderText(QtWidgets.QApplication.translate('BirthDay', "Date in format dd.mm.yyyy"))
self.set_date = QtWidgets.QPushButton(self)
self.set_date.setGeometry(QtCore.QRect(20, 90, 310, 25))
self.set_date.setText(QtGui.QApplication.translate('BirthDay', "Save date", None, QtGui.QApplication.UnicodeUTF8))
self.set_date.setText(QtWidgets.QApplication.translate('BirthDay', "Save date"))
self.set_date.clicked.connect(self.save_curr_date)
self.date.setText(inst._data[x] if x in inst._data else '')
@ -84,3 +83,4 @@ class BirthDay(plugin_super_class.PluginSuperClass):
timer.stop()
if self._profile.get_friend_by_number(friend_number).tox_id not in self._data:
self.send_lossless('', friend_number)

View File

@ -1,5 +1,5 @@
import plugin_super_class
from PySide import QtCore
from PyQt5 import QtCore
import time
@ -69,4 +69,3 @@ class Bot(plugin_super_class.PluginSuperClass):
message = self._message
invoke_in_main_thread(self._profile.send_message, message, friend_number)

1684
Chess/chess.py Normal file

File diff suppressed because it is too large Load Diff

BIN
Chess/chess/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:none; fill-rule:evenodd; fill-opacity:1; stroke:#000000; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<g style="fill:#000000; stroke:#000000; stroke-linecap:butt;">
<path
d="M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.646,38.99 6.677,38.97 6,38 C 7.354,36.06 9,36 9,36 z" />
<path
d="M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z" />
<path
d="M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z" />
</g>
<path
d="M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18"
style="fill:none; stroke:#ffffff; stroke-linejoin:miter;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="fill:none; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 22.5,11.63 L 22.5,6"
style="fill:none; stroke:#000000; stroke-linejoin:miter;"
id="path6570" />
<path
d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25"
style="fill:#000000;fill-opacity:1; stroke-linecap:butt; stroke-linejoin:miter;" />
<path
d="M 11.5,37 C 17,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 19,16 9.5,13 6.5,19.5 C 3.5,25.5 11.5,29.5 11.5,29.5 L 11.5,37 z "
style="fill:#000000; stroke:#000000;" />
<path
d="M 20,8 L 25,8"
style="fill:none; stroke:#000000; stroke-linejoin:miter;" />
<path
d="M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.51,26.6 L 22.5,24.5 C 20,18 9.906,14 6.997,19.85 C 4.5,25.5 11.85,28.85 11.85,28.85"
style="fill:none; stroke:#ffffff;" />
<path
d="M 11.5,30 C 17,27 27,27 32.5,30 M 11.5,33.5 C 17,30.5 27,30.5 32.5,33.5 M 11.5,37 C 17,34 27,34 32.5,37"
style="fill:none; stroke:#ffffff;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:none; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18"
style="fill:#000000; stroke:#000000;" />
<path
d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10"
style="fill:#000000; stroke:#000000;" />
<path
d="M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z"
style="fill:#ffffff; stroke:#ffffff;" />
<path
d="M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z"
transform="matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)"
style="fill:#ffffff; stroke:#ffffff;" />
<path
d="M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z "
style="fill:#ffffff; stroke:none;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<path
d="M 22,9 C 19.79,9 18,10.79 18,13 C 18,13.89 18.29,14.71 18.78,15.38 C 16.83,16.5 15.5,18.59 15.5,21 C 15.5,23.03 16.44,24.84 17.91,26.03 C 14.91,27.09 10.5,31.58 10.5,39.5 L 33.5,39.5 C 33.5,31.58 29.09,27.09 26.09,26.03 C 27.56,24.84 28.5,23.03 28.5,21 C 28.5,18.59 27.17,16.5 25.22,15.38 C 25.71,14.71 26,13.89 26,13 C 26,10.79 24.21,9 22,9 z "
style="opacity:1; fill:#000000; fill-opacity:1; fill-rule:nonzero; stroke:#000000; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:miter; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;" />
</svg>

After

Width:  |  Height:  |  Size: 816 B

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:000000; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<g style="fill:#000000; stroke:none;">
<circle cx="6" cy="12" r="2.75" />
<circle cx="14" cy="9" r="2.75" />
<circle cx="22.5" cy="8" r="2.75" />
<circle cx="31" cy="9" r="2.75" />
<circle cx="39" cy="12" r="2.75" />
</g>
<path
d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z"
style="stroke-linecap:butt; stroke:#000000;" />
<path
d="M 9,26 C 9,28 10.5,28 11.5,30 C 12.5,31.5 12.5,31 12,33.5 C 10.5,34.5 10.5,36 10.5,36 C 9,37.5 11,38.5 11,38.5 C 17.5,39.5 27.5,39.5 34,38.5 C 34,38.5 35.5,37.5 34,36 C 34,36 34.5,34.5 33,33.5 C 32.5,31 32.5,31.5 33.5,30 C 34.5,28 36,28 36,26 C 27.5,24.5 17.5,24.5 9,26 z"
style="stroke-linecap:butt;" />
<path
d="M 11,38.5 A 35,35 1 0 0 34,38.5"
style="fill:none; stroke:#000000; stroke-linecap:butt;" />
<path
d="M 11,29 A 35,35 1 0 1 34,29"
style="fill:none; stroke:#ffffff;" />
<path
d="M 12.5,31.5 L 32.5,31.5"
style="fill:none; stroke:#ffffff;" />
<path
d="M 11.5,34.5 A 35,35 1 0 0 33.5,34.5"
style="fill:none; stroke:#ffffff;" />
<path
d="M 10.5,37.5 A 35,35 1 0 0 34.5,37.5"
style="fill:none; stroke:#ffffff;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:000000; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z "
style="stroke-linecap:butt;" />
<path
d="M 12.5,32 L 14,29.5 L 31,29.5 L 32.5,32 L 12.5,32 z "
style="stroke-linecap:butt;" />
<path
d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z "
style="stroke-linecap:butt;" />
<path
d="M 14,29.5 L 14,16.5 L 31,16.5 L 31,29.5 L 14,29.5 z "
style="stroke-linecap:butt;stroke-linejoin:miter;" />
<path
d="M 14,16.5 L 11,14 L 34,14 L 31,16.5 L 14,16.5 z "
style="stroke-linecap:butt;" />
<path
d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 z "
style="stroke-linecap:butt;" />
<path
d="M 12,35.5 L 33,35.5 L 33,35.5"
style="fill:none; stroke:#ffffff; stroke-width:1; stroke-linejoin:miter;" />
<path
d="M 13,31.5 L 32,31.5"
style="fill:none; stroke:#ffffff; stroke-width:1; stroke-linejoin:miter;" />
<path
d="M 14,29.5 L 31,29.5"
style="fill:none; stroke:#ffffff; stroke-width:1; stroke-linejoin:miter;" />
<path
d="M 14,16.5 L 31,16.5"
style="fill:none; stroke:#ffffff; stroke-width:1; stroke-linejoin:miter;" />
<path
d="M 11,14 L 34,14"
style="fill:none; stroke:#ffffff; stroke-width:1; stroke-linejoin:miter;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:none; fill-rule:evenodd; fill-opacity:1; stroke:#000000; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<g style="fill:#ffffff; stroke:#000000; stroke-linecap:butt;">
<path
d="M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.646,38.99 6.677,38.97 6,38 C 7.354,36.06 9,36 9,36 z" />
<path
d="M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z" />
<path
d="M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z" />
</g>
<path
d="M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18"
style="fill:none; stroke:#000000; stroke-linejoin:miter;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="fill:none; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 22.5,11.63 L 22.5,6"
style="fill:none; stroke:#000000; stroke-linejoin:miter;" />
<path
d="M 20,8 L 25,8"
style="fill:none; stroke:#000000; stroke-linejoin:miter;" />
<path
d="M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25"
style="fill:#ffffff; stroke:#000000; stroke-linecap:butt; stroke-linejoin:miter;" />
<path
d="M 11.5,37 C 17,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 19,16 9.5,13 6.5,19.5 C 3.5,25.5 11.5,29.5 11.5,29.5 L 11.5,37 z "
style="fill:#ffffff; stroke:#000000;" />
<path
d="M 11.5,30 C 17,27 27,27 32.5,30"
style="fill:none; stroke:#000000;" />
<path
d="M 11.5,33.5 C 17,30.5 27,30.5 32.5,33.5"
style="fill:none; stroke:#000000;" />
<path
d="M 11.5,37 C 17,34 27,34 32.5,37"
style="fill:none; stroke:#000000;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:none; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18"
style="fill:#ffffff; stroke:#000000;" />
<path
d="M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10"
style="fill:#ffffff; stroke:#000000;" />
<path
d="M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z"
style="fill:#000000; stroke:#000000;" />
<path
d="M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z"
transform="matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)"
style="fill:#000000; stroke:#000000;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<path
d="M 22,9 C 19.79,9 18,10.79 18,13 C 18,13.89 18.29,14.71 18.78,15.38 C 16.83,16.5 15.5,18.59 15.5,21 C 15.5,23.03 16.44,24.84 17.91,26.03 C 14.91,27.09 10.5,31.58 10.5,39.5 L 33.5,39.5 C 33.5,31.58 29.09,27.09 26.09,26.03 C 27.56,24.84 28.5,23.03 28.5,21 C 28.5,18.59 27.17,16.5 25.22,15.38 C 25.71,14.71 26,13.89 26,13 C 26,10.79 24.21,9 22,9 z "
style="opacity:1; fill:#ffffff; fill-opacity:1; fill-rule:nonzero; stroke:#000000; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:miter; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;" />
</svg>

After

Width:  |  Height:  |  Size: 816 B

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:#ffffff; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 9 13 A 2 2 0 1 1 5,13 A 2 2 0 1 1 9 13 z"
transform="translate(-1,-1)" />
<path
d="M 9 13 A 2 2 0 1 1 5,13 A 2 2 0 1 1 9 13 z"
transform="translate(15.5,-5.5)" />
<path
d="M 9 13 A 2 2 0 1 1 5,13 A 2 2 0 1 1 9 13 z"
transform="translate(32,-1)" />
<path
d="M 9 13 A 2 2 0 1 1 5,13 A 2 2 0 1 1 9 13 z"
transform="translate(7,-4.5)" />
<path
d="M 9 13 A 2 2 0 1 1 5,13 A 2 2 0 1 1 9 13 z"
transform="translate(24,-4)" />
<path
d="M 9,26 C 17.5,24.5 30,24.5 36,26 L 38,14 L 31,25 L 31,11 L 25.5,24.5 L 22.5,9.5 L 19.5,24.5 L 14,10.5 L 14,25 L 7,14 L 9,26 z "
style="stroke-linecap:butt;" />
<path
d="M 9,26 C 9,28 10.5,28 11.5,30 C 12.5,31.5 12.5,31 12,33.5 C 10.5,34.5 10.5,36 10.5,36 C 9,37.5 11,38.5 11,38.5 C 17.5,39.5 27.5,39.5 34,38.5 C 34,38.5 35.5,37.5 34,36 C 34,36 34.5,34.5 33,33.5 C 32.5,31 32.5,31.5 33.5,30 C 34.5,28 36,28 36,26 C 27.5,24.5 17.5,24.5 9,26 z "
style="stroke-linecap:butt;" />
<path
d="M 11.5,30 C 15,29 30,29 33.5,30"
style="fill:none;" />
<path
d="M 12,33.5 C 18,32.5 27,32.5 33,33.5"
style="fill:none;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">
<g style="opacity:1; fill:#ffffff; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">
<path
d="M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z "
style="stroke-linecap:butt;" />
<path
d="M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z "
style="stroke-linecap:butt;" />
<path
d="M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14"
style="stroke-linecap:butt;" />
<path
d="M 34,14 L 31,17 L 14,17 L 11,14" />
<path
d="M 31,17 L 31,29.5 L 14,29.5 L 14,17"
style="stroke-linecap:butt; stroke-linejoin:miter;" />
<path
d="M 31,29.5 L 32.5,32 L 12.5,32 L 14,29.5" />
<path
d="M 11,14 L 34,14"
style="fill:none; stroke:#000000; stroke-linejoin:miter;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,5 +1,5 @@
import plugin_super_class
from PySide import QtGui, QtCore
from PyQt5 import QtCore, QtWidgets
import json
@ -15,25 +15,25 @@ class CopyableToxId(plugin_super_class.PluginSuperClass):
self.load_translator()
def get_description(self):
return QtGui.QApplication.translate("TOXID", 'Plugin which allows you to copy TOX ID of your friend easily.', None, QtGui.QApplication.UnicodeUTF8)
return QtWidgets.QApplication.translate("TOXID", 'Plugin which allows you to copy TOX ID of your friend easily.')
def get_window(self):
inst = self
class Window(QtGui.QWidget):
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(QtCore.QRect(450, 300, 350, 100))
self.send = QtGui.QCheckBox(self)
self.send = QtWidgets.QCheckBox(self)
self.send.setGeometry(QtCore.QRect(20, 10, 310, 25))
self.send.setText(QtGui.QApplication.translate("TOXID", "Send my TOX ID to contacts", None, QtGui.QApplication.UnicodeUTF8))
self.setWindowTitle(QtGui.QApplication.translate("TOXID", "CopyableToxID", None, QtGui.QApplication.UnicodeUTF8))
self.send.setText(QtWidgets.QApplication.translate("TOXID", "Send my TOX ID to contacts"))
self.setWindowTitle(QtWidgets.QApplication.translate("TOXID", "CopyableToxID"))
self.send.clicked.connect(self.update)
self.send.setChecked(inst._data['send_id'])
self.help = QtGui.QPushButton(self)
self.help = QtWidgets.QPushButton(self)
self.help.setGeometry(QtCore.QRect(20, 40, 200, 25))
self.help.setText(QtGui.QApplication.translate("TOXID", "List of commands", None, QtGui.QApplication.UnicodeUTF8))
self.help.setText(QtWidgets.QApplication.translate("TOXID", "List of commands"))
self.help.clicked.connect(lambda: inst.command('help'))
def update(self):
@ -49,17 +49,17 @@ class CopyableToxId(plugin_super_class.PluginSuperClass):
if self._copy:
self._timer.stop()
self._copy = False
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(data)
self.save_settings(json.dumps(self._data))
elif self._data['send_id']:
self.send_lossless(self._tox.self_get_address(), friend_number)
def error(self):
msgbox = QtGui.QMessageBox()
title = QtGui.QApplication.translate("TOXID", "Error", None, QtGui.QApplication.UnicodeUTF8)
msgbox = QtWidgets.QMessageBox()
title = QtWidgets.QApplication.translate("TOXID", "Error")
msgbox.setWindowTitle(title.format(self._name))
text = QtGui.QApplication.translate("TOXID", "Tox ID cannot be copied", None, QtGui.QApplication.UnicodeUTF8)
text = QtWidgets.QApplication.translate("TOXID", "Tox ID cannot be copied")
msgbox.setText(text)
msgbox.exec_()
@ -70,7 +70,7 @@ class CopyableToxId(plugin_super_class.PluginSuperClass):
self._curr = -1
arr = list(filter(lambda x: x.startswith(public_key), self._data['id']))
if len(arr):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(arr[0])
else:
self.error()
@ -97,15 +97,15 @@ class CopyableToxId(plugin_super_class.PluginSuperClass):
self._copy = False
return
elif text == 'help':
msgbox = QtGui.QMessageBox()
title = QtGui.QApplication.translate("TOXID", "List of commands for plugin CopyableToxID", None, QtGui.QApplication.UnicodeUTF8)
msgbox = QtWidgets.QMessageBox()
title = QtWidgets.QApplication.translate("TOXID", "List of commands for plugin CopyableToxID")
msgbox.setWindowTitle(title)
text = QtGui.QApplication.translate("TOXID", """Commands:
text = QtWidgets.QApplication.translate("TOXID", """Commands:
copy: copy TOX ID of current friend
copy <friend_number>: copy TOX ID of friend with specified number
enable: allow send your TOX ID to friends
disable: disallow send your TOX ID to friends
help: show this help""", None, QtGui.QApplication.UnicodeUTF8)
help: show this help""")
msgbox.setText(text)
msgbox.exec_()
return
@ -114,7 +114,7 @@ help: show this help""", None, QtGui.QApplication.UnicodeUTF8)
public_key = self._tox.friend_get_public_key(num)
arr = list(filter(lambda x: x.startswith(public_key), self._data['id']))
if self._profile.get_friend_by_number(num).status is None and len(arr):
clipboard = QtGui.QApplication.clipboard()
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(arr[0])
elif self._profile.get_friend_by_number(num).status is not None:
self._copy = True
@ -125,7 +125,7 @@ help: show this help""", None, QtGui.QApplication.UnicodeUTF8)
self.error()
def get_menu(self, menu, num):
act = QtGui.QAction(QtGui.QApplication.translate("TOXID", "Copy TOX ID", None, QtGui.QApplication.UnicodeUTF8), menu)
act = QtWidgets.QAction(QtWidgets.QApplication.translate("TOXID", "Copy TOX ID"), menu)
friend = self._profile.get_friend(num)
act.connect(act, QtCore.SIGNAL("triggered()"), lambda: self.command('copy ' + str(friend.number)))
return [act]

64
Garland/garland.py Normal file
View File

@ -0,0 +1,64 @@
import plugin_super_class
import threading
import time
from PyQt5 import QtCore
class InvokeEvent(QtCore.QEvent):
EVENT_TYPE = QtCore.QEvent.Type(QtCore.QEvent.registerEventType())
def __init__(self, fn, *args, **kwargs):
QtCore.QEvent.__init__(self, InvokeEvent.EVENT_TYPE)
self.fn = fn
self.args = args
self.kwargs = kwargs
class Invoker(QtCore.QObject):
def event(self, event):
event.fn(*event.args, **event.kwargs)
return True
_invoker = Invoker()
def invoke_in_main_thread(fn, *args, **kwargs):
QtCore.QCoreApplication.postEvent(_invoker, InvokeEvent(fn, *args, **kwargs))
class Garland(plugin_super_class.PluginSuperClass):
def __init__(self, *args):
super(Garland, self).__init__('Garland', 'grlnd', *args)
self._thread = None
self._exec = None
self._time = 3
def close(self):
self.stop()
def stop(self):
self._exec = False
self._thread.join()
def start(self):
self._exec = True
self._thread = threading.Thread(target=self.change_status)
self._thread.start()
def command(self, command):
if command.startswith('time'):
self._time = max(int(command.split(' ')[1]), 300) / 1000
else:
super().command(command)
def update(self):
self._profile.set_status((self._profile.status + 1) % 3)
def change_status(self):
time.sleep(5)
while self._exec:
invoke_in_main_thread(self.update)
time.sleep(self._time)

View File

@ -1,7 +1,7 @@
import plugin_super_class
import threading
import time
from PySide import QtCore
from PyQt5 import QtCore
class InvokeEvent(QtCore.QEvent):
@ -34,6 +34,7 @@ class MarqueeStatus(plugin_super_class.PluginSuperClass):
self._thread = None
self._exec = None
self.active = False
self.left = True
def close(self):
self.stop()
@ -48,9 +49,18 @@ class MarqueeStatus(plugin_super_class.PluginSuperClass):
self._thread = threading.Thread(target=self.change_status)
self._thread.start()
def command(self, command):
if command == 'rev':
self.left = not self.left
else:
super(MarqueeStatus, self).command(command)
def set_status_message(self):
message = self._profile.status_message
self._profile.set_status_message(bytes(message[1:] + message[0], 'utf-8'))
if self.left:
self._profile.set_status_message(bytes(message[1:] + message[0], 'utf-8'))
else:
self._profile.set_status_message(bytes(message[-1] + message[:-1], 'utf-8'))
def init_status(self):
self._profile.status_message = bytes(self._profile.status_message.strip() + ' ', 'utf-8')
@ -66,3 +76,4 @@ class MarqueeStatus(plugin_super_class.PluginSuperClass):
invoke_in_main_thread(self.set_status_message)
invoke_in_main_thread(self._profile.set_status_message, bytes(tmp, 'utf-8'))
self.active = False

View File

@ -1,15 +1,20 @@
# Plugins
Repo with plugins for [Toxygen](https://github.com/xveduk/toxygen/)
Repo with plugins for [Toxygen](https://github.com/toxygen-project/toxygen/)
For more info visit [plugins.md](https://github.com/xveduk/toxygen/blob/master/docs/plugins.md) and [plugin_api.md](https://github.com/xveduk/toxygen/blob/master/docs/plugin-api.md)
For more info visit [plugins.md](https://github.com/toxygen-project/toxygen/blob/master/docs/plugins.md) and [plugin_api.md](https://github.com/toxygen-project/toxygen/blob/master/docs/plugin-api.md)
# Plugins list:
- ToxId - share your Tox ID and copy friend's Tox ID easily.
- MarqueeStatus - create ticker from your status message.
- BirthDay - get notifications on your friends' birthdays
- Bot - bot which can communicate with your friends when you are away
- SearchPlugin - select text in message and find it in search engine
- BirthDay - get notifications on your friends' birthdays.
- Bot - bot which can communicate with your friends when you are away.
- SearchPlugin - select text in message and find it in search engine.
- AutoAwayStatusLinux - sets "Away" status when user is inactive (Linux only).
- AutoAwayStatusWindows - sets "Away" status when user is inactive (Windows only).
- Chess - play chess with your friends using Tox.
- Garland - changes your status like it's garland.
- AutoAnswer - calls auto answering.
- uToxInlineSending - send inlines with the same name as uTox does.
- AvatarEncryption - encrypt all avatars using profile password

View File

@ -1,5 +1,5 @@
import plugin_super_class
from PySide import QtGui, QtCore
from PyQt5 import QtGui, QtCore, QtWidgets
class SearchPlugin(plugin_super_class.PluginSuperClass):
@ -8,23 +8,23 @@ class SearchPlugin(plugin_super_class.PluginSuperClass):
super(SearchPlugin, self).__init__('SearchPlugin', 'srch', *args)
def get_message_menu(self, menu, text):
google = QtGui.QAction(
QtGui.QApplication.translate("srch", "Find in Google", None, QtGui.QApplication.UnicodeUTF8),
google = QtWidgets.QAction(
QtWidgets.QApplication.translate("srch", "Find in Google"),
menu)
google.triggered.connect(lambda: self.google(text))
duck = QtGui.QAction(
QtGui.QApplication.translate("srch", "Find in DuckDuckGo", None, QtGui.QApplication.UnicodeUTF8),
duck = QtWidgets.QAction(
QtWidgets.QApplication.translate("srch", "Find in DuckDuckGo"),
menu)
duck.triggered.connect(lambda: self.duck(text))
yandex = QtGui.QAction(
QtGui.QApplication.translate("srch", "Find in Yandex", None, QtGui.QApplication.UnicodeUTF8),
yandex = QtWidgets.QAction(
QtWidgets.QApplication.translate("srch", "Find in Yandex"),
menu)
yandex.triggered.connect(lambda: self.yandex(text))
bing = QtGui.QAction(
QtGui.QApplication.translate("srch", "Find in Bing", None, QtGui.QApplication.UnicodeUTF8),
bing = QtWidgets.QAction(
QtWidgets.QApplication.translate("srch", "Find in Bing"),
menu)
bing.triggered.connect(lambda: self.bing(text))
@ -32,16 +32,20 @@ class SearchPlugin(plugin_super_class.PluginSuperClass):
def google(self, text):
url = QtCore.QUrl('https://www.google.com/search?q=' + text)
QtGui.QDesktopServices.openUrl(url)
self.open_url(url)
def duck(self, text):
url = QtCore.QUrl('https://duckduckgo.com/?q=' + text)
QtGui.QDesktopServices.openUrl(url)
self.open_url(url)
def yandex(self, text):
url = QtCore.QUrl('https://yandex.com/search/?text=' + text)
QtGui.QDesktopServices.openUrl(url)
self.open_url(url)
def bing(self, text):
url = QtCore.QUrl('https://www.bing.com/search?q=' + text)
self.open_url(url)
def open_url(self, url):
QtGui.QDesktopServices.openUrl(url)

19
uToxInlineSending/uin.py Normal file
View File

@ -0,0 +1,19 @@
import plugin_super_class
class uToxInlineSending(plugin_super_class.PluginSuperClass):
def __init__(self, *args):
super(uToxInlineSending, self).__init__('uToxInlineSending', 'uin', *args)
self._tmp = None
def stop(self):
self._profile.send_screenshot = self._tmp
def start(self):
self._tmp = self._profile.send_screenshot
def func(data):
self._profile.send_inline(data, 'utox-inline.png')
self._profile.send_screenshot = func