Dears,
I am new on python and trying to start python networking with a simple code that have 2 plain text line edits and try to start 2 telnet sessions and get output of each session on a separate plain text line area however i get the below error
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
the code as below:
app = QApplication(sys.argv)
def to_str(bytes_or_str):
if isinstance(bytes_or_str, bytes):
value = bytes_or_str.decode() # uses 'utf-8' for encoding
else:
value = bytes_or_str
return value # Instance of str
def testTelnet_start(): # called when button pressed
_thread.start_new_thread(testTelnet,("192.168.3.247",1))
print("Test")
_thread.start_new_thread(testTelnet,("192.168.3.252",2))
def testTelnet(ip,x):
try:
tel_conn = telnetlib.Telnet()
tel_conn.open(host= ip)
data = tel_conn.read_until(b"login:",3)
data = to_str(data)
data = ip + "\n" + data
print(data)
if(x==1):
plain_text_area_Upgrade1.appendPlainText(data)
elif(x==2):
plain_text_area_Upgrade2.appendPlainText(data)
except Exception as e:
print(e)
my_Test_Window = QWidget()
my_Test_Window.setWindowTitle("Telnet Window")
my_Test_Window.resize(490,350)
my_Test_Window.setFixedSize(my_Test_Window.size())
push_test1 = QPushButton("Test#1",my_Test_Window)
push_test1.move(90,280)
plain_text_area_Upgrade1 = QPlainTextEdit(my_Test_Window)
plain_text_area_Upgrade1.resize(160,150)
plain_text_area_Upgrade1.updatesEnabled()
plain_text_area_Upgrade1.move(25,20)
plain_text_area_Upgrade1.setReadOnly(True)
plain_text_area_Upgrade1.insertPlainText("Testing ...")
plain_text_area_Upgrade1.appendPlainText("")
plain_text_area_Upgrade2 = QPlainTextEdit(my_Test_Window)
plain_text_area_Upgrade2.resize(160,150)
plain_text_area_Upgrade2.updatesEnabled()
plain_text_area_Upgrade2.move(250,20)
plain_text_area_Upgrade2.setReadOnly(True)
plain_text_area_Upgrade2.insertPlainText("Testing ...")
plain_text_area_Upgrade2.appendPlainText("")
push_test1.clicked.connect(testTelnet_start)
my_Test_Window.show()
app.exec_()
Any idea why a simple multi threading code cause those errors ?
Thanks.
Related
Today i am working on a project about incoming phone calls being transcripted and getting saved into text files, but i am also kinda new to python and python loops.
I want to loop over a SQL server column and let each row loop trough the azure Speech to text service i use (all of the phonecall OID's). I have been stuck on this problem for a couple days now so i thought i might find some help here.
import azure.cognitiveservices.speech as speechsdk
import time
from os import path
from pydub import AudioSegment
import requests
import hashlib
import sys
import os.path
import pyodbc
databaseName = '*'
username = '*'
password = '*'
server = '*'
driver = '*'
try:
CONNECTION_STRING = 'DRIVER='+driver+';SERVER='+server+';DATABASE='+databaseName+';UID='+username+';PWD='+ password
conn = pyodbc.connect(CONNECTION_STRING)
cursor = conn.cursor()
storedproc = "* = *'"
cursor.execute(storedproc)
row = cursor.fetchone()
while row:
array = [(int(row[1]))]
row = cursor.fetchone()
i = 0
while i<len(array):
OID = (array[i])
i = i + 1
print(OID)
string = f"{OID}*"
encoded = string.encode()
result = hashlib.sha256(encoded)
resultHash = (result.hexdigest())
Telefoongesprek = requests.get(f"*{OID}", headers={f"api-key":f"{resultHash}"})
with open("Telefoongesprek.mp3", "wb") as f:
f.write(Telefoongesprek.content)
src = "Telefoongesprek.mp3"
dst = "Telefoongesprek.wav"
sound = AudioSegment.from_file(src)
sound.export(dst, format="wav")
def speech_recognize_continuous_from_file():
speech_config = speechsdk.SpeechConfig(subscription="*", region="*")
speech_config.speech_recognition_language = "nl-NL"
audio_config = speechsdk.audio.AudioConfig(filename="Telefoongesprek.wav")
speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)
done = False
def stop_cb(evt):
print('CLOSING on {}'.format(evt))
nonlocal done
done = True
all_results = []
def handle_final_result(evt):
all_results.append(evt.result.text)
speech_recognizer.recognized.connect(handle_final_result)
speech_recognizer.session_started.connect(handle_final_result)
speech_recognizer.session_stopped.connect(handle_final_result)
speech_recognizer.canceled.connect(handle_final_result)
speech_recognizer.session_stopped.connect(stop_cb)
speech_recognizer.canceled.connect(stop_cb)
speech_recognizer.start_continuous_recognition()
while not done:
time.sleep(.5)
speech_recognizer.stop_continuous_recognition()
print(all_results)
telefoongesprek = str(all_results)
filename = f"C:\\Users\\Beau\\Contact-verkeer\\contact-verkeer\\telefoon\\STT Transcriptions\\Telefoongesprek#{OID}.txt"
file = open(filename, "w")
file.write(telefoongesprek)
file.close()
speech_recognize_continuous_from_file()
cursor.close()
del cursor
conn.close()
except Exception as e:
print("Error: %s" % e)
everything works apart form each other but i just dont know how to place the loop and witch one i should use (For/While loop). right here im trying to loop over an array but i dont this this is correct.
Error message: Decoding failed. ffmpeg returned error code: 1
[mp3 # 000001cb8c57e0o0] Failed to read frame size: could not seek to 1073.
which i am pretty sure means that my azure function can't find an mp3 file, what means that the "Mp3 to Wav" convert doesn't work.
Thanks in advance!
If I understand your question, you have a database with lots of phone call details. One of the field value in each row is used to create the associated mp3 file. You want to do speech to text using azure on each of the mp3 file you have in your database.
So you can do it in two ways:
Iterate though all rows in the database and create all the associted files into a folder in the local disk with the OID as your filename.
Then write another loop to iterate through this folder and send the files for transcription to Azure Speech to Text service.
The other technique is to do everything in a single loop like the way you have shown which will require some corrections.
Ok, so now that part is clear, we can go into the speech to text part. So azure allow you to send the compressed format for transcription, which means you actually don't need to convert it into wav file.
Please have a look at the modified code below with the changes:
# code snippet borrowed from azure samples
def speech_recognize_continuous_from_file(filename):
class BinaryFileReaderCallback(speechsdk.audio.PullAudioInputStreamCallback):
def __init__(self, filename: str):
super().__init__()
self._file_h = open(filename, "rb")
def read(self, buffer: memoryview) -> int:
try:
size = buffer.nbytes
frames = self._file_h.read(size)
buffer[:len(frames)] = frames
return len(frames)
except Exception as ex:
print('Exception in `read`: {}'.format(ex))
raise
def close(self) -> None:
print('closing file')
try:
self._file_h.close()
except Exception as ex:
print('Exception in `close`: {}'.format(ex))
raise
# Creates an audio stream format. For an example we are using MP3 compressed file here
compressed_format = speechsdk.audio.AudioStreamFormat(compressed_stream_format=speechsdk.AudioStreamContainerFormat.MP3)
callback = BinaryFileReaderCallback(filename=filename)
stream = speechsdk.audio.PullAudioInputStream(stream_format=compressed_format, pull_stream_callback=callback)
speech_config = speechsdk.SpeechConfig(subscription="*", region="*")
speech_config.speech_recognition_language = "nl-NL"
audio_config = speechsdk.audio.AudioConfig(stream=stream)
# Creates a speech recognizer using a file as audio input, also specify the speech language
speech_recognizer = speechsdk.SpeechRecognizer(speech_config, audio_config)
done = False
def stop_cb(evt):
print('CLOSING on {}'.format(evt))
nonlocal done
done = True
all_results = []
def handle_final_result(evt):
all_results.append(evt.result.text)
speech_recognizer.recognized.connect(handle_final_result)
speech_recognizer.session_started.connect(handle_final_result)
speech_recognizer.session_stopped.connect(handle_final_result)
speech_recognizer.canceled.connect(handle_final_result)
speech_recognizer.session_stopped.connect(stop_cb)
speech_recognizer.canceled.connect(stop_cb)
speech_recognizer.start_continuous_recognition()
while not done:
time.sleep(.5)
speech_recognizer.stop_continuous_recognition()
print(all_results)
telefoongesprek = str(all_results)
filename = f"C:\\Users\\Beau\\Contact-verkeer\\contact-verkeer\\telefoon\\STT Transcriptions\\Telefoongesprek#{OID}.txt"
file = open(filename, "w")
file.write(telefoongesprek)
file.close()
try:
CONNECTION_STRING = 'DRIVER='+driver+';SERVER='+server+';DATABASE='+databaseName+';UID='+username+';PWD='+ password
conn = pyodbc.connect(CONNECTION_STRING)
cursor = conn.cursor()
storedproc = "* = *'"
cursor.execute(storedproc)
row = cursor.fetchone()
# loop through the rows
while row:
array = [(int(row[1]))]
i = 0
while i<len(array):
OID = (array[i])
i = i + 1
print(OID)
string = f"{OID}*"
encoded = string.encode()
result = hashlib.sha256(encoded)
resultHash = (result.hexdigest())
telefoongesprek_response = requests.get(f"*{OID}", headers={f"api-key":f"{resultHash}"})
# save the file to local disk as mp3
with open("Telefoongesprek.mp3", "wb") as f:
f.write(telefoongesprek_response.content)
# do the speech to text on the mp3 file
speech_recognize_continuous_from_file(f.name)
# fetch the next row
row = cursor.fetchone()
cursor.close()
del cursor
conn.close()
except Exception as e:
print("Error: %s" % e)
I haven't tested this full code as i don't have the db connections with me. Please fell free to modify for your use case and let me know if you have any issues.
I have a class for multiprocessing in Python which creates 3 different processes. First process is for checking if there is any signal from my hardware and pushing it into a Queue, second process is for getting the data out of the Queue and pushing it into a database and the third processes is for getting the data out of the database and pushing it on a server.
obj = QE()
stdFunct = standardFunctions()
watchDogProcess = multiprocessing.Process(target=obj.watchDog)
watchDogProcess.start()
pushToDBSProcess = multiprocessing.Process(target=obj.pushToDBS)
pushToDBSProcess.start()
pushToCloud = multiprocessing.Process(target=stdFunct.uploadCycleTime)
pushToCloud.start()
watchDogProcess.join()
pushToDBSProcess.join()
pushToCloud.join()
My first two processes are running perfectly as desired, however I am struggling with the third process. The following is the code of my third process :
def uploadCycleTime(self):
while True:
uploadCycles = []
lastUpPointer = "SELECT id FROM lastUploaded"
lastUpPointer = self.dbFetchone(lastUpPointer)
lastUpPointer = lastUpPointer[0]
# print("lastUploaded :"+str(lastUpPointer))
cyclesToUploadSQL = "SELECT id,machineId,startDateTime,endDateTime,type FROM cycletimes WHERE id > "+str(lastUpPointer)
cyclesToUpload = self.dbfetchMany(cyclesToUploadSQL,15)
cyclesUploadLength = len(cyclesToUpload)
if(cyclesUploadLength>0):
for cycles in cyclesToUpload:
uploadCycles.append({"dataId":cycles[0],"machineId":cycles[1],"startDateTime":cycles[2].strftime('%Y-%m-%d %H:%M:%S.%f'),"endDateTime":cycles[3].strftime('%Y-%m-%d %H:%M:%S.%f'),"type":cycles[4]})
# print("length : "+str(cyclesUploadLength))
lastUpPointer = uploadCycles[cyclesUploadLength-1]["dataId"]
uploadCycles = json.dumps(uploadCycles)
api = self.dalUrl+"/cycle-times"
uploadResponse = self.callPostAPI(api,str(uploadCycles))
print(lastUpPointer)
changePointerSQL = "UPDATE lastUploaded SET id="+str(lastUpPointer)
try:
changePointerSQL = self.dbAbstraction(changePointerSQL)
except Exception as errorPointer:
print("Pointer change Error : "+str(errorPointer))
time.sleep(2)
Now I am saving a pointer to remember the last id uploaded, and from there on keep uploading 15 packets. When there is data existing in the DB the code works well, however if there is no existing when the process is initiated and data is sent afterwards then it fails to fetch the data from the DB.
I tried printing the length in realtime, it keeps giving me 0, inspite of data being continuously pushed into the DB in real-time.
In my upload process, I missed out on a commit()
def dbFetchAll(self,dataString):
# dataToPush = self.cycletimeQueue.get()
# print(dataToPush)
dbTry = 1
try:
while(dbTry == 1): # This while is to ensure the data has been pushed
sql = dataString
self.conn.execute(sql)
response = self.conn.fetchall()
dbTry = 0
return response
# print(self.conn.rowcount, "record inserted.")
except Exception as error:
print ("Error : "+str(error))
return dbTry
***finally:
self.mydb.commit()***
I would need some of your expertise concerning GUI and more precisely PyQt4.
Context
I am currently designing a GUI with PyQt. It was previously done with wxPython, but I was kind of force to migrate to Qt due to internal issue.
At some point, I needed to display traditional RTF content, ie including hidden tags such as {\rtf1\ansi\ansicpg1252\deff0\deflang1036\deflangfe1036{\fonttbl{\f0\fswiss\fprq2\fcharset0 Calibri;}{\f1\froman\fprq2\fcharset2 Symbol;}}, \tx360 or \par and so on.
If I'm not mistaking, QTextEdit from PyQt can't "interpret" this RTF and will just display the whole string. But neither did wxPython and I had found a workaround provided by the wxPython community, which was to copy the string to windows clipboard and then paste it in the wanted text widget.
Thus, I had this piece of code:
class rtfClip():
def __init__(self):
self.CF_RTF = win32clipboard.RegisterClipboardFormat("Rich Text Format")
# Puts 'toPaste' on the clipboard
def setClipboard(self,toPaste):
cbOpened = False
# Wait for board availability, then do operations
while not cbOpened:
try:
win32clipboard.OpenClipboard(0)
cbOpened = True
win32clipboard.EmptyClipboard() # need to empty, or prev data will stay
win32clipboard.SetClipboardData(self.CF_RTF, toPaste)
win32clipboard.CloseClipboard()
except Exception, err:
# If access is denied, that means that the clipboard is in use.
# Keep trying until it's available.
if err[0] == 5: #Access Denied
pass
#print 'waiting on clipboard...'
# wait on clipboard because something else has it. we're waiting a
# random amount of time before we try again so we don't collide again
time.sleep( random.random()/50 )
elif err[0] == 1418: #doesn't have board open
pass
elif err[0] == 0: #open failure
pass
else:
print 'ERROR in Clipboard section of readcomments: %s' % err
pass
# Save the user's existing clipboard data, if possible. It is unable to save
# copied files, image data, etc; text, HTML, RTF, etc are preserved just fine
def saveClipboard(self):
cbOpened = False
while not cbOpened:
try:
win32clipboard.OpenClipboard(0)
cbOpened = True
self.cbSaved = {}
rval = win32clipboard.EnumClipboardFormats( 0 )
while rval != 0:
#print "Retrieving CB format %d" % rval
dat = win32clipboard.GetClipboardData( rval )
if rval == 15: #CF_HDROP
#this'll error, so just give up
self.cbSaved = {}
win32clipboard.EmptyClipboard()
break
else:
self.cbSaved[ rval ] = win32clipboard.GetClipboardData( rval )
rval = win32clipboard.EnumClipboardFormats( rval )
win32clipboard.CloseClipboard()
except Exception, err:
if err[0] == 5: #Access Denied
#print 'waiting on clipboard...'
time.sleep( random.random()/50 )
pass
elif err[0]== 6:
#print 'clipboard type error, aborting...'
win32clipboard.CloseClipboard()
break
elif err[0] == 1418: #doesn't have board open
cbOpened = False
elif err[0] == 0: #open failure
cbOpened = False
else:
print 'Error while saving clipboard: %s' % err
pass
# Restore the user's clipboard, if possible
def restoreClipboard(self):
cbOpened = False
# don't wait for the CB if we don't have to
if len(self.cbSaved) > 0:
#open clipboard
while not cbOpened:
try:
win32clipboard.OpenClipboard(0)
win32clipboard.EmptyClipboard()
cbOpened = True
except Exception, err:
if err[0] == 5: #Access Denied
#print 'waiting on clipboard...'
time.sleep( random.random()/50 )
pass
elif err[0] == 1418: #doesn't have board open
cbOpened = False
elif err[0] == 0: #open failure
cbOpened = False
else:
print 'Error with clipboard restoration: %s' % err
pass
#replace items
try:
for item in self.cbSaved:
data = self.cbSaved.get(item)
# windows appends NULL to most clipboard items, so strip off the NULL
if data[-1] == '\0':
data = data[:-1]
win32clipboard.SetClipboardData( item, data )
except Exception, err:
#print 'ERR: %s' % err
win32clipboard.EmptyClipboard()
try:
win32clipboard.CloseClipboard()
except:
pass
And then I just had to paste my RTF string in the associated widget:
rtf = copy_to_clipboard.rtfClip()
rtf.saveClipboard() # Save the current user's clipboard
rtf.setClipboard(my_rtf_string_full_of_rtf_tags) # Put our RTF on the clipboard
preview_dlg = preview_rtf_text(None)
preview_dlg.preview_rtf_ctrl.SetEditable(True)
preview_dlg.preview_rtf_ctrl.Paste() # Paste in into the textbox
rtf.restoreClipboard() # Restore the user's clipboard
preview_dlg.ShowModal()
preview_dlg.Destroy()
(preview_rtf_text being a class with only a TextCtrl named preview_rtf_ctrl)
Problem
My problem is that for any reason I can't manage to get this solution working with PyQt.
I have attempted designing a very similar solution with
rtf = copy_to_clipboard.rtfClip()
rtf.saveClipboard() # Save the current user's clipboard
rtf.setClipboard(rtf_content) # Put our RTF on the clipboard
#
rtf_preview_dlg = AEM_RTF_preview(self)
rtf_preview_dlg.rtf_preview_ctl.setReadOnly(False)
rtf_preview_dlg.rtf_preview_ctl.setAcceptRichText(True)
cursor = QtGui.QTextCursor(rtf_preview_dlg.rtf_preview_ctl.document())
cursor.setPosition(0)
rtf_preview_dlg.rtf_preview_ctl.setTextCursor(cursor)
rtf_preview_dlg.rtf_preview_ctl.paste()
rtf.restoreClipboard() # Restore the user's clipboard
rtf_preview_dlg.rtf_preview_ctl.setReadOnly(True)
rtf_preview_dlg.exec_()
But for any reason this won't work: nothing is pasted to the QTextEdit (rtf_preview_ctl).
I saw on some topics that PyQt had its own clipboard, but how would I make him "take" the content from the windows one? Is it even a solution?
Sorry for the very long question, I hope some of you may have an idea, since it would be an important feature of the GUI.
EDIT : There might be other solution for my need, my dream would just be to display formatted microsoft RTF content, one way or another.
I found a very old command line utility, unrtf. It outputs to STDOUT, so we need to process the output from there. It's been made for linux, but Windows binaries are available, even if the version I found is a bit older than the latest provided for Linux.
It requires to write a temporary file and might have some small issues with rtf conversion, but for simple cases seems to work fine enough.
In this case I automatically detect if there's some rtf content in the clipboard (so you can test it with along with your current program), but you can also paste raw rtf contents there to test it: you actually don't need the clipboard at all to make it work.
As far as I can understand it also supports tables and images, which are exported in external files (so you might have to test its behavior and possibly edit the html before actually applying it to the QTextEdit).
rtfTypes = set(['text/rtf', 'text/richtext', 'application/x-qt-windows-mime;value="Rich Text Format"'])
class PasteWidget(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
l = QtWidgets.QGridLayout()
self.setLayout(l)
self.input = QtWidgets.QTextEdit()
l.addWidget(self.input)
self.input.setAcceptRichText(False)
self.pasteBtn = QtWidgets.QPushButton('Paste')
l.addWidget(self.pasteBtn)
self.pasteBtn.clicked.connect(self.paste)
self.convertBtn = QtWidgets.QPushButton('Convert')
l.addWidget(self.convertBtn)
self.convertBtn.clicked.connect(self.convert)
self.output = QtWidgets.QTextEdit()
l.addWidget(self.output)
self.output.setReadOnly(True)
self.clipboard = QtWidgets.QApplication.clipboard()
self.clipboard.changed.connect(self.checkClipboard)
self.checkClipboard()
def checkClipboard(self, mode=QtGui.QClipboard.Clipboard):
if mode != QtGui.QClipboard.Clipboard:
return
self.pasteBtn.setEnabled(bool(set(self.clipboard.mimeData().formats()) & rtfTypes))
def paste(self):
mime = self.clipboard.mimeData()
for format in mime.formats():
if format in rtfTypes:
self.input.setPlainText(str(mime.data(format)))
def convert(self):
rtf = self.input.toPlainText()
if not rtf:
return
tempPath = QtCore.QDir.tempPath()
with open(os.path.join(tempPath, '_sourceRtf'), 'wb') as _input:
_input.write(rtf)
unrtf = QtCore.QProcess()
unrtf.readyReadStandardOutput.connect(lambda: self.output.setHtml(str(unrtf.readAllStandardOutput())))
unrtf.start('unrtf.exe', ['--html', os.path.join(tempPath, '_sourceRtf')])
Obviously the unrtf.exe has to be in the system path (or the path of the main script).
I'm trying to handle events from multiple usb keyboards, so that the code knows from which keyboard an input is coming from. The code identify the different keyboards via the device instance id (they all have the same product and vendor id) but not from which an user input is coming from (it just toggles between them).
Is this even possible with pywinusb? I tried playing with the event handlers with no luck.
from time import sleep
from msvcrt import kbhit
import pywinusb.hid as hid
# feel free to test
target_vendor_id = 0xffff
target_product_id = 0x0035
def sample_handler(data):
print("Raw data: {0}".format(data))
def getinput(data, id):
print data
print id
if(id == "8&2754010&0&0000" and data == "09008708"):
print "Success"
else:
print "Failed"
def raw_test():
# example, handle the HidDeviceFilter().get_devices() result grouping items by parent ID
all_hids = hid.HidDeviceFilter(vendor_id = target_vendor_id, product_id = target_product_id).get_devices()
#print all_hids
if all_hids:
while True:
for index, device in enumerate(all_hids):
result = device.instance_id.split('\\')[-1]
try:
device.open()
getinput(raw_input(), result)
finally:
device.close()
if __name__ == '__main__':
# first be kind with local encodings
import sys
if sys.version_info >= (3,):
# as is, don't handle unicodes
unicode = str
raw_input = input
else:
# allow to show encoded strings
import codecs
sys.stdout = codecs.getwriter('mbcs')(sys.stdout)
raw_test()
I'm getting error when I try setting status to empathy with dbus using python,
this is the code I've got from different sources
## getting status from clementine music player
import dbus
# Clementine lives on the Session bus
session_bus = dbus.SessionBus()
# Get Clementine's player object, and then get an interface from that object,
# otherwise we'd have to type out the full interface name on every method call.
player = session_bus.get_object('org.mpris.clementine', '/Player')
iface = dbus.Interface(player, dbus_interface='org.freedesktop.MediaPlayer')
# Call a method on the interface
metadata = iface.GetMetadata()
print metadata["title"]+' - '+metadata["artist"]
status = metadata["title"]+' - '+metadata["artist"]
## the below code is from https://github.com/engla/kupfer/blob/master/kupfer/plugin/empathy.py
import os
import subprocess
import sys
import time
import pynotify as pn
# it takes a long time before empathy is willing to accept statuses
EMPATHY_STARTUP_SECONDS = 20
def show_usage():
print "\nUsage:"
print sys.argv[0], "|".join(_STATUSES.keys())
def set_status(status):
try:
activate(status)
notify_set_status(status)
except IndexError:
print "Missing required parameter."
show_usage()
except ValueError as err:
print err
show_usage()
def notify_set_status(status):
success = pn.init("icon-summary-body")
if not success:
raise Error()
# I like this icon, even if it's not relevant
icon = 'notification-keyboard-brightness-low'
pn.Notification("Empathy", "Tried to set status to "+ status, icon).show()
def main():# give empathy some time to start up
set_status(status)
def _(text):
return text
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# All code below was derived from https://github.com/engla/kupfer/blob/master/kupfer/plugin/empathy.py
ACCOUNTMANAGER_PATH = "/org/freedesktop/Telepathy/AccountManager"
ACCOUNTMANAGER_IFACE = "org.freedesktop.Telepathy.AccountManager"
ACCOUNT_IFACE = "org.freedesktop.Telepathy.Account"
CHANNEL_GROUP_IFACE = "org.freedesktop.Telepathy.Channel.Interface.Group"
CONTACT_IFACE = "org.freedesktop.Telepathy.Connection.Interface.Contacts"
SIMPLE_PRESENCE_IFACE = "org.freedesktop.Telepathy.Connection.Interface.SimplePresence"
DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties"
CHANNELDISPATCHER_IFACE = "org.freedesktop.Telepathy.ChannelDispatcher"
CHANNELDISPATCHER_PATH = "/org/freedesktop/Telepathy/ChannelDispatcher"
CHANNEL_TYPE = "org.freedesktop.Telepathy.Channel.ChannelType"
CHANNEL_TYPE_TEXT = "org.freedesktop.Telepathy.Channel.Type.Text"
CHANNEL_TARGETHANDLE = "org.freedesktop.Telepathy.Channel.TargetHandle"
CHANNEL_TARGETHANDLETYPE = "org.freedesktop.Telepathy.Channel.TargetHandleType"
EMPATHY_CLIENT_IFACE = "org.freedesktop.Telepathy.Client.Empathy"
EMPATHY_ACCOUNT_KEY = "EMPATHY_ACCOUNT"
EMPATHY_CONTACT_ID = "EMPATHY_CONTACT_ID"
_ATTRIBUTES = {
'alias': 'org.freedesktop.Telepathy.Connection.Interface.Aliasing/alias',
'presence': 'org.freedesktop.Telepathy.Connection.Interface.SimplePresence/presence',
'contact_caps': 'org.freedesktop.Telepathy.Connection.Interface.ContactCapabilities.DRAFT/caps',
'jid': 'org.freedesktop.Telepathy.Connection/contact-id',
'caps': 'org.freedesktop.Telepathy.Connection.Interface.Capabilities/caps',
}
def _create_dbus_connection():
sbus = dbus.SessionBus()
proxy_obj = sbus.get_object(ACCOUNTMANAGER_IFACE, ACCOUNTMANAGER_PATH)
dbus_iface = dbus.Interface(proxy_obj, DBUS_PROPS_IFACE)
return dbus_iface
def activate(status):
bus = dbus.SessionBus()
interface = _create_dbus_connection()
for valid_account in interface.Get(ACCOUNTMANAGER_IFACE, "ValidAccounts"):
account = bus.get_object(ACCOUNTMANAGER_IFACE, valid_account)
connection_status = account.Get(ACCOUNT_IFACE, "ConnectionStatus")
if connection_status != 0:
continue
connection_path = account.Get(ACCOUNT_IFACE, "Connection")
connection_iface = connection_path.replace("/", ".")[1:]
connection = bus.get_object(connection_iface, connection_path)
simple_presence = dbus.Interface(connection, SIMPLE_PRESENCE_IFACE)
try:
simple_presence.SetPresence(status, _(status))
except dbus.exceptions.DBusException:
print(status + ' is not supported by ' + valid_account)
print simple_presence
main()
when I run this script,
I get the following error.
phanindra#phanindra:~$ python clementine.py
onelove - Blue
(clementine.py:6142): Gtk-WARNING **: Unable to locate theme engine in module_path: "pixmap",
onelove - Blue is not supported by /org/freedesktop/Telepathy/Account/gabble/jabber/abcd_40gmail_2ecom0
I did something wrong? or the functions are deprecated?
Try this to update the status of Empathy with the current track playing in Clementine:
import dbus
session_bus = dbus.SessionBus()
player = session_bus.get_object('org.mpris.clementine', '/Player')
iface = dbus.Interface(player, dbus_interface='org.freedesktop.MediaPlayer')
metadata = iface.GetMetadata()
status = "♫ ".decode('utf8')+metadata["title"]+' - '+metadata["album"]+" ♫".decode('utf8')
print status
from gi.repository import TelepathyGLib as Tp
from gi.repository import GObject
loop = GObject.MainLoop()
am = Tp.AccountManager.dup()
am.prepare_async(None, lambda *args: loop.quit(), None)
loop.run()
am.set_all_requested_presences(Tp.ConnectionPresenceType.AVAILABLE,
'available', status)
Thank you for updating the Format in my original post !
- Harsha
Here is the API specification for the SimplePresence API's SetPresence call: http://telepathy.freedesktop.org/spec/Connection_Interface_Simple_Presence.html#Method:SetPresence
I think the problem is that you're trying to set the presence to an invalid status - you are only allow to set the status to one which the connection manager recognises - e.g. Available. You can set whatever you like for the message.
So your code should read something like:
simple_presence.SetPresence("Available", status)