PyQt5 QtMultimedia - python-3.4

So I'm trying to create a GUI that searches a dictionary for a word, returns the entries and suggestions and downloads the audio, returning "related words" (sometimes more than one) that have audio. Then, the user clicks on one of three buttons to play the audio, based on the dialect. I can get the words to play, but I can't get the last played one to close so I can download another.
Here is the relevant code:
#staticmethod
def munster():
""" This method plays the Munster recording, if it exists"""
url = QtCore.QUrl.fromLocalFile("./CanM.mp3")
content = QtMultimedia.QMediaContent(url)
player = QtMultimedia.QMediaPlayer()
player.setMedia(content)
player.play()
player.stateChanged(app.quit)
When it gets to the last line it gives me this error:
TypeError: native Qt signal is not callable
Is there any way to close the player to allow downloading of another audio file with the same name?
For the record, I'm using the latest release of PyQt5, and Qt5.4 on Python 3.4 with Windows 81. However, I'm also working on this project (with the same Qt and PyQt) on an Archlinux system as well, and would like it to be portable easily.
Edit: Quite easy, once I started looking at what all was contained within the Player class. Just needed to use the disconnect method.
Edit2: Edited to show complete working code
#staticmethod
def play_audio(dialect):
file_names = {'Munster': './CanM.mp3', 'Connacht': './CanC.mp3', 'Ulster': './CanU.mp3'}
url = QtCore.QUrl.fromLocalFile(os.path.abspath(file_names[dialect]))
content = QtMultimedia.QMediaContent(url)
player = QtMultimedia.QMediaPlayer()
player.setMedia(content)
player.play()
player.stateChanged.connect(lambda: player.disconnect())

Related

extracting song info from EXTINF from live radio stream

Is it possible to extract the song info from a live HLS M3U8 radio stream using for example python or any other program?
I can currently view the song info by opening the response in Google DevTools, but I'd like to automatically scrape/extract the song title and save it to a file each time the song changes.
You should try using the Python library (https://github.com/globocom/m3u8) to parse and manipulate m3u8 manifests instead of writing your own script. You have to check if it supports the tags you are trying to get metadata for. If not you should be able to easily extend the library to add the functionality you need.
import m3u8
def get_movie(line, data, lineno):
if line.startswith('#MOVIE-NAME:'):
custom_tag = line.split(':')
data['movie'] = custom_tag[1].strip()
m3u8_obj = m3u8.load('http://videoserver.com/playlist.m3u8',
custom_tags_parser=get_movie)
print(m3u8_obj.data['movie']) # million dollar baby

Can't figure how phone number reveal works

I am pretty new to web-scraping and recently I am trying to automatically scrap phone number for pages like this. I am not supposed to use Selenium/headless url browser libraries and I am trying to find the a way to actually request the phone number using let say a web service or any other possible solution that could give me the phone number hopefully directly without having to go through the actual button press by selenium.
I totally understand that it may not even be possible to automatically reveal the phone number in one shut as it is meant not be accessible by nosy newbie web-scraper like me; but I still like to raise the question for my information to get detailed answer from an expert point of view.
If I search the "Reveal" button DOM element, it shows some tags which I have never seen before. I have two main questions which I believe could be helpful for newbies like me.
1) Given a set of unknown tags/attribues (ie. data-q and data-reveal in the blow button), how is one able to find out which scripts in the page are actually using them?
2) I googled the button element's tag like: data-q and data-reveal the only relevant I could find was this which for some reason I don't have access two even-if I use proxy.
Any clue particularly on the first question is much appreciate it.
Regards,
Below is the href-button code
Reveal
Ok, according to your demand there are several steps before you finally get a solution.
1st step : open your own browser and enter your target page(https://www.gumtree.com/p/vans/2015-ford-transit-custom-2.2tdci-290-l1-h1/1190345514)
2nd step : (Assume you are using Chrome as your favorite browser) Press Ctrl+Shift+I to open the console, and then select 'Network' tag in the console.
3rd step : Press the 'Reveal' button on that page, watch the console carefully, catch the http request which is sent immediately when you press the 'Reveal' button. You can see the request contains a long string of number in Query String Parameters, actually it is a timestamp.
4th step : Also you can see there is a part named 'Request Headers' in that http request, and you should copy the values of referer , user-agent , x-gumtree-token.
5th step : Try to construct your request (I am a fan of Python, So I am going to show you my example code in Python)
import time
import requests
import json
headers = {
'referer': 'please enter the value you just copied from that specific request',
'user-agent': 'please enter the value you just copied from that specific request',
'x-gumtree-token': 'please enter the value you just copied from that specific request'
}
url = 'https://www.gumtree.com/ajax/account/seller/reveal/number/1190345514?_='
current_time = time.time()
current_time = str(current_time)
current_time = current_time.split('.')[0] + current_time.split('.')[1] + '0'
url += current_time
response = requests.get(url=url,headers=headers)
response_result = json.loads(response.content)
phone_number = response_result['data']

Client doesn't have a name/class at startup

I'm trying to start an application (Spotify) on a particular tag. Rules aren't applied and now I'm inspecting the client class by printing the class in a notification in the "manage" signal. This results in an empty notification.
client.connect_signal("manage", function (c, startup)
naughty.notify({title=c.class})
end)
When I restart awesome, it does print the client class, so why isn't it working when the client is initially started?
Using xprop, it also prints the class:
WM_CLASS(STRING) = "spotify", "Spotify"
Sounds like a bug in Spotify (and I think I heard about this one before). I would guess that Spotify does not follow ICCCM and only sets its WM_CLASS property after it made its window visible and not before.
I fear that you cannot do much about this except for complaining to Spotify devs to fix their stuff.
You could work around this by starting a timer in the manage signal that checks if a window turns out to be spotify a short time later. Alternatively, you could do something like client.connect_signal("property::class", function(c) if c.class == "Spotify" then print("This is now a spotify window") end end) to react to change to a window's class (of course you'd want to do something more useful to Spotify's windows than printing them).
(Per the ICCCM, a window is not allowed to change its class while it is visible, but who cares about standards...)
I had a similar issue with the claws-mail client. Inspecting it via xprop, it shows
WM_CLASS(STRING) = "claws-mail", "Claws-mail"
but awesome just did’t apply the rules for it. The trick was giving awesome-wm both of these class names in the rules section by providing a set of characters to chose from:
rule = {class = "[Cc]laws%-mail"}
I hope this works for your spotify application, too.
For further reading about patterns in lua I suggest this:
https://www.lua.org/pil/20.2.html

Asterisk: Record application is generating empty files

User making the call is asked to dial an extension. This is done by 1#playing a prompt with Background and then 2#wait_for_digit. Based on the extension that has been dialed, the destination number is determined and the call is forwarded to that number.
If the called person doesn't not answer, then Playback is used to play a prompt that asks the user to record the voice message; recording the voice message is done with the Record application.
This Record application is always generating empty wav files, size 44 bytes. If I remove the 1#playing a prompt with Background the Record application is generating proper files. If the Background is included, all recordings are empty.
I am using Perl Asterisk::AGI module.
$agi->exec('Answer');
....
.....
$agi->exec('Background', 'en/extra/please-enter-the-extension,n'); # this is the troubling part
my $my_extension = $agi->wait_for_digit(5000);
....
.....
$agi->exec('Playback', 'en/extra/the-party-you-are-calling&en/extra/is-curntly-busy,noanswer');
$agi->exec('Playback', 'en/vm-intro,noanswer');
my $file = 'xyz.wav';
$agi->exec('Record', "$file,0,10,k");
...
...
What should I do to make it work as I want it to?
Thank you.
UPDATE 1:
The same script is working without glitches now. Not sure if something unrelated to the script has changed.
Most likly you have check your codecs. IF you use g729 or g723 and no transcoder,it just can't write in wav format.

Qt or PyQt - check when file is used by another process. Wait until finish copy

Good morning,
What is the best strategy for check when a big file o big directory has finished to copy?
I want wait until a file has finish fully to copy. Is there a code example in q
I'm working on mac os x.
thanks
Update
I use QFileSystemWatcher. the problem is that I receive file or directory change notification when o copy it is in progress. So user copy a big folder (inside many files), the operating system copy process start, it take 5 minuts, but in same times my application receive file changed notification. This is a problem because when i receive a change notification my application start for doing some operations on that files, but the copy is already in progress!!!!
There is only one reliable way to do this: Change the copy process to write to temporary files and then rename them after the copy is finished.
That way, you can ignore new files which end with .tmp and rename is an atomic operation.
If you can't change the copy process, all you can do is add a timer to wait for, say, half an hour to make sure the copy is really finished.
A more fine grained (and more risky) approach is to add a loop that check the file size and stops when the file size doesn't change for a certain time but that's also hard to get right.
Worse, this doesn't prevent you from reading partial files (when the copy process was terminated in the middle).
I think that the QFileSystemWatcher is the right start for you to get to the point of monitoring for changes, but as you have found, these changes are ANY changes. From this point, I think it should be easy enough for you to just check the modification time of the file.
Here is a simple example of a Watcher class that will let you specify a file to monitor and see if it has been modified after a given time. It can run a callback or emit a signal that anyone can watch:
import os.path
import time
from PyQt4 import QtCore
class Watcher(QtCore.QObject):
fileNotModified = QtCore.pyqtSignal(str)
MOD_TIME_DIFF = 5 #seconds
def __init__(self, aFile, callback=None, checkEvery=5):
super(Watcher, self).__init__()
self.file = aFile
self.callback = callback
self._timer = QtCore.QTimer(self)
self._timer.setInterval(checkEvery*1000)
self._timer.timeout.connect(self._checkFile)
def _checkFile(self):
diff = time.time() - os.path.getmtime(self.file)
if diff > self.MOD_TIME_DIFF:
self._timer.stop()
self.fileNotModified.emit(self.file)
if self.callback:
self.callback()
def start(self):
self._timer.start()
def stop(self):
self._timer.stop()
An example of using it:
def callbackNotify():
print "Callback!"
def signalNotify(f):
print "Signal: %s was modified!" % f
# You could directly give it a callback
watcher = Watcher("/path/to/file.file", callback=callbackNotify)
# Or could use a signal
watcher.fileNotModified.connect(signalNotify)
# tell the watcher timer to start checking
watcher.start()
## after the file hasnt been modified in 5 seconds ##
# Signal: /path/to/file.file was modified!
# Callback!
Try using QtConcurrent framework.
In particular, check out QFuture and QFutureWatcher. You can execute asynchronous copy operations inside a QFuture object and monitor its progress through signals and slots with a watcher.
bool copyFunction() {
// copy operations here, return true on success
}
MyHandlerClass myObject;
QFutureWatcher<bool> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));
QFuture<bool> future = QtConcurrent::run(copyFunction);
Since you have no control on the external application, my suggestion is that you lock the files while you work on them. In this way other programs will not be able to access them while locked.
Alternatively, if you have access to the other program's source, you should implement some form of inter process communication,via sockets, messages or whatever method you prefer.

Resources