StreamingSoundtracks.com
VIP
Subscribe to become a VIP member of SST!

· Request More Often
· Unshared Requests
· Request Countdown Timer
· Request Ready Indicator
· Your Request History
· Access To The VIP Forum
· Add More Favorites

:: Click Here To Upgrade ::

:: Give VIP as a Gift ::

Listen Live!

Donation Meter


Make donations with PayPal!
Monthly Goal:
$500.00

Need:
$162.58

5 Donations:
$337.42

Death.FM (Apr-9) shrike $20.00
StreamingSoundtracks.com (Apr-8) trailblder $25.00
Death.FM (Apr-2) SeclusionSolution $242.42
StreamingSoundtracks.com (Apr-2) Locutus76 $30.00
Death.FM (Apr-1) valar_morghulis $20.00

 


Last Month's Donors
Death.FM (Mar-29) htmm $13.37
StreamingSoundtracks.com (Mar-27) klingon50 $10.00
Death.FM (Mar-22) chapper $10.00
Death.FM (Mar-17) swissdeath $9.99
Death.FM (Mar-15) osiris $10.00
1980s.FM (Mar-11) Bondstec $15.00




Search

 

SSTore



:: SSTore ::



Ask SST.com for playlist and time remaining

 
Post new topic   Reply to topic    StreamingSoundtracks.com Forum Index -> General
View previous topic :: View next topic 
Author Message
USA tbttfox
Cadet 1
Cadet 1



Joined: Jul 28, 2008
Member#: 22030
Posts: 4
Location: Los Angeles

tbttfox is offline View user's profile Send private message tbttfox's Favorites are Private
PostPosted: Thu Feb 05, 2009 1:45 pm   Post subject: Ask SST.com for playlist and time remaining Reply with quote


I'm working on a Linux "widget" (python script) to display artist/song/time in my command line while playing the stream through mplayer.
Upon looking through the source for the live365 page, I found an xml file that posted the current song with time remaining. I set up my script to query that, and everything worked great ... UNTIL!
This file has now been whacked out for the past two days. It only displays that this station is playing the ID/PSA, and I miss being able to see the current song/time at a keystroke.
My question is:
Is there a way to ask SST directly for the current song and time remaining on the current song? Perhaps an xml file like live365?
Nate
Captain
Captain

aw

Joined: Dec 12, 2004
Member#: 8729
Posts: 1424
Location: Here and NOT There

Nate is offline View user's profile Send private message Send e-mail View Nate's Favorites
Yahoo Messenger MSN Messenger
PostPosted: Thu Feb 05, 2009 1:54 pm   Post subject: Reply with quote


I don't have the technical knowledge to offer up a specific solution, but hopefully this thread should help answer your question

http://www.streamingsoundtracks.com/modules.php?name=Forums&file=viewtopic&t=5018
_________________
"My Logic is Undeniable" - I, Robot
USA tbttfox
Cadet 1
Cadet 1



Joined: Jul 28, 2008
Member#: 22030
Posts: 4
Location: Los Angeles

tbttfox is offline View user's profile Send private message tbttfox's Favorites are Private
PostPosted: Thu Feb 05, 2009 2:07 pm   Post subject: Reply with quote


That is, in fact, EXACTLY what I was looking for.

Now to figure out how to use SOAP and the .wsdl
Yemen j2brown
Commodore
Commodore

aw

Joined: Feb 22, 2002
Member#: 9
Posts: 3188
Location: Sterling, VA

j2brown is offline View user's profile Send private message Send e-mail View j2brown's Favorites
AIM Address Yahoo Messenger MSN Messenger
PostPosted: Thu Feb 05, 2009 3:02 pm   Post subject: Reply with quote


Linux widget? I'd be very interested in playing with that. Let me know when you've got something you're willing to share. I'm OK with alpa release stuff, I won't think less of you if it doesn't work perfectly. Hit me up via PM/IM if you don't want to post here.

jeff
sdg
USA tbttfox
Cadet 1
Cadet 1



Joined: Jul 28, 2008
Member#: 22030
Posts: 4
Location: Los Angeles

tbttfox is offline View user's profile Send private message tbttfox's Favorites are Private
PostPosted: Tue Feb 10, 2009 7:42 pm   Post subject: Reply with quote


I just finished doing a major overhaul, and now all the functionality that I use is set in one large class.
Now it's not actually a real widget, but some of this could prove useful.

Some background info:
I'm using OpenSUSE Linux with KDE.
The program that's getting updated tabs is called Yakuake.
It's a terminal emulator that drops down from the top of the screen (much like in the game Quake)
I'm updating the tabs using DCOP (which I think is KDE only)
And I think that the only module you'd have to download is SOAPpy from HERE

[EDIT]: Removed code so there's not 40 versions of it clogging up the forum.

Last edited by tbttfox on Thu Feb 12, 2009 7:10 pm; edited 1 time in total
France Alchemist VIP (subscribed member)
Vice Admiral (Moderator)
Vice Admiral (Moderator)



Joined: Dec 30, 2003
Member#: 4272
Posts: 1621
Location: Annecy

Alchemist is offline View user's profile Send private message Visit poster's website View Alchemist's Favorites
PostPosted: Wed Feb 11, 2009 1:47 am   Post subject: Reply with quote


Thanks a lot for sharing this, tbttfox! Cool
_________________
"I've seen things you people wouldn't believe" - Blade Runner
Netherlands Dutchbat
Captain
Captain



Joined: Aug 09, 2008
Member#: 22196
Posts: 1875
Location: Roosendaal

Dutchbat is offline View user's profile Send private message View Dutchbat's Favorites
PostPosted: Wed Feb 11, 2009 3:59 am   Post subject: Reply with quote


Well I'm glad I don't have any knowledge in this area at all. But I like the way people can be into it real bad. As long as it for the benefit of SST-use I will give my sympathy but make sure that it should be available for nitwits like me under max. 1 keyclick. Wink
_________________

take a look at my collection: My album list
USA tbttfox
Cadet 1
Cadet 1



Joined: Jul 28, 2008
Member#: 22030
Posts: 4
Location: Los Angeles

tbttfox is offline View user's profile Send private message tbttfox's Favorites are Private
PostPosted: Wed Feb 11, 2009 1:04 pm   Post subject: Reply with quote


Dutchbat wrote:
... but make sure that it should be available for nitwits like me under max. 1 keyclick. Wink


If you don't know how to use it, you're going to have to wait till somebody else makes an easy to use version. I'm sure not going to make a pretty GUI for it. Sorry.
It's not written for anybody else but me, though I wrote it like I did so that it would be easily portable and extensible if anybody else with programming experience wanted to make something out of it, but that's just good practice.

Also, this is nowhere near completed. There's still a lot of stuff I want to add.

[EDIT 2] A link!!
http://www.mediafire.com/?sharekey=db4225d8d1ee491d24a64199ac7f73e5e04e75f6e8ebb871

[EDIT] Here's a new version of the code with a "mute" feature. The other day, there was a ... rather annoying song. Rather than guess when the song ended, I figured I could just shut the music off for a single song and turn it back on when it was done.

Code:

#!/usr/bin/python
import threading,os,time,commands,re,urllib
from SOAPpy import WSDL
from math import ceil

class sstQue:
    """
This is a Class for reading and parsing information from StreamingSoundtracks.com

Included Methods:
updateQue => reads the queue directly from sst.com.  This function specifically doesn't use the API so it can query the entire queue.
queStep => removes the first song off the que.  Useful so you don't have to continually check sst.com. Call after a current song update.
quePrint => displays & returns the Nth item in the queue. It will automatically update the que if not all entries are present (from queStep)
updateCurrentSong => updates the current song information.
printCurrentSong => displays and returns the current song information
decTime => decrement the currentSong's time remaining
unescape => internal function to remove HTML escape sequences
addTimes => internal function to sum two times in min:sec format.  Used to calculate time until for quePrint
timeStruct => internal function to parse the sst API's timecodes

Included data:
que => the upcoming songs. Stored in this 2d array format:  que[number][number,time,album,song,requestedBy,message]
remSec => the seconds remaining in the current song
remMin => the minutes remaining in the current song
curSongLength => the length of the current song
curSongRemain => the time remaining in the current song
curSong => the Title of the current song
curAlbum => the Album of the current song
curArtist => the Artist of the current song
listenCount => the number of current listeners
curRequestedBy => the member who requested the current song
coverLink => link to the album art
siteLink => link to sst.com album
"""
    def __init__(self):
        self.que = []
        self.server = WSDL.Proxy('http://www.streamingsoundtracks.com/soap/FM24seven.wsdl')
        self.curSong = ''
    def updateQue(self):
        url = 'http://www.streamingsoundtracks.com/modules/Queue_Played/Queue_Played.php'
        f = urllib.urlopen(url)
        s = f.read()
        f.close()
        #get everything in first <table> tag, and remove all special characters
        partsplit = s[s.find("<table"):s.find("</table")].replace("\r\n","").replace("\t","")
        partsplit = partsplit.split("<tr>")
        self.que = []
        for part in partsplit:
            #split at tags
            testing = re.split(r'<[a-zA-Z\/][^>]*>',part)
            info = [self.unescape(a).strip() for a in testing if a != '']
            self.que.append(info)
        self.que = self.que[3:]
        checkCur = self.unescape(self.curSong)
        first = self.que[0][3]
        if checkCur == first:
            self.que = self.que[1:]

    def queStep(self):
        if len(self.que) > 1:
            self.que = self.que[1:]
        elif len(self.que) == 1:
            self.que = []
           
    def quePrint(self,n):
        length = len(self.que)
        if n > length:
            self.updateQue()
            length = len(self.que)
            if n > length:
                print "Index out of Range"
                return
        #add all time values together
        if n > 1:
            times = [time[1] for time in self.que[:n-1]]
            timeTill = reduce(lambda x,y:self.addTimes(x,y),times)
            timeSplit = timeTill.split(":")
            if int(timeSplit[0])>= 60:
                min = int(timeSplit[0]) % 60
                hour = (int(timeSplit[0]) - min) / 60
                timeTill = str(hour) + ":" + str(min).rjust(2,"0") + ":" + timeSplit[1]
        else:
            timeTill = "Next"       
        song = self.que[n-1]
        #[number,time,album,song,requestedBy,message]
        print "\nQueue: " + str(n) + "\nTime Till: " + timeTill + "\nAlbum: " + song[2] + "\nSong: " + song[3] + "\nRequested By:" + song[4] + "\nMessage: " + song[5] + "\n"
        return (str(n), timeTill, song[2], song[3], song[4], song[5])

    def updateCurrentSong(self):
        tempCurSong = self.server.GetCurrentlyPlaying(False)
        tempCurTitle = self.unescape(tempCurSong['Track'])
        if tempCurTitle == self.curSong:
            return -1
        songStart = self.timeStruct(tempCurSong['PlayStart'])
        serverTime = self.timeStruct(tempCurSong['SystemTime'])
        songLength = ceil(tempCurSong['Length'] / 1000)
        rawTime = songLength - (time.mktime(serverTime) - time.mktime(songStart))
        self.remSec = int(rawTime % 60)
        self.remMin = int((rawTime - self.remSec) / 60)
        self.curSongLength = songLength
        self.curSongRemain = str(self.remMin) + ":" + str(self.remSec).rjust(2,"0")
        self.curSong = tempCurTitle
        self.curAlbum = self.unescape(tempCurSong['Album'])
        self.curArtist = self.unescape(tempCurSong['Artist'])
        self.listenCount = tempCurSong['ListenerCount']
        self.curRequestedBy = tempCurSong['RequestedBy']
        self.coverLink = tempCurSong['CoverLink']
        self.siteLink = tempCurSong['SiteLink']
        return 0

    def printCurrentSong(self):   
        print "\nAlbum: " + self.curAlbum + "\nArtist: " + self.curArtist + "\nSong: " + self.curSong + "\n"
        return (self.curAlbum, self.curArtist, self.curSong, self.curRequestedBy)

    def decTime(self):
        self.remSec = self.remSec - 1
        if self.remSec < 0:
            self.remMin = self.remMin - 1
            self.remSec = 59
       
    def unescape(self,s):
        s = s.replace("&lt;", "<")
        s = s.replace("&gt;", ">")
        s = s.replace("&quot;", "\\\"")
        s = s.replace("&nbsp;", " ")
        s = s.replace("&ntilde;", "n")
        s = s.replace("&amp;", "&")
        return s

    def addTimes(self,a,b):
        a = a.split(":")
        b = b.split(":")
        c = [int(a[0]) + int(b[0]),int(a[1]) + int(b[1])]
        if c[1] >= 60:
            c[1] = c[1] - 60
            c[0] = c[0] + 1
        sec = str(c[1])   
        return str(c[0]) + ":" + sec.rjust(2,"0")

    def timeStruct(self,a):
        b = str(a[0]) + ' ' + str(a[1]) + ' ' + str(a[2]) + ' ' + str(a[3]) + ' ' + str(a[4]) + ' ' + str(int(a[5]))
        return time.strptime(b,'%Y %m %d %H %M %S')
       
#This function updates the tab name within Yakuake to include album, artist, and timeRemaining.
def yakuakeUpdate():
    cmd = gdcopi + "slotRenameSession " + str(gSes) +  " \""
    songAlbum = gQue.curSong + "--" + gQue.curAlbum + " "
    songAlbum = songAlbum[:60]
    cmd = cmd + songAlbum + "--" + str(gQue.remMin) + ":" + str(gQue.remSec).rjust(2,"0") + "\""
    os.system(cmd)
       
#This is a thread that starts my command line media player
class playSST(threading.Thread):
    def run(self):
        os.system('mplayer -msglevel all=-1 -quiet http://PATH/TO/YOUR/STREAM.ogg > /dev/null')

#This is a thread that takes care of telling the sstQue class to update correctly
class updateTab(threading.Thread):
    def run(self):
        self.dirtySong = True
        self.mute = True
        dirtyTime = True
        while True:
            if self.dirtySong:
                print "================================="
                self.dirtySong = False
                if gQue.updateCurrentSong() == -1 and self.mute == False:
                    #if there was no update, wait 1 second and retry
                    self.dirtySong = True
                    time.sleep(1)
                    continue
                gQue.printCurrentSong()
                gQue.queStep()
                if self.mute == True:
                    self.mute = False
                    psst = playSST()
                    psst.setDaemon(True)
                    psst.start()
            if dirtyTime:
                dirtyTime = False
                myTime = time.localtime()
                gQue.decTime()
                yakuakeUpdate()
                if gQue.remMin <=0 and gQue.remSec <=0:
                    self.dirtySong = True
            #use internal clock to do time calculations       
            timecheck = time.localtime()
            if timecheck != myTime:
                dirtyTime = True
            #fifth second tick for checking
            time.sleep(0.2)   

def main():
    #find the Yakuake tab where I'll print the updated information
    sessionList = commands.getoutput(gdcopi + "sessionIdList").split(",")
    for session in sessionList:
        name = commands.getoutput(gdcopi + "slotSessionName " + session)
        if name == 'mplayer':
            global gSes
            gSes = int(session)
    #start the threads. Daemon threads exit when the main program exits
    ut = updateTab()
    ut.setDaemon(True)
    ut.start()
    #check for user input
    while True:
        input = raw_input("Command? \n")
        if input == 'q':
            break
        elif input == 'r':   
            ut.dirtySong = True
        elif input == 'm':
            os.system('killall mplayer')
            ut.mute = True
        elif input == 'f':
            os.system('killall mplayer')
            ut.mute = True
            ut.dirtySong = True
        elif len(input) > 0:   
            if input[0] == 'n':
                if len(input) == 1:
                    gQue.quePrint(1)
                else:   
                    number = input[1:]
                    if number.isdigit():
                        gQue.quePrint(int(number))
    #once everything ends kill mplayer and remove the info from the Yakuake tab.   
    os.system("killall mplayer")
    cmd = gdcopi + "slotRenameSession " + str(gSes) + " \"mplayer\""
    os.system(cmd)

#set global variables
gSes = -1
gdcopi = "dcop yakuake DCOPInterface "
gQue = sstQue()

main()

Display posts from previous:
Post new topic   Reply to topic    StreamingSoundtracks.com Forum Index -> General All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum



Forums ©


Copyright © 2001-2020 24seven.FM, LLC All rights reserved.
Comments, images, and trademarks are property of their respective owners.
You can syndicate our news using the file backend.php or ultramode.txt. Robots may follow the Sitemap.