Code cleanup
This commit is contained in:
parent
5b6fb1c22a
commit
21807f4f99
213
nrsc5-dui.py
213
nrsc5-dui.py
|
@ -20,7 +20,6 @@
|
||||||
# Updated by zefie for modern nrsc5 ~ 2019
|
# Updated by zefie for modern nrsc5 ~ 2019
|
||||||
# Updated and enhanced by markjfine ~ 2021
|
# Updated and enhanced by markjfine ~ 2021
|
||||||
|
|
||||||
#import os, sys, shutil, re, gtk, gobject, json, datetime, numpy, glob, time, platform
|
|
||||||
import os, pty, select, sys, shutil, re, json, datetime, numpy, glob, time, platform, io
|
import os, pty, select, sys, shutil, re, json, datetime, numpy, glob, time, platform, io
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from threading import Timer, Thread
|
from threading import Timer, Thread
|
||||||
|
@ -53,9 +52,7 @@ cfgDir = os.path.join(runtimeDir, "cfg") # config file directory
|
||||||
class NRSC5_DUI(object):
|
class NRSC5_DUI(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
global runtimeDir, resDir
|
global runtimeDir, resDir
|
||||||
#gobject.threads_init()
|
self.windowsOS = False # save our determination as a var in case we change how we determine.
|
||||||
#Gdk.threads_init()
|
|
||||||
self.windowsOS = False # save our determination as a var in case we change how we determine.
|
|
||||||
|
|
||||||
self.getControls() # get controls and windows
|
self.getControls() # get controls and windows
|
||||||
self.initStreamInfo() # initilize stream info and clear status widgets
|
self.initStreamInfo() # initilize stream info and clear status widgets
|
||||||
|
@ -87,8 +84,8 @@ class NRSC5_DUI(object):
|
||||||
self.mapFile = os.path.join(resDir, "map.png")
|
self.mapFile = os.path.join(resDir, "map.png")
|
||||||
self.defaultSize = [490,250] # default width,height of main app
|
self.defaultSize = [490,250] # default width,height of main app
|
||||||
self.nrsc5 = None # nrsc5 process
|
self.nrsc5 = None # nrsc5 process
|
||||||
self.nrsc5master = None
|
self.nrsc5master = None # required for pipe
|
||||||
self.nrsc5slave = None
|
self.nrsc5slave = None # required for pipe
|
||||||
self.playerThread = None # player thread
|
self.playerThread = None # player thread
|
||||||
self.playing = False # currently playing
|
self.playing = False # currently playing
|
||||||
self.statusTimer = None # status update timer
|
self.statusTimer = None # status update timer
|
||||||
|
@ -97,16 +94,15 @@ class NRSC5_DUI(object):
|
||||||
self.nrsc5Args = [] # arguments for nrsc5
|
self.nrsc5Args = [] # arguments for nrsc5
|
||||||
self.logFile = None # nrsc5 log file
|
self.logFile = None # nrsc5 log file
|
||||||
self.lastImage = "" # last image file displayed
|
self.lastImage = "" # last image file displayed
|
||||||
self.coverImage = ""
|
self.coverImage = "" # cover image to display
|
||||||
self.id3Changed = False
|
self.id3Changed = False # if the track info changed
|
||||||
#self.lastXHDR = ["", -1] # the last XHDR data received
|
|
||||||
self.lastXHDR = "" # the last XHDR data received
|
self.lastXHDR = "" # the last XHDR data received
|
||||||
self.lastLOT = "" # the last LOT received with XHDR
|
self.lastLOT = "" # the last LOT received with XHDR
|
||||||
self.stationStr = "" # current station frequency (string)
|
self.stationStr = "" # current station frequency (string)
|
||||||
self.streamNum = 0 # current station stream number
|
self.streamNum = 0 # current station stream number
|
||||||
self.nrsc5msg = "" # send key command to nrsc5 (streamNum)
|
self.nrsc5msg = "" # send key command to nrsc5 (streamNum)
|
||||||
self.update_btns = True
|
self.update_btns = True # whether to update the stream buttons
|
||||||
self.set_program_btns()
|
self.set_program_btns() # whether to set the stream buttons
|
||||||
self.bookmarks = [] # station bookmarks
|
self.bookmarks = [] # station bookmarks
|
||||||
self.booknames = ["","","",""] # station bookmark names
|
self.booknames = ["","","",""] # station bookmark names
|
||||||
self.stationLogos = {} # station logos
|
self.stationLogos = {} # station logos
|
||||||
|
@ -204,7 +200,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
self.pointer_cursor = Gdk.Cursor(Gdk.CursorType.LEFT_PTR)
|
self.pointer_cursor = Gdk.Cursor(Gdk.CursorType.LEFT_PTR)
|
||||||
self.hand_cursor = Gdk.Cursor(Gdk.CursorType.HAND2)
|
self.hand_cursor = Gdk.Cursor(Gdk.CursorType.HAND2)
|
||||||
#self.missing_image = Gtk.Image.new_from_icon_name("MISSING_IMAGE",Gtk.IconSize.LARGE_TOOLBAR)
|
|
||||||
|
|
||||||
# set events on info labels
|
# set events on info labels
|
||||||
self.set_tuning_actions(self.btnAudioPrgs0, "btn_prg0", False, False)
|
self.set_tuning_actions(self.btnAudioPrgs0, "btn_prg0", False, False)
|
||||||
|
@ -240,21 +235,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
# regex for getting nrsc5 output
|
# regex for getting nrsc5 output
|
||||||
self.regex = [
|
self.regex = [
|
||||||
#re.compile("^.*main\.c:[\d]+: Station name: (.*)$"), # 0 match station name
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Station location: (-?[\d]+\.[\d]+) (-?[\d]+\.[\d]+), ([\d]+)m$"), # 1 match station location
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Slogan: (.*)$"), # 2 match station slogan
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Audio bit rate: (.*) kbps$"), # 3 match audio bit rate
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Title: (.*)$"), # 4 match title
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Artist: (.*)$"), # 5 match artist
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Album: (.*)$"), # 6 match album
|
|
||||||
#re.compile("^.*main\.c:[\d]+: LOT file: port=([\d]+) lot=([\d]+) name=(.*\.(?:jpg|png|txt)) size=([\d]+) mime=([\w]+)$"), # 7 match file (album art, maps, weather info)
|
|
||||||
#re.compile("^.*main\.c:[\d]+: MER: (-?[\d]+\.[\d]+) dB \(lower\), (-?[\d]+\.[\d]+) dB \(upper\)$"), # 8 match MER
|
|
||||||
#re.compile("^.*main\.c:[\d]+: BER: (0\.[\d]+), avg: (0\.[\d]+), min: (0\.[\d]+), max: (0\.[\d]+)$"), # 9 match BER
|
|
||||||
#re.compile("^.*nrsc5\.c:[\d]+: Best gain: (.*) dB,.*$"), # 10 match gain
|
|
||||||
#re.compile("^.*main\.c:[\d]+: SIG Service: type=(.*) number=(.*) name=(.*)$"), # 11 match stream
|
|
||||||
#re.compile("^.*main\.c:[\d]+: .*Data component:.* port=([\d]+).* type=([\d]+) .*$"), # 12 match port
|
|
||||||
#re.compile("^.*main\.c:[\d]+: XHDR: .* ([0-9A-Fa-f]{8}) (.*)$"), # 13 match xhdr tag
|
|
||||||
#re.compile("^.*main\.c:[\d]+: Unique file identifier: PPC;07; ([\S]+).*$") # 14 match unique file id
|
|
||||||
re.compile("^[0-9\:]{8,8} Station name: (.*)$"), # 0 match station name
|
re.compile("^[0-9\:]{8,8} Station name: (.*)$"), # 0 match station name
|
||||||
re.compile("^[0-9\:]{8,8} Station location: (-?[\d]+\.[\d]+) (-?[\d]+\.[\d]+), ([\d]+)m$"), # 1 match station location
|
re.compile("^[0-9\:]{8,8} Station location: (-?[\d]+\.[\d]+) (-?[\d]+\.[\d]+), ([\d]+)m$"), # 1 match station location
|
||||||
re.compile("^[0-9\:]{8,8} Slogan: (.*)$"), # 2 match station slogan
|
re.compile("^[0-9\:]{8,8} Slogan: (.*)$"), # 2 match station slogan
|
||||||
|
@ -282,7 +262,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
self.loadSettings()
|
self.loadSettings()
|
||||||
self.proccessWeatherMaps()
|
self.proccessWeatherMaps()
|
||||||
#self..connect('check-resize',self.on_window_resized) # TODO: fix on resize infinite loop
|
|
||||||
|
|
||||||
# set up pty
|
# set up pty
|
||||||
self.nrsc5master,self.nrsc5slave = pty.openpty()
|
self.nrsc5master,self.nrsc5slave = pty.openpty()
|
||||||
|
@ -317,10 +296,6 @@ class NRSC5_DUI(object):
|
||||||
def on_cover_resize(self, container):
|
def on_cover_resize(self, container):
|
||||||
global mapDir
|
global mapDir
|
||||||
if self.coverImage != "":
|
if self.coverImage != "":
|
||||||
#img_size = min(self.alignmentCover.get_allocated_height(), self.alignmentCover.get_allocated_width()) - 12
|
|
||||||
#pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.coverImage)
|
|
||||||
#pixbuf = pixbuf.scale_simple(img_size, img_size, GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
#self.imgCover.set_from_pixbuf(pixbuf)
|
|
||||||
self.showArtwork(self.coverImage)
|
self.showArtwork(self.coverImage)
|
||||||
|
|
||||||
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
||||||
|
@ -330,14 +305,12 @@ class NRSC5_DUI(object):
|
||||||
map_img = Image.open(map_file).resize((img_size, img_size), Image.LANCZOS)
|
map_img = Image.open(map_file).resize((img_size, img_size), Image.LANCZOS)
|
||||||
self.imgMap.set_from_pixbuf(self.img_to_pixbuf(map_img))
|
self.imgMap.set_from_pixbuf(self.img_to_pixbuf(map_img))
|
||||||
else:
|
else:
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR)
|
|
||||||
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
||||||
elif (self.mapData["mapMode"] == 1):
|
elif (self.mapData["mapMode"] == 1):
|
||||||
if os.path.isfile(self.mapData["weatherNow"]):
|
if os.path.isfile(self.mapData["weatherNow"]):
|
||||||
map_img = Image.open(self.mapData["weatherNow"]).resize((img_size, img_size), Image.LANCZOS)
|
map_img = Image.open(self.mapData["weatherNow"]).resize((img_size, img_size), Image.LANCZOS)
|
||||||
self.imgMap.set_from_pixbuf(self.img_to_pixbuf(map_img))
|
self.imgMap.set_from_pixbuf(self.img_to_pixbuf(map_img))
|
||||||
else:
|
else:
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR)
|
|
||||||
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
||||||
|
|
||||||
def id3_did_change(self):
|
def id3_did_change(self):
|
||||||
|
@ -377,10 +350,8 @@ class NRSC5_DUI(object):
|
||||||
imageList = musicbrainzngs.get_image_list(inID)
|
imageList = musicbrainzngs.get_image_list(inID)
|
||||||
except:
|
except:
|
||||||
print("MusicBrainz image list retrieval error for id "+inID)
|
print("MusicBrainz image list retrieval error for id "+inID)
|
||||||
#pass
|
|
||||||
|
|
||||||
if (imageList is not None) and ('images' in imageList):
|
if (imageList is not None) and ('images' in imageList):
|
||||||
#print('has images')
|
|
||||||
for (idx, image) in enumerate(imageList['images']):
|
for (idx, image) in enumerate(imageList['images']):
|
||||||
imgTypes = self.check_value('types', image, None)
|
imgTypes = self.check_value('types', image, None)
|
||||||
imgApproved = self.check_value('approved', image, "False")
|
imgApproved = self.check_value('approved', image, "False")
|
||||||
|
@ -397,7 +368,6 @@ class NRSC5_DUI(object):
|
||||||
imgData = musicbrainzngs.get_image_front(inID, size="500")
|
imgData = musicbrainzngs.get_image_front(inID, size="500")
|
||||||
except:
|
except:
|
||||||
print("MusicBrainz image retrieval error for id "+inID)
|
print("MusicBrainz image retrieval error for id "+inID)
|
||||||
#pass
|
|
||||||
|
|
||||||
if (imgData is not None) and (len(imgData) > 0):
|
if (imgData is not None) and (len(imgData) > 0):
|
||||||
dataBytes = io.BytesIO(imgData)
|
dataBytes = io.BytesIO(imgData)
|
||||||
|
@ -416,13 +386,10 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
setExtend = (self.cbExtend.get_sensitive() and self.cbExtend.get_active())
|
setExtend = (self.cbExtend.get_sensitive() and self.cbExtend.get_active())
|
||||||
searchArtist = newArtist
|
searchArtist = newArtist
|
||||||
#searchArtist = artist=self.streamInfo["Artist"].replace("'","’").replace("/","ft.")
|
|
||||||
newTitle = self.streamInfo["Title"].replace("'","’")
|
newTitle = self.streamInfo["Title"].replace("'","’")
|
||||||
baseStr = str(newArtist+" - "+self.streamInfo["Title"]).replace(" ","_").replace("/","_").replace(":","_")+".jpg"
|
baseStr = str(newArtist+" - "+self.streamInfo["Title"]).replace(" ","_").replace("/","_").replace(":","_")+".jpg"
|
||||||
saveStr = os.path.join(aasDir, baseStr)
|
saveStr = os.path.join(aasDir, baseStr)
|
||||||
|
|
||||||
#print("lastXHDR: "+self.lastXHDR)
|
|
||||||
#if ((newArtist=="") and (newTitle=="")) or (setExtend and (self.lastXHDR == "1")):
|
|
||||||
if ((newArtist=="") and (newTitle=="")):
|
if ((newArtist=="") and (newTitle=="")):
|
||||||
self.coverImage = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
self.coverImage = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
||||||
self.streamInfo['Album']=""
|
self.streamInfo['Album']=""
|
||||||
|
@ -443,13 +410,6 @@ class NRSC5_DUI(object):
|
||||||
i = 1
|
i = 1
|
||||||
|
|
||||||
while (not imgSaved):
|
while (not imgSaved):
|
||||||
#if no image was downloaded the first time through and Strict was True, try again setting Strict to False
|
|
||||||
#print()
|
|
||||||
#if (i==2) and (setStrict):
|
|
||||||
# setStrict = False
|
|
||||||
# print("Running through again, setStrict is ",setStrict)
|
|
||||||
#else:
|
|
||||||
# print("Running through first time, setStrict is ",setStrict)
|
|
||||||
setStrict = (i in [1,3,5,7])
|
setStrict = (i in [1,3,5,7])
|
||||||
setType = ''
|
setType = ''
|
||||||
if (i in [1,2,3,4]):
|
if (i in [1,2,3,4]):
|
||||||
|
@ -457,25 +417,17 @@ class NRSC5_DUI(object):
|
||||||
setStatus = ''
|
setStatus = ''
|
||||||
if (i in [1,2,5,6]):
|
if (i in [1,2,5,6]):
|
||||||
setStatus = 'Official'
|
setStatus = 'Official'
|
||||||
#print("Search pass #{}: setStrict={}, setType={}, setStatus={}".format(i,setStrict,setType,setStatus))
|
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
#print("searching for {} - {}".format(searchArtist,newTitle))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
#result = musicbrainzngs.search_recordings(strict=setStrict, artist=searchArtist, recording=newTitle, type='Album', status='Official')
|
|
||||||
result = musicbrainzngs.search_recordings(strict=setStrict, artist=searchArtist, recording=newTitle, type=setType, status=setStatus)
|
result = musicbrainzngs.search_recordings(strict=setStrict, artist=searchArtist, recording=newTitle, type=setType, status=setStatus)
|
||||||
#print("recording search succeeded")
|
|
||||||
except:
|
except:
|
||||||
print("MusicBrainz recording search error")
|
print("MusicBrainz recording search error")
|
||||||
#pass
|
|
||||||
|
|
||||||
#print("got recording search result with {} recordings".format(len(result['recording-list'])))
|
|
||||||
if (result is not None) and ('recording-list' in result) and (len(result['recording-list']) != 0):
|
if (result is not None) and ('recording-list' in result) and (len(result['recording-list']) != 0):
|
||||||
# loop through the list until you get a match
|
# loop through the list until you get a match
|
||||||
for (idx, release) in enumerate(result['recording-list']):
|
for (idx, release) in enumerate(result['recording-list']):
|
||||||
#print(release)
|
|
||||||
resultID = self.check_value('id',release,"")
|
resultID = self.check_value('id',release,"")
|
||||||
resultScore = self.check_value('ext:score',release,"0")
|
resultScore = self.check_value('ext:score',release,"0")
|
||||||
resultArtist = self.check_value('artist-credit-phrase',release,"")
|
resultArtist = self.check_value('artist-credit-phrase',release,"")
|
||||||
|
@ -493,10 +445,8 @@ class NRSC5_DUI(object):
|
||||||
resultArtist2 = ""
|
resultArtist2 = ""
|
||||||
releaseMatch = False
|
releaseMatch = False
|
||||||
imageMatch = False
|
imageMatch = False
|
||||||
#print(" #{} got release list with {} releases and recordingMatch is {}".format(idx, len(release['release-list']),recordingMatch))
|
|
||||||
if recordingMatch and ('release-list' in release):
|
if recordingMatch and ('release-list' in release):
|
||||||
for (idx2, release2) in enumerate(release['release-list']):
|
for (idx2, release2) in enumerate(release['release-list']):
|
||||||
#print(release2)
|
|
||||||
imageMatch = False
|
imageMatch = False
|
||||||
resultID = self.check_value('id',release2,"")
|
resultID = self.check_value('id',release2,"")
|
||||||
resultStatus = self.check_value('status',release2,"Official")
|
resultStatus = self.check_value('status',release2,"Official")
|
||||||
|
@ -506,10 +456,8 @@ class NRSC5_DUI(object):
|
||||||
typeMatch = (resultType in ['Single','Album','EP'])
|
typeMatch = (resultType in ['Single','Album','EP'])
|
||||||
statusMatch = (resultStatus == 'Official')
|
statusMatch = (resultStatus == 'Official')
|
||||||
albumMatch = (not self.check_terms(resultAlbum, albumExclude))
|
albumMatch = (not self.check_terms(resultAlbum, albumExclude))
|
||||||
#artistMatch2 = (resultArtist2 != "") and (not ('Various' in resultArtist2))
|
|
||||||
artistMatch2 = (not ('Various' in resultArtist2))
|
artistMatch2 = (not ('Various' in resultArtist2))
|
||||||
releaseMatch = (artistMatch2 and albumMatch and typeMatch and statusMatch)
|
releaseMatch = (artistMatch2 and albumMatch and typeMatch and statusMatch)
|
||||||
#print(" #{} {}: Track: {} - {}, {}: {} - {}, {} {}% {}".format(idx, resultStatus, resultArtist, resultTitle, resultType, resultArtist2, resultAlbum, resultID, resultScore, resultGenre))
|
|
||||||
# don't bother checking for covers unless album, type, and status match
|
# don't bother checking for covers unless album, type, and status match
|
||||||
if releaseMatch:
|
if releaseMatch:
|
||||||
imageMatch = self.check_musicbrainz_cover(resultID)
|
imageMatch = self.check_musicbrainz_cover(resultID)
|
||||||
|
@ -519,7 +467,6 @@ class NRSC5_DUI(object):
|
||||||
if (recordingMatch and releaseMatch and imageMatch):
|
if (recordingMatch and releaseMatch and imageMatch):
|
||||||
|
|
||||||
# got a full match, now get the cover art
|
# got a full match, now get the cover art
|
||||||
#print("Found {}: Track: {} - {}, {}: {} - {}, {} {}% {}".format(resultStatus, resultArtist, resultTitle, resultType, resultArtist2, resultAlbum, resultID, resultScore, resultGenre))
|
|
||||||
if self.save_musicbrainz_cover(resultID,saveStr):
|
if self.save_musicbrainz_cover(resultID,saveStr):
|
||||||
self.coverImage = saveStr
|
self.coverImage = saveStr
|
||||||
imgSaved = True
|
imgSaved = True
|
||||||
|
@ -528,25 +475,20 @@ class NRSC5_DUI(object):
|
||||||
self.coverMetas[baseStr] = [self.streamInfo["Title"],self.streamInfo["Artist"],self.streamInfo["Album"],self.streamInfo["Genre"]]
|
self.coverMetas[baseStr] = [self.streamInfo["Title"],self.streamInfo["Artist"],self.streamInfo["Album"],self.streamInfo["Genre"]]
|
||||||
|
|
||||||
if (imgSaved) and ((idx+1) < len(result['recording-list'])) or (not scoreMatch):
|
if (imgSaved) and ((idx+1) < len(result['recording-list'])) or (not scoreMatch):
|
||||||
#print("#{} scoreMatch is {}... breaking".format(idx, scoreMatch))
|
|
||||||
break
|
break
|
||||||
|
|
||||||
#i = 2
|
|
||||||
i = i + 1
|
i = i + 1
|
||||||
# if we got an image or Strict was false the first time through, there's no need to run through it again
|
# if we got an image or Strict was false the first time through, there's no need to run through it again
|
||||||
#if (imgSaved) or (setStrict==False):
|
|
||||||
if (imgSaved) or (i == 9) or ((not setExtend) and (i == 2)):
|
if (imgSaved) or (i == 9) or ((not setExtend) and (i == 2)):
|
||||||
break
|
break
|
||||||
|
|
||||||
# If no match use the station logo if there is one
|
# If no match use the station logo if there is one
|
||||||
if (not imgSaved):
|
if (not imgSaved):
|
||||||
#print("No image found, using logo")
|
|
||||||
self.coverImage = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
self.coverImage = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
||||||
self.streamInfo['Album']=""
|
self.streamInfo['Album']=""
|
||||||
self.streamInfo['Genre']=""
|
self.streamInfo['Genre']=""
|
||||||
except:
|
except:
|
||||||
print("general error in the musicbrainz routine")
|
print("general error in the musicbrainz routine")
|
||||||
#pass
|
|
||||||
|
|
||||||
# now display it by simulating a window resize
|
# now display it by simulating a window resize
|
||||||
self.on_cover_resize(self.mainWindow)
|
self.on_cover_resize(self.mainWindow)
|
||||||
|
@ -559,19 +501,12 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
def displayLogo(self):
|
def displayLogo(self):
|
||||||
global aasDir
|
global aasDir
|
||||||
#if (self.stationLogos.has_key(self.stationStr)):
|
|
||||||
if (self.stationStr in self.stationLogos):
|
if (self.stationStr in self.stationLogos):
|
||||||
# show station logo if it's cached
|
# show station logo if it's cached
|
||||||
logo = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
logo = os.path.join(aasDir, self.stationLogos[self.stationStr][self.streamNum])
|
||||||
if (os.path.isfile(logo)):
|
if (os.path.isfile(logo)):
|
||||||
self.streamInfo["Logo"] = self.stationLogos[self.stationStr][self.streamNum]
|
self.streamInfo["Logo"] = self.stationLogos[self.stationStr][self.streamNum]
|
||||||
#img_size = min(self.alignmentCover.get_allocated_height(), self.alignmentCover.get_allocated_width()) - 12
|
|
||||||
#self.pixbuf = Gtk.gdk.pixbuf_new_from_file(logo)
|
|
||||||
#self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(logo)
|
|
||||||
self.coverImage = logo
|
self.coverImage = logo
|
||||||
#self.handle_window_resize()
|
|
||||||
#self.pixbuf = self.pixbuf.scale_simple(img_size, img_size, GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
#self.imgCover.set_from_pixbuf(self.pixbuf)
|
|
||||||
self.showArtwork(logo)
|
self.showArtwork(logo)
|
||||||
else:
|
else:
|
||||||
# add entry in database for the station if it doesn't exist
|
# add entry in database for the station if it doesn't exist
|
||||||
|
@ -589,11 +524,7 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
def handle_window_resize(self):
|
def handle_window_resize(self):
|
||||||
if (self.pixbuf != None):
|
if (self.pixbuf != None):
|
||||||
#allocation = self.imgCover.get_allocation()
|
|
||||||
#desired_width = int(allocation.width / 2.5)
|
|
||||||
#desired_height = desired_width
|
|
||||||
desired_size = min(self.alignmentCover.get_allocated_height(), self.alignmentCover.get_allocated_width()) - 12
|
desired_size = min(self.alignmentCover.get_allocated_height(), self.alignmentCover.get_allocated_width()) - 12
|
||||||
#self.pixbuf = self.pixbuf.scale_simple(desired_width, desired_height, Gtk.gdk.INTERP_HYPER)
|
|
||||||
self.pixbuf = self.pixbuf.scale_simple(desired_size, desired_size, GdkPixbuf.InterpType.BILINEAR)
|
self.pixbuf = self.pixbuf.scale_simple(desired_size, desired_size, GdkPixbuf.InterpType.BILINEAR)
|
||||||
self.imgCover.set_from_pixbuf(self.pixbuf)
|
self.imgCover.set_from_pixbuf(self.pixbuf)
|
||||||
|
|
||||||
|
@ -609,7 +540,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
# update all of the spin buttons to prevent the text from sticking
|
# update all of the spin buttons to prevent the text from sticking
|
||||||
self.spinFreq.update()
|
self.spinFreq.update()
|
||||||
#self.spinStream.update()
|
|
||||||
self.spinGain.update()
|
self.spinGain.update()
|
||||||
self.spinPPM.update()
|
self.spinPPM.update()
|
||||||
self.spinRTL.update()
|
self.spinRTL.update()
|
||||||
|
@ -628,7 +558,6 @@ class NRSC5_DUI(object):
|
||||||
if (not self.cbAutoGain.get_active()):
|
if (not self.cbAutoGain.get_active()):
|
||||||
self.streamInfo["Gain"] = self.spinGain.get_value()
|
self.streamInfo["Gain"] = self.spinGain.get_value()
|
||||||
self.nrsc5Args.append("-g")
|
self.nrsc5Args.append("-g")
|
||||||
#self.nrsc5Args.append(str(int(self.streamInfo["Gain"]*10)))
|
|
||||||
self.nrsc5Args.append(str(int(self.streamInfo["Gain"])))
|
self.nrsc5Args.append(str(int(self.streamInfo["Gain"])))
|
||||||
|
|
||||||
# set ppm error if not zero
|
# set ppm error if not zero
|
||||||
|
@ -643,18 +572,14 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
# set frequency and stream
|
# set frequency and stream
|
||||||
self.nrsc5Args.append(str(self.spinFreq.get_value()))
|
self.nrsc5Args.append(str(self.spinFreq.get_value()))
|
||||||
#self.nrsc5Args.append(str(int(self.spinStream.get_value()-1)))
|
|
||||||
self.nrsc5Args.append(str(int(self.streamNum)))
|
self.nrsc5Args.append(str(int(self.streamNum)))
|
||||||
|
|
||||||
#print(self.nrsc5Args)
|
|
||||||
|
|
||||||
# start the timer
|
# start the timer
|
||||||
self.statusTimer = Timer(1, self.checkStatus)
|
self.statusTimer = Timer(1, self.checkStatus)
|
||||||
self.statusTimer.start()
|
self.statusTimer.start()
|
||||||
|
|
||||||
# disable the controls
|
# disable the controls
|
||||||
self.spinFreq.set_sensitive(False)
|
self.spinFreq.set_sensitive(False)
|
||||||
#self.spinStream.set_sensitive(False)
|
|
||||||
self.spinGain.set_sensitive(False)
|
self.spinGain.set_sensitive(False)
|
||||||
self.spinPPM.set_sensitive(False)
|
self.spinPPM.set_sensitive(False)
|
||||||
self.spinRTL.set_sensitive(False)
|
self.spinRTL.set_sensitive(False)
|
||||||
|
@ -662,24 +587,18 @@ class NRSC5_DUI(object):
|
||||||
self.btnStop.set_sensitive(True)
|
self.btnStop.set_sensitive(True)
|
||||||
self.cbAutoGain.set_sensitive(False)
|
self.cbAutoGain.set_sensitive(False)
|
||||||
self.playing = True
|
self.playing = True
|
||||||
#self.lastXHDR = ["", -1]
|
|
||||||
self.lastXHDR = ""
|
self.lastXHDR = ""
|
||||||
self.lastLOT = ""
|
self.lastLOT = ""
|
||||||
#print("lastXHDR reset")
|
|
||||||
|
|
||||||
# start the player thread
|
# start the player thread
|
||||||
self.playerThread = Thread(target=self.play)
|
self.playerThread = Thread(target=self.play)
|
||||||
self.playerThread.start()
|
self.playerThread.start()
|
||||||
|
|
||||||
self.stationStr = str(self.spinFreq.get_value())
|
self.stationStr = str(self.spinFreq.get_value())
|
||||||
#self.stationNum = int(self.spinStream.get_value())-1
|
|
||||||
#self.set_program_btns()
|
|
||||||
|
|
||||||
self.displayLogo()
|
self.displayLogo()
|
||||||
|
|
||||||
# check if station is bookmarked
|
# check if station is bookmarked
|
||||||
self.bookmarked = False
|
self.bookmarked = False
|
||||||
#freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.spinStream.get_value())
|
|
||||||
freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.streamNum + 1)
|
freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.streamNum + 1)
|
||||||
for b in self.bookmarks:
|
for b in self.bookmarks:
|
||||||
if (b[2] == freq):
|
if (b[2] == freq):
|
||||||
|
@ -720,7 +639,6 @@ class NRSC5_DUI(object):
|
||||||
if (not self.cbAutoGain.get_active()):
|
if (not self.cbAutoGain.get_active()):
|
||||||
self.spinGain.set_sensitive(True)
|
self.spinGain.set_sensitive(True)
|
||||||
self.spinFreq.set_sensitive(True)
|
self.spinFreq.set_sensitive(True)
|
||||||
#self.spinStream.set_sensitive(True)
|
|
||||||
self.spinPPM.set_sensitive(True)
|
self.spinPPM.set_sensitive(True)
|
||||||
self.spinRTL.set_sensitive(True)
|
self.spinRTL.set_sensitive(True)
|
||||||
self.btnPlay.set_sensitive(True)
|
self.btnPlay.set_sensitive(True)
|
||||||
|
@ -737,12 +655,10 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
def on_btnBookmark_clicked(self, btn):
|
def on_btnBookmark_clicked(self, btn):
|
||||||
# pack frequency and channel number into one int
|
# pack frequency and channel number into one int
|
||||||
#freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.spinStream.get_value())
|
|
||||||
freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.streamNum + 1)
|
freq = int((self.spinFreq.get_value()+0.005)*100) + int(self.streamNum + 1)
|
||||||
|
|
||||||
# create bookmark
|
# create bookmark
|
||||||
bookmark = [
|
bookmark = [
|
||||||
#"{:4.1f}-{:1.0f}".format(self.spinFreq.get_value(), self.spinStream.get_value()),
|
|
||||||
"{:4.1f}-{:1.0f}".format(self.spinFreq.get_value(), self.streamNum + 1),
|
"{:4.1f}-{:1.0f}".format(self.spinFreq.get_value(), self.streamNum + 1),
|
||||||
self.streamInfo["Callsign"],
|
self.streamInfo["Callsign"],
|
||||||
freq
|
freq
|
||||||
|
@ -824,7 +740,6 @@ class NRSC5_DUI(object):
|
||||||
about_dialog.set_comments("A second-generation graphical interface for nrsc5.")
|
about_dialog.set_comments("A second-generation graphical interface for nrsc5.")
|
||||||
about_dialog.set_authors(authors)
|
about_dialog.set_authors(authors)
|
||||||
about_dialog.set_license(license)
|
about_dialog.set_license(license)
|
||||||
#about_dialog.set_logo(Gtk.gdk.pixbuf_new_from_file("logo.png"))
|
|
||||||
about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(os.path.join(resDir,"logo.png")))
|
about_dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(os.path.join(resDir,"logo.png")))
|
||||||
|
|
||||||
# callbacks for destroying the dialog
|
# callbacks for destroying the dialog
|
||||||
|
@ -853,15 +768,9 @@ class NRSC5_DUI(object):
|
||||||
self.streamInfo["Logo"] = ""
|
self.streamInfo["Logo"] = ""
|
||||||
self.streamInfo["Bitrate"] = 0
|
self.streamInfo["Bitrate"] = 0
|
||||||
self.set_program_btns()
|
self.set_program_btns()
|
||||||
#print("lastXHDR, cover, and logo reset")
|
|
||||||
if self.playing:
|
if self.playing:
|
||||||
self.nrsc5msg = str(self.streamNum)
|
self.nrsc5msg = str(self.streamNum)
|
||||||
self.displayLogo()
|
self.displayLogo()
|
||||||
#TODO: fix so stream change is smoother - should be able to pipe new stream number to running application and update display_logo()
|
|
||||||
# For now, just restart
|
|
||||||
#if (self.playing):
|
|
||||||
# self.on_btnStop_clicked(None)
|
|
||||||
# self.on_btnPlay_clicked(None)
|
|
||||||
|
|
||||||
def set_program_btns(self):
|
def set_program_btns(self):
|
||||||
self.btnAudioPrgs0.set_active(self.update_btns and self.streamNum == 0)
|
self.btnAudioPrgs0.set_active(self.update_btns and self.streamNum == 0)
|
||||||
|
@ -889,7 +798,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
# set frequency and stream
|
# set frequency and stream
|
||||||
self.spinFreq.set_value(float(int(station/10)/10.0))
|
self.spinFreq.set_value(float(int(station/10)/10.0))
|
||||||
#self.spinStream.set_value(station%10)
|
|
||||||
self.streamNum = (station%10)-1
|
self.streamNum = (station%10)-1
|
||||||
self.on_stream_changed()
|
self.on_stream_changed()
|
||||||
|
|
||||||
|
@ -938,9 +846,7 @@ class NRSC5_DUI(object):
|
||||||
mapImg = Image.open(mapFile).resize((200,200), Image.LANCZOS) # scale map to fit window
|
mapImg = Image.open(mapFile).resize((200,200), Image.LANCZOS) # scale map to fit window
|
||||||
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
||||||
else:
|
else:
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.ICON_SIZE_LARGE_TOOLBAR) # display missing image if file is not found
|
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG) # display missing image if file is not found
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR) # display missing image if file is not found
|
|
||||||
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
|
||||||
|
|
||||||
elif (btn == self.radMapWeather):
|
elif (btn == self.radMapWeather):
|
||||||
self.mapData["mapMode"] = 1
|
self.mapData["mapMode"] = 1
|
||||||
|
@ -948,9 +854,7 @@ class NRSC5_DUI(object):
|
||||||
mapImg = Image.open(self.mapData["weatherNow"]).resize((200,200), Image.LANCZOS) # scale map to fit window
|
mapImg = Image.open(self.mapData["weatherNow"]).resize((200,200), Image.LANCZOS) # scale map to fit window
|
||||||
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
||||||
else:
|
else:
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.ICON_SIZE_LARGE_TOOLBAR) # display missing image if file is not found
|
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG) # display missing image if file is not found
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR) # display missing image if file is not found
|
|
||||||
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
|
||||||
|
|
||||||
def on_btnMap_clicked(self, btn):
|
def on_btnMap_clicked(self, btn):
|
||||||
# open map viewer window
|
# open map viewer window
|
||||||
|
@ -1001,7 +905,6 @@ class NRSC5_DUI(object):
|
||||||
FTMP = open('tmp.log','w')
|
FTMP = open('tmp.log','w')
|
||||||
|
|
||||||
# run nrsc5 and output stdout & stderr to pipes
|
# run nrsc5 and output stdout & stderr to pipes
|
||||||
#self.nrsc5 = Popen(self.nrsc5Args, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
|
||||||
self.nrsc5 = Popen(self.nrsc5Args, shell=False, stdin=self.nrsc5slave, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
self.nrsc5 = Popen(self.nrsc5Args, shell=False, stdin=self.nrsc5slave, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -1009,7 +912,6 @@ class NRSC5_DUI(object):
|
||||||
if (self.nrsc5msg != ""):
|
if (self.nrsc5msg != ""):
|
||||||
select.select([],[self.nrsc5master],[])
|
select.select([],[self.nrsc5master],[])
|
||||||
os.write(self.nrsc5master,str.encode(self.nrsc5msg))
|
os.write(self.nrsc5master,str.encode(self.nrsc5msg))
|
||||||
#print(self.nrsc5msg)
|
|
||||||
self.nrsc5msg = ""
|
self.nrsc5msg = ""
|
||||||
# read output from nrsc5
|
# read output from nrsc5
|
||||||
output = self.nrsc5.stderr.readline()
|
output = self.nrsc5.stderr.readline()
|
||||||
|
@ -1055,18 +957,15 @@ class NRSC5_DUI(object):
|
||||||
def getImageLot(self,imgStr):
|
def getImageLot(self,imgStr):
|
||||||
r = re.compile("^([\d]+)_.*$")
|
r = re.compile("^([\d]+)_.*$")
|
||||||
m = r.match(imgStr)
|
m = r.match(imgStr)
|
||||||
#print("lot is "+m.group(1))
|
|
||||||
return m.group(1)
|
return m.group(1)
|
||||||
|
|
||||||
def checkStatus(self):
|
def checkStatus(self):
|
||||||
# update status information
|
# update status information
|
||||||
def update():
|
def update():
|
||||||
global aasDir
|
global aasDir
|
||||||
#Gdk.threads_enter()
|
|
||||||
try:
|
try:
|
||||||
imagePath = ""
|
imagePath = ""
|
||||||
image = ""
|
image = ""
|
||||||
#ber = [self.streamInfo["BER"][0]*100,self.streamInfo["BER"][1]*100,self.streamInfo["BER"][2]*100,self.streamInfo["BER"][3]*100]
|
|
||||||
ber = [self.streamInfo["BER"][i]*100 for i in range(4)]
|
ber = [self.streamInfo["BER"][i]*100 for i in range(4)]
|
||||||
self.id3Changed = self.id3_did_change()
|
self.id3Changed = self.id3_did_change()
|
||||||
self.txtTitle.set_text(self.streamInfo["Title"])
|
self.txtTitle.set_text(self.streamInfo["Title"])
|
||||||
|
@ -1079,7 +978,6 @@ class NRSC5_DUI(object):
|
||||||
self.txtGenre.set_tooltip_text(self.streamInfo["Genre"])
|
self.txtGenre.set_tooltip_text(self.streamInfo["Genre"])
|
||||||
self.lblBitRate.set_label("{:3.1f} kbps".format(self.streamInfo["Bitrate"]))
|
self.lblBitRate.set_label("{:3.1f} kbps".format(self.streamInfo["Bitrate"]))
|
||||||
self.lblBitRate2.set_label("{:3.1f} kbps".format(self.streamInfo["Bitrate"]))
|
self.lblBitRate2.set_label("{:3.1f} kbps".format(self.streamInfo["Bitrate"]))
|
||||||
#self.lblError.set_label("{:2.2f}% BER ".format(self.streamInfo["BER"][1]*100))
|
|
||||||
self.lblError.set_label("{:2.2f}% BER ".format(self.streamInfo["BER"][0]*100))
|
self.lblError.set_label("{:2.2f}% BER ".format(self.streamInfo["BER"][0]*100))
|
||||||
self.lblCall.set_label(" " + self.streamInfo["Callsign"])
|
self.lblCall.set_label(" " + self.streamInfo["Callsign"])
|
||||||
self.lblName.set_label(self.streamInfo["Callsign"])
|
self.lblName.set_label(self.streamInfo["Callsign"])
|
||||||
|
@ -1124,36 +1022,23 @@ class NRSC5_DUI(object):
|
||||||
# technically we should show the file with the matching lot id
|
# technically we should show the file with the matching lot id
|
||||||
|
|
||||||
lot = -1
|
lot = -1
|
||||||
#if (int(self.lastXHDR[1]) > 0 and self.streamInfo["Cover"] != None):
|
|
||||||
if ((self.lastXHDR == "0") and (self.streamInfo["Cover"] != "")):
|
if ((self.lastXHDR == "0") and (self.streamInfo["Cover"] != "")):
|
||||||
imagePath = os.path.join(aasDir, self.streamInfo["Cover"])
|
imagePath = os.path.join(aasDir, self.streamInfo["Cover"])
|
||||||
image = self.streamInfo["Cover"]
|
image = self.streamInfo["Cover"]
|
||||||
lot = self.getImageLot(image)
|
lot = self.getImageLot(image)
|
||||||
#print("lastXHDR is 0, set image to Cover:"+imagePath)
|
|
||||||
#elif (int(self.lastXHDR[1]) < 0 or self.streamInfo["Cover"] == None):
|
|
||||||
elif (((self.lastXHDR == "1") or (self.lastImage != "")) and (self.streamInfo["Logo"] != "")):
|
elif (((self.lastXHDR == "1") or (self.lastImage != "")) and (self.streamInfo["Logo"] != "")):
|
||||||
imagePath = os.path.join(aasDir, self.streamInfo["Logo"])
|
imagePath = os.path.join(aasDir, self.streamInfo["Logo"])
|
||||||
image = self.streamInfo["Logo"]
|
image = self.streamInfo["Logo"]
|
||||||
#print("lastXHDR is 1, set image to Logo:"+imagePath)
|
|
||||||
if (not os.path.isfile(imagePath)):
|
if (not os.path.isfile(imagePath)):
|
||||||
self.imgCover.clear()
|
self.imgCover.clear()
|
||||||
self.coverImage = ""
|
self.coverImage = ""
|
||||||
|
|
||||||
# resize and display image if it changed and exists
|
# resize and display image if it changed and exists
|
||||||
if (self.xhdrChanged and (self.lastImage != image) and ((self.lastLOT == lot) or (lot == -1)) and os.path.isfile(imagePath)):
|
if (self.xhdrChanged and (self.lastImage != image) and ((self.lastLOT == lot) or (lot == -1)) and os.path.isfile(imagePath)):
|
||||||
#if ((self.lastImage != image) and os.path.isfile(imagePath)):
|
|
||||||
#print("xhdrChanged, image changed, lot matches image, and file exists:"+imagePath)
|
|
||||||
self.xhdrChanged = False
|
self.xhdrChanged = False
|
||||||
self.lastImage = image
|
self.lastImage = image
|
||||||
#img_size = min(self.alignmentCover.get_allocated_height(), self.alignmentCover.get_allocated_width()) - 12
|
|
||||||
#self.pixbuf = Gtk.gdk.pixbuf_new_from_file(imagePath)
|
|
||||||
#self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(imagePath)
|
|
||||||
self.coverImage = imagePath
|
self.coverImage = imagePath
|
||||||
#self.pixbuf = self.pixbuf.scale_simple(img_size, img_size, GdkPixbuf.InterpType.BILINEAR)
|
|
||||||
#self.imgCover.set_from_pixbuf(self.pixbuf)
|
|
||||||
self.showArtwork(imagePath)
|
self.showArtwork(imagePath)
|
||||||
#print("displaying image:"+imagePath)
|
|
||||||
#self.handle_window_resize()
|
|
||||||
self.debugLog("Image Changed")
|
self.debugLog("Image Changed")
|
||||||
|
|
||||||
# Disable downloaded cover images until fixed with MusicBrainz
|
# Disable downloaded cover images until fixed with MusicBrainz
|
||||||
|
@ -1161,11 +1046,9 @@ class NRSC5_DUI(object):
|
||||||
self.get_cover_image_online()
|
self.get_cover_image_online()
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
#Gdk.threads_leave()
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if (self.playing):
|
if (self.playing):
|
||||||
#gobject.idle_add(update)
|
|
||||||
GLib.idle_add(update)
|
GLib.idle_add(update)
|
||||||
self.statusTimer = Timer(1, self.checkStatus)
|
self.statusTimer = Timer(1, self.checkStatus)
|
||||||
self.statusTimer.start()
|
self.statusTimer.start()
|
||||||
|
@ -1187,7 +1070,7 @@ class NRSC5_DUI(object):
|
||||||
# check if the tile has already been loaded
|
# check if the tile has already been loaded
|
||||||
if (self.mapData["mapTiles"][x][y] == ts):
|
if (self.mapData["mapTiles"][x][y] == ts):
|
||||||
try:
|
try:
|
||||||
os.remove(os.path.join(aasDir, fileName)) # delete this tile, it's not needed
|
os.remove(os.path.join(aasDir, fileName)) # delete this tile, it's not needed
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return # no need to recreate the map if it hasn't changed
|
return # no need to recreate the map if it hasn't changed
|
||||||
|
@ -1199,7 +1082,7 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
currentPath = os.path.join(aasDir,fileName)
|
currentPath = os.path.join(aasDir,fileName)
|
||||||
newPath = os.path.join(mapDir, "TrafficMap_{:g}_{:g}.png".format(x,y)) # create path to new tile location
|
newPath = os.path.join(mapDir, "TrafficMap_{:g}_{:g}.png".format(x,y)) # create path to new tile location
|
||||||
if(os.path.exists(newPath)): os.remove(newPath) # delete old image if it exists (only necessary on windows)
|
if(os.path.exists(newPath)): os.remove(newPath) # delete old image if it exists (only necessary on windows)
|
||||||
shutil.move(currentPath, newPath) # move and rename map tile
|
shutil.move(currentPath, newPath) # move and rename map tile
|
||||||
except:
|
except:
|
||||||
|
@ -1215,16 +1098,14 @@ class NRSC5_DUI(object):
|
||||||
imgMap = Image.new("RGB", (600, 600), "white") # create blank image for traffic map
|
imgMap = Image.new("RGB", (600, 600), "white") # create blank image for traffic map
|
||||||
for i in range(0,3):
|
for i in range(0,3):
|
||||||
for j in range(0,3):
|
for j in range(0,3):
|
||||||
tileFile = os.path.join(mapDir, "TrafficMap_{:g}_{:g}.png".format(i,j)) # get path to tile
|
tileFile = os.path.join(mapDir, "TrafficMap_{:g}_{:g}.png".format(i,j)) # get path to tile
|
||||||
imgMap.paste(Image.open(tileFile), (j*200, i*200)) # paste tile into map
|
imgMap.paste(Image.open(tileFile), (j*200, i*200)) # paste tile into map
|
||||||
os.remove(tileFile) # delete tile image
|
os.remove(tileFile) # delete tile image
|
||||||
|
|
||||||
# now put a timestamp on it.
|
# now put a timestamp on it.
|
||||||
imgMap = imgMap.convert("RGBA")
|
imgMap = imgMap.convert("RGBA")
|
||||||
imgBig = (981,981) # size of a weather map
|
imgBig = (981,981) # size of a weather map
|
||||||
#posTS = (imgMap.size[0]-235, imgMap.size[1]-29) # calculate position to put timestamp (bottom right)
|
|
||||||
posTS = (imgBig[0]-235, imgBig[1]-29) # calculate position to put timestamp (bottom right)
|
posTS = (imgBig[0]-235, imgBig[1]-29) # calculate position to put timestamp (bottom right)
|
||||||
#imgTS = self.mkTimestamp(t, imgMap.size, posTS) # create timestamp
|
|
||||||
imgTS = self.mkTimestamp(t, imgBig, posTS) # create timestamp for a weather map
|
imgTS = self.mkTimestamp(t, imgBig, posTS) # create timestamp for a weather map
|
||||||
imgTS = imgTS.resize((imgMap.size[0], imgMap.size[1]), Image.LANCZOS) # resize it so it's proportional to the size of a traffic map (981 -> 600)
|
imgTS = imgTS.resize((imgMap.size[0], imgMap.size[1]), Image.LANCZOS) # resize it so it's proportional to the size of a traffic map (981 -> 600)
|
||||||
imgMap = Image.alpha_composite(imgMap, imgTS) # overlay timestamp on traffic map
|
imgMap = Image.alpha_composite(imgMap, imgTS) # overlay timestamp on traffic map
|
||||||
|
@ -1234,8 +1115,7 @@ class NRSC5_DUI(object):
|
||||||
# display on map page
|
# display on map page
|
||||||
if (self.radMapTraffic.get_active()):
|
if (self.radMapTraffic.get_active()):
|
||||||
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
||||||
#imgMap = imgMap.resize((200,200), Image.LANCZOS) # scale map to fit window
|
imgMap = imgMap.resize((img_size, img_size), Image.LANCZOS) # scale map to fit window
|
||||||
imgMap = imgMap.resize((img_size, img_size), Image.LANCZOS)
|
|
||||||
self.imgMap.set_from_pixbuf(imgToPixbuf(imgMap)) # convert image to pixbuf and display
|
self.imgMap.set_from_pixbuf(imgToPixbuf(imgMap)) # convert image to pixbuf and display
|
||||||
|
|
||||||
if (self.mapViewer is not None): self.mapViewer.updated(0) # notify map viwerer if it's open
|
if (self.mapViewer is not None): self.mapViewer.updated(0) # notify map viwerer if it's open
|
||||||
|
@ -1261,7 +1141,7 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
if (self.mapData["weatherTime"] == ts):
|
if (self.mapData["weatherTime"] == ts):
|
||||||
try:
|
try:
|
||||||
os.remove(os.path.join(aasDir, fileName)) # delete this tile, it's not needed
|
os.remove(os.path.join(aasDir, fileName)) # delete this tile, it's not needed
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return # no need to recreate the map if it hasn't changed
|
return # no need to recreate the map if it hasn't changed
|
||||||
|
@ -1275,14 +1155,14 @@ class NRSC5_DUI(object):
|
||||||
# move new overlay to map directory
|
# move new overlay to map directory
|
||||||
try:
|
try:
|
||||||
if(os.path.exists(wxOlPath)): os.remove(wxOlPath) # delete old image if it exists (only necessary on windows)
|
if(os.path.exists(wxOlPath)): os.remove(wxOlPath) # delete old image if it exists (only necessary on windows)
|
||||||
shutil.move(os.path.join(aasDir, fileName), wxOlPath) # move and rename map tile
|
shutil.move(os.path.join(aasDir, fileName), wxOlPath) # move and rename map tile
|
||||||
except:
|
except:
|
||||||
self.debugLog("Error moving weather overlay", True)
|
self.debugLog("Error moving weather overlay", True)
|
||||||
self.mapData["weatherTime"] = 0
|
self.mapData["weatherTime"] = 0
|
||||||
|
|
||||||
# create weather map
|
# create weather map
|
||||||
try:
|
try:
|
||||||
mapPath = os.path.join(mapDir, "BaseMap_" + id + ".png") # get path to base map
|
mapPath = os.path.join(mapDir, "BaseMap_" + id + ".png") # get path to base map
|
||||||
if (os.path.isfile(mapPath) == False): # make sure base map exists
|
if (os.path.isfile(mapPath) == False): # make sure base map exists
|
||||||
self.makeBaseMap(self.mapData["weatherID"], self.mapData["weatherPos"]) # create base map if it doesn't exist
|
self.makeBaseMap(self.mapData["weatherID"], self.mapData["weatherPos"]) # create base map if it doesn't exist
|
||||||
|
|
||||||
|
@ -1300,8 +1180,7 @@ class NRSC5_DUI(object):
|
||||||
# display on map page
|
# display on map page
|
||||||
if (self.radMapWeather.get_active()):
|
if (self.radMapWeather.get_active()):
|
||||||
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
img_size = min(self.alignmentMap.get_allocated_height(), self.alignmentMap.get_allocated_width()) - 12
|
||||||
#imgMap = imgMap.resize((200,200), Image.LANCZOS) # scale map to fit window
|
imgMap = imgMap.resize((img_size, img_size), Image.LANCZOS) # scale map to fit window
|
||||||
imgMap = imgMap.resize((img_size, img_size), Image.LANCZOS) # scale map to fit window
|
|
||||||
self.imgMap.set_from_pixbuf(imgToPixbuf(imgMap)) # convert image to pixbuf and display
|
self.imgMap.set_from_pixbuf(imgToPixbuf(imgMap)) # convert image to pixbuf and display
|
||||||
|
|
||||||
self.proccessWeatherMaps() # get rid of old maps and add new ones to the list
|
self.proccessWeatherMaps() # get rid of old maps and add new ones to the list
|
||||||
|
@ -1317,7 +1196,7 @@ class NRSC5_DUI(object):
|
||||||
weatherPos = None
|
weatherPos = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(aasDir, fileName)) as weatherInfo: # open weather info file
|
with open(os.path.join(aasDir, fileName)) as weatherInfo: # open weather info file
|
||||||
for line in weatherInfo: # read line by line
|
for line in weatherInfo: # read line by line
|
||||||
if ("DWR_Area_ID=" in line): # look for line with "DWR_Area_ID=" in it
|
if ("DWR_Area_ID=" in line): # look for line with "DWR_Area_ID=" in it
|
||||||
# get ID from line
|
# get ID from line
|
||||||
|
@ -1346,12 +1225,10 @@ class NRSC5_DUI(object):
|
||||||
def proccessWeatherMaps(self):
|
def proccessWeatherMaps(self):
|
||||||
global mapDir
|
global mapDir
|
||||||
numberOfMaps = 0
|
numberOfMaps = 0
|
||||||
#r = re.compile("^map.WeatherMap_([a-zA-Z0-9]+)_([0-9]+).png")
|
|
||||||
r = re.compile("^.*map.WeatherMap_([a-zA-Z0-9]+)_([0-9]+).png")
|
r = re.compile("^.*map.WeatherMap_([a-zA-Z0-9]+)_([0-9]+).png")
|
||||||
now = dtToTs(datetime.datetime.now(tz.tzutc())) # get current time
|
now = dtToTs(datetime.datetime.now(tz.tzutc())) # get current time
|
||||||
files = glob.glob(os.path.join(mapDir, "WeatherMap_") + "*.png") # look for weather map files
|
files = glob.glob(os.path.join(mapDir, "WeatherMap_") + "*.png") # look for weather map files
|
||||||
files.sort() # sort files
|
files.sort() # sort files
|
||||||
#print(files)
|
|
||||||
for f in files:
|
for f in files:
|
||||||
m = r.match(f) # match regex
|
m = r.match(f) # match regex
|
||||||
if (m):
|
if (m):
|
||||||
|
@ -1371,7 +1248,7 @@ class NRSC5_DUI(object):
|
||||||
# skip if not the correct location
|
# skip if not the correct location
|
||||||
elif (id == self.mapData["weatherID"]):
|
elif (id == self.mapData["weatherID"]):
|
||||||
if (f not in self.weatherMaps):
|
if (f not in self.weatherMaps):
|
||||||
self.weatherMaps.append(f) # add to list
|
self.weatherMaps.append(f) # add to list
|
||||||
numberOfMaps += 1
|
numberOfMaps += 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -1394,12 +1271,12 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
def makeBaseMap(self, id, pos):
|
def makeBaseMap(self, id, pos):
|
||||||
global mapDir
|
global mapDir
|
||||||
mapPath = os.path.join(mapDir, "BaseMap_" + id + ".png") # get map path
|
mapPath = os.path.join(mapDir, "BaseMap_" + id + ".png") # get map path
|
||||||
if (os.path.isfile(self.mapFile)):
|
if (os.path.isfile(self.mapFile)):
|
||||||
if (os.path.isfile(mapPath) == False): # check if the map has already been created for this location
|
if (os.path.isfile(mapPath) == False): # check if the map has already been created for this location
|
||||||
self.debugLog("Creating new map: " + mapPath)
|
self.debugLog("Creating new map: " + mapPath)
|
||||||
px = self.getMapArea(*pos) # convert map locations to pixel coordinates
|
px = self.getMapArea(*pos) # convert map locations to pixel coordinates
|
||||||
mapImg = Image.open(self.mapFile).crop(px) # open the full map and crop it to the coordinates
|
mapImg = Image.open(self.mapFile).crop(px) # open the full map and crop it to the coordinates
|
||||||
mapImg.save(mapPath) # save the cropped map to disk for later use
|
mapImg.save(mapPath) # save the cropped map to disk for later use
|
||||||
self.debugLog("Finished creating map")
|
self.debugLog("Finished creating map")
|
||||||
else:
|
else:
|
||||||
|
@ -1438,7 +1315,6 @@ class NRSC5_DUI(object):
|
||||||
def parseFeedback(self, line):
|
def parseFeedback(self, line):
|
||||||
global aasDir, mapDir
|
global aasDir, mapDir
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
#print(line)
|
|
||||||
if (self.regex[4].match(line)):
|
if (self.regex[4].match(line)):
|
||||||
# match title
|
# match title
|
||||||
m = self.regex[4].match(line)
|
m = self.regex[4].match(line)
|
||||||
|
@ -1470,17 +1346,13 @@ class NRSC5_DUI(object):
|
||||||
elif (self.regex[13].match(line)):
|
elif (self.regex[13].match(line)):
|
||||||
# match xhdr
|
# match xhdr
|
||||||
m = self.regex[13].match(line)
|
m = self.regex[13].match(line)
|
||||||
#xhdr = [m.group(1),m.group(2)]
|
|
||||||
xhdr = m.group(1)
|
xhdr = m.group(1)
|
||||||
mime = m.group(2)
|
mime = m.group(2)
|
||||||
lot = m.group(3)
|
lot = m.group(3)
|
||||||
#print("got XHDR msg xhdr:"+xhdr+" for lot:"+lot)
|
|
||||||
if (xhdr != self.lastXHDR) or (lot != self.lastLOT):
|
if (xhdr != self.lastXHDR) or (lot != self.lastLOT):
|
||||||
#print("xhdr changed:"+xhdr+" for lot:"+lot)
|
|
||||||
self.lastXHDR = xhdr
|
self.lastXHDR = xhdr
|
||||||
self.lastLOT = lot
|
self.lastLOT = lot
|
||||||
self.xhdrChanged = True
|
self.xhdrChanged = True
|
||||||
#self.debugLog("XHDR Changed: {:s} (lot {:s})".format(xhdr[0],xhdr[1]))
|
|
||||||
self.debugLog("XHDR Changed: {:s} (lot {:s})".format(xhdr,lot))
|
self.debugLog("XHDR Changed: {:s} (lot {:s})".format(xhdr,lot))
|
||||||
elif (self.regex[7].match(line)):
|
elif (self.regex[7].match(line)):
|
||||||
# match album art
|
# match album art
|
||||||
|
@ -1494,7 +1366,6 @@ class NRSC5_DUI(object):
|
||||||
coverStream = self.checkPorts(p,0)
|
coverStream = self.checkPorts(p,0)
|
||||||
logoStream = self.checkPorts(p,1)
|
logoStream = self.checkPorts(p,1)
|
||||||
|
|
||||||
#print("got LOT msg, port:"+str(p)+" lot_name:"+fileName+" size:"+str(fileSize))
|
|
||||||
# check file existance and size .. right now we just debug log
|
# check file existance and size .. right now we just debug log
|
||||||
if (not os.path.isfile(os.path.join(aasDir,fileName))):
|
if (not os.path.isfile(os.path.join(aasDir,fileName))):
|
||||||
self.debugLog("Missing file: " + fileName)
|
self.debugLog("Missing file: " + fileName)
|
||||||
|
@ -1503,26 +1374,17 @@ class NRSC5_DUI(object):
|
||||||
if (fileSize != actualFileSize):
|
if (fileSize != actualFileSize):
|
||||||
self.debugLog("Corrupt file: " + fileName + " (expected: "+fileSize+" bytes, got "+actualFileSize+" bytes)")
|
self.debugLog("Corrupt file: " + fileName + " (expected: "+fileSize+" bytes, got "+actualFileSize+" bytes)")
|
||||||
|
|
||||||
#tmp = self.streams[int(self.spinStream.get_value()-1)][0]
|
|
||||||
#tmp = self.streams[int(self.streamNum)][0]
|
|
||||||
|
|
||||||
#if (p == self.streams[int(self.spinStream.get_value()-1)][0]):
|
|
||||||
#if (p == self.streams[int(self.streamNum)][0]):
|
|
||||||
if (coverStream > -1):
|
if (coverStream > -1):
|
||||||
if coverStream == self.streamNum:
|
if coverStream == self.streamNum:
|
||||||
#set cover only if downloading covers and including station covers
|
#set cover only if downloading covers and including station covers
|
||||||
if (self.cbCoverIncl.get_active() or (not self.cbCovers.get_active())):
|
if (self.cbCoverIncl.get_active() or (not self.cbCovers.get_active())):
|
||||||
self.streamInfo["Cover"] = fileName
|
self.streamInfo["Cover"] = fileName
|
||||||
self.debugLog("Got Album Cover: " + fileName)
|
self.debugLog("Got Album Cover: " + fileName)
|
||||||
#print("got Cover:"+fileName+" for stream "+str(coverStream))
|
|
||||||
#elif (p == self.streams[int(self.spinStream.get_value()-1)][1]):
|
|
||||||
#elif (p == self.streams[int(self.streamNum)][1]):
|
|
||||||
elif (logoStream > -1):
|
elif (logoStream > -1):
|
||||||
if logoStream == self.streamNum:
|
if logoStream == self.streamNum:
|
||||||
self.streamInfo["Logo"] = fileName
|
self.streamInfo["Logo"] = fileName
|
||||||
self.stationLogos[self.stationStr][logoStream] = fileName # add station logo to database
|
self.stationLogos[self.stationStr][logoStream] = fileName # add station logo to database
|
||||||
self.debugLog("Got Station Logo: "+fileName)
|
self.debugLog("Got Station Logo: "+fileName)
|
||||||
#print("got Logo:"+fileName+" for stream "+str(logoStream))
|
|
||||||
|
|
||||||
elif(fileName[headerOffset:(5+headerOffset)] == "DWRO_" and mapDir is not None):
|
elif(fileName[headerOffset:(5+headerOffset)] == "DWRO_" and mapDir is not None):
|
||||||
self.processWeatherOverlay(fileName)
|
self.processWeatherOverlay(fileName)
|
||||||
|
@ -1554,7 +1416,7 @@ class NRSC5_DUI(object):
|
||||||
elif (self.regex[11].match(line)):
|
elif (self.regex[11].match(line)):
|
||||||
# match stream
|
# match stream
|
||||||
m = self.regex[11].match(line)
|
m = self.regex[11].match(line)
|
||||||
t = m.group(1) # stream type
|
t = m.group(1) # stream type
|
||||||
s = int(m.group(2), 10) # stream number
|
s = int(m.group(2), 10) # stream number
|
||||||
n = m.group(3)
|
n = m.group(3)
|
||||||
|
|
||||||
|
@ -1624,7 +1486,6 @@ class NRSC5_DUI(object):
|
||||||
self.alignmentMap = builder.get_object("alignment_map")
|
self.alignmentMap = builder.get_object("alignment_map")
|
||||||
self.imgMap = builder.get_object("imgMap")
|
self.imgMap = builder.get_object("imgMap")
|
||||||
self.spinFreq = builder.get_object("spinFreq")
|
self.spinFreq = builder.get_object("spinFreq")
|
||||||
#self.spinStream = builder.get_object("spinStream")
|
|
||||||
self.spinGain = builder.get_object("spinGain")
|
self.spinGain = builder.get_object("spinGain")
|
||||||
self.spinPPM = builder.get_object("spinPPM")
|
self.spinPPM = builder.get_object("spinPPM")
|
||||||
self.spinRTL = builder.get_object("spinRTL")
|
self.spinRTL = builder.get_object("spinRTL")
|
||||||
|
@ -1731,7 +1592,6 @@ class NRSC5_DUI(object):
|
||||||
"BER": [0,0,0,0], # bit error rate: current, average, min, max
|
"BER": [0,0,0,0], # bit error rate: current, average, min, max
|
||||||
"Gain": 0 # automatic gain
|
"Gain": 0 # automatic gain
|
||||||
}
|
}
|
||||||
#print("reset cover and logo")
|
|
||||||
|
|
||||||
self.streams = [[],[],[],[]]
|
self.streams = [[],[],[],[]]
|
||||||
self.numStreams = 0
|
self.numStreams = 0
|
||||||
|
@ -1841,7 +1701,6 @@ class NRSC5_DUI(object):
|
||||||
|
|
||||||
self.mainWindow.move(config["WindowX"], config["WindowY"])
|
self.mainWindow.move(config["WindowX"], config["WindowY"])
|
||||||
self.spinFreq.set_value(config["Frequency"])
|
self.spinFreq.set_value(config["Frequency"])
|
||||||
#self.spinStream.set_value(config["Stream"])
|
|
||||||
self.streamNum = config["Stream"]-1
|
self.streamNum = config["Stream"]-1
|
||||||
if (self.streamNum < 0):
|
if (self.streamNum < 0):
|
||||||
self.streamNum = 0
|
self.streamNum = 0
|
||||||
|
@ -1913,7 +1772,6 @@ class NRSC5_DUI(object):
|
||||||
self.statusTimer.cancel()
|
self.statusTimer.cancel()
|
||||||
|
|
||||||
# wait for player thread to exit
|
# wait for player thread to exit
|
||||||
#if (self.playerThread is not None and self.playerThread.isAlive()):
|
|
||||||
if (self.playerThread is not None and self.playerThread.is_alive()):
|
if (self.playerThread is not None and self.playerThread.is_alive()):
|
||||||
self.playerThread.join(1)
|
self.playerThread.join(1)
|
||||||
|
|
||||||
|
@ -1933,7 +1791,6 @@ class NRSC5_DUI(object):
|
||||||
"Width" : width,
|
"Width" : width,
|
||||||
"Height" : height,
|
"Height" : height,
|
||||||
"Frequency" : self.spinFreq.get_value(),
|
"Frequency" : self.spinFreq.get_value(),
|
||||||
#"Stream" : int(self.spinStream.get_value()),
|
|
||||||
"Stream" : int(self.streamNum)+1,
|
"Stream" : int(self.streamNum)+1,
|
||||||
"Gain" : self.spinGain.get_value(),
|
"Gain" : self.spinGain.get_value(),
|
||||||
"AutoGain" : self.cbAutoGain.get_active(),
|
"AutoGain" : self.cbAutoGain.get_active(),
|
||||||
|
@ -1992,7 +1849,7 @@ class NRSC5_SLPopup(object):
|
||||||
self.entryWindow.close()
|
self.entryWindow.close()
|
||||||
|
|
||||||
def on_entryWindow_delete(self, *args):
|
def on_entryWindow_delete(self, *args):
|
||||||
self.callback() # run the callback
|
self.callback() # run the callback
|
||||||
|
|
||||||
class NRSC5_Map(object):
|
class NRSC5_Map(object):
|
||||||
def __init__(self, parent, callback, data):
|
def __init__(self, parent, callback, data):
|
||||||
|
@ -2029,7 +1886,7 @@ class NRSC5_Map(object):
|
||||||
self.mapWindow.resize(*self.config["windowSize"]) # set the window size
|
self.mapWindow.resize(*self.config["windowSize"]) # set the window size
|
||||||
self.mapWindow.move(*self.config["windowPos"]) # set the window position
|
self.mapWindow.move(*self.config["windowPos"]) # set the window position
|
||||||
if (self.config["mode"] == 0):
|
if (self.config["mode"] == 0):
|
||||||
self.radMapTraffic.set_active(True) # set the map radio buttons
|
self.radMapTraffic.set_active(True) # set the map radio buttons
|
||||||
elif (self.config["mode"] == 1):
|
elif (self.config["mode"] == 1):
|
||||||
self.radMapWeather.set_active(True)
|
self.radMapWeather.set_active(True)
|
||||||
self.setMap(self.config["mode"]) # display the current map
|
self.setMap(self.config["mode"]) # display the current map
|
||||||
|
@ -2042,18 +1899,18 @@ class NRSC5_Map(object):
|
||||||
if (btn.get_active()):
|
if (btn.get_active()):
|
||||||
if (btn == self.radMapTraffic):
|
if (btn == self.radMapTraffic):
|
||||||
self.config["mode"] = 0
|
self.config["mode"] = 0
|
||||||
self.imgKey.set_visible(False) # hide the key for the weather radar
|
self.imgKey.set_visible(False) # hide the key for the weather radar
|
||||||
|
|
||||||
# stop animation if it's enabled
|
# stop animation if it's enabled
|
||||||
if (self.animateTimer is not None):
|
if (self.animateTimer is not None):
|
||||||
self.animateTimer.cancel()
|
self.animateTimer.cancel()
|
||||||
self.animateTimer = None
|
self.animateTimer = None
|
||||||
|
|
||||||
self.setMap(0) # show the traffic map
|
self.setMap(0) # show the traffic map
|
||||||
|
|
||||||
elif (btn == self.radMapWeather):
|
elif (btn == self.radMapWeather):
|
||||||
self.config["mode"] = 1
|
self.config["mode"] = 1
|
||||||
self.imgKey.set_visible(True) # show the key for the weather radar
|
self.imgKey.set_visible(True) # show the key for the weather radar
|
||||||
|
|
||||||
# check if animate is enabled and start animation
|
# check if animate is enabled and start animation
|
||||||
if (self.config["animate"] and self.animateTimer is None):
|
if (self.config["animate"] and self.animateTimer is None):
|
||||||
|
@ -2083,7 +1940,7 @@ class NRSC5_Map(object):
|
||||||
self.config["scale"] = btn.get_active()
|
self.config["scale"] = btn.get_active()
|
||||||
if (self.config["mode"] == 1):
|
if (self.config["mode"] == 1):
|
||||||
if (self.config["animate"]):
|
if (self.config["animate"]):
|
||||||
i = len(self.weatherMaps)-1 if (self.mapIndex-1 < 0) else self.mapIndex-1 # get the index for the current map in the animation
|
i = len(self.weatherMaps)-1 if (self.mapIndex-1 < 0) else self.mapIndex-1 # get the index for the current map in the animation
|
||||||
self.showImage(self.weatherMaps[i], self.config["scale"]) # show the current map in the animation
|
self.showImage(self.weatherMaps[i], self.config["scale"]) # show the current map in the animation
|
||||||
else:
|
else:
|
||||||
self.showImage(self.data["weatherNow"], self.config["scale"]) # show the most recent map
|
self.showImage(self.data["weatherNow"], self.config["scale"]) # show the most recent map
|
||||||
|
@ -2139,15 +1996,13 @@ class NRSC5_Map(object):
|
||||||
def showImage(self, fileName, scale):
|
def showImage(self, fileName, scale):
|
||||||
if (os.path.isfile(fileName)):
|
if (os.path.isfile(fileName)):
|
||||||
if (scale):
|
if (scale):
|
||||||
mapImg = Image.open(fileName).resize((600,600), Image.LANCZOS) # open and scale map to fit window
|
mapImg = Image.open(fileName).resize((600,600), Image.LANCZOS) # open and scale map to fit window
|
||||||
else:
|
else:
|
||||||
mapImg = Image.open(fileName) # open map
|
mapImg = Image.open(fileName) # open map
|
||||||
|
|
||||||
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
self.imgMap.set_from_pixbuf(imgToPixbuf(mapImg)) # convert image to pixbuf and display
|
||||||
else:
|
else:
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.ICON_SIZE_LARGE_TOOLBAR) # display missing image if file is not found
|
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG) # display missing image if file is not found
|
||||||
#self.imgMap.set_from_stock(Gtk.STOCK_MISSING_IMAGE, Gtk.IconSize.LARGE_TOOLBAR) # display missing image if file is not found
|
|
||||||
self.imgMap.set_from_icon_name("MISSING_IMAGE", Gtk.IconSize.DIALOG)
|
|
||||||
|
|
||||||
def setMap(self, map):
|
def setMap(self, map):
|
||||||
global mapDir
|
global mapDir
|
||||||
|
@ -2173,8 +2028,6 @@ def tsToDt(ts):
|
||||||
|
|
||||||
def imgToPixbuf(img):
|
def imgToPixbuf(img):
|
||||||
# convert PIL.Image to gdk.pixbuf
|
# convert PIL.Image to gdk.pixbuf
|
||||||
#imgArr = numpy.array(img.convert("RGB"))
|
|
||||||
#return gtk.gdk.pixbuf_new_from_array(imgArr, gtk.gdk.COLORSPACE_RGB, 8)
|
|
||||||
data = GLib.Bytes.new(img.tobytes())
|
data = GLib.Bytes.new(img.tobytes())
|
||||||
return GdkPixbuf.Pixbuf.new_from_bytes(data, GdkPixbuf.Colorspace.RGB, 'A' in img.getbands(),
|
return GdkPixbuf.Pixbuf.new_from_bytes(data, GdkPixbuf.Colorspace.RGB, 'A' in img.getbands(),
|
||||||
8, img.width, img.height, len(img.getbands())*img.width)
|
8, img.width, img.height, len(img.getbands())*img.width)
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -21,13 +21,13 @@ gtk_package_files.append([os.path.join('lib','gtk-2.0','modules'), get_files_rec
|
||||||
gtk_package_files.append([os.path.join('share','icons'), get_files_recursive(os.path.join(gtk_base_path,'..','runtime','share','icons'))])
|
gtk_package_files.append([os.path.join('share','icons'), get_files_recursive(os.path.join(gtk_base_path,'..','runtime','share','icons'))])
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = 'nrsc5-gui',
|
name = 'nrsc5-dui',
|
||||||
description = 'Graphical frontend for nrsc5 cli utility',
|
description = 'Graphical frontend for nrsc5 cli utility',
|
||||||
version = '1.0',
|
version = '1.0',
|
||||||
|
|
||||||
windows = [
|
windows = [
|
||||||
{
|
{
|
||||||
'script': 'nrsc5-gui.py',
|
'script': 'nrsc5-dui.py',
|
||||||
'icon_resources': [(1, os.path.join("res","nrsc5-gui.ico"))],
|
'icon_resources': [(1, os.path.join("res","nrsc5-gui.ico"))],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue