Ejemplo n.º 1
0
def getTagInCurJson(jsonTags, jsonDict):
    ret = ""
    try:
        if(isinstance(jsonTags[0][0], int)):
            if(jsonTags[0][0] > len(jsonDict)):
                str_tools.printMsg("JSON", "Source file sized differently from template (max: "+ jsonTags[0][0] +"). Parameter changed to max of json source: " + len(jsonDict) -1)
                jsonTags[0][0] = len(jsonDict) -1
    except:
        pass

    for i in range(len(jsonTags[0])):
        r0 = jsonTags[0][i]
        if(i==0): #First
            ret = jsonDict[r0]
        elif (i == len(jsonTags[0]) - 1): #Last one
            if(isinstance(ret, list)):
                ret = ret[0][r0]
            else:
                ret = ret[r0]
        else: #n index in middle
            if(isinstance(ret, list)):
                ret = ret[0][r0]
            else:
                ret = ret[r0]
    return ret
Ejemplo n.º 2
0
def generateImg(content, filename, quality=50):
    driver = driverInit()
    driver.get("about:blank")
    driver.delete_all_cookies()

    encodedBytes = base64.b64encode(content.encode("utf-8"))
    encodedStr = str(encodedBytes, "utf-8")

    driver.get("data:text/html;charset=utf-8;base64," + encodedStr)

    delay = 5
    try:
        waitLoading = WebDriverWait(driver, delay).until(
            EC.presence_of_element_located((By.TAG_NAME, 'end')))
    except TimeoutException:
        str_tools.printMsg("Wdv ", "Timeout on slide generation")

    time.sleep(1)
    png = driver.get_screenshot_as_png()

    box = (0, 0, 320, 240)
    im = Image.open(BytesIO(png))
    rgb_im = im.convert('RGB')
    region = rgb_im.crop(box)

    try:
        region.save(filename + ".jpg", 'JPEG', optimize=True, quality=quality)
    except Exception as ex:
        str_tools.printMsg("Wdv ", "WebDriver error : " + str(ex))
    driver.quit()
Ejemplo n.º 3
0
def searchForJson(expr, d, parent=[], level=0):
    found = 0
    if(isinstance(d, dict)):
        for k, v in d.items():
            if(isinstance(v, dict)):
                parent.append(k)
                level = level+1
                parent, level, found = searchForJson(expr, v, parent, level)
                if (found == 1):
                    return parent, level, found
                parent.pop(len(parent)-1)
            elif(isinstance(v, list)):
                parent.append(k)
                level = level+1
                parent, level, found = searchForJson(expr, v, parent, level)
                if (found == 1):
                    return parent, level, found
                parent.pop(len(parent)-1)
            else:
                if (v == expr):
                    parent.append(k)
                    str_tools.printMsg ("JSON", "Tag '" + expr + "' found in : " + str(parent))
                    return parent, level, 1
    if(isinstance(d, list)):
        idx = 0
        for item in d:
            if(isinstance(item, list)):
                parent.append(item)
                level = level+1
                parent, level, found = searchForJson(expr, item, parent, level)
                if (found == 1):
                    return parent, level, found
            else:
                for k, v in item.items():
                    if(isinstance(v, dict)):
                        parent.append(k)
                        level = level+1
                        parent, level, found = searchForJson(expr, v, parent, level)
                        if (found == 1):
                            return parent, level, found
                        parent.pop(len(parent)-1)
                    else:
                        if (v == expr):
                            if(d.count != 1):
                                parent.append(idx)
                            parent.append(k)
                            str_tools.printMsg ("JSON", "Tag '" + expr + "' found in : " + str(parent))
                            return parent, level, 1
            idx = idx+1
    return parent, level, found
Ejemplo n.º 4
0
def parseJson(file,tmpl):
    artist = ""
    title  = ""
    cover  = ""

    try:
        file = file.decode('utf-8')
    except:
        pass
    
    try:
        if (file.index("{") != 0):
            file = file[file.index("{"):]
        while (file[len(file)-1] != "}"):
            file = file[0:-1]
        if (tmpl.index("{") != 0):
            tmpl = tmpl[tmpl.index("{"):]
        while (tmpl[len(tmpl)-1] != "}"):
            tmpl = tmpl[0:-1]
    except:
        pass

   
    # Identification of where are the $artist, the $title and the $cover tags are in the tmpl file
    jsonDecoderTemplate = json.JSONDecoder()

    jsonTemplate = ""
    try:
        jsonTemplate = jsonDecoderTemplate.decode(tmpl)
    except:
        jsonTemplate = jsonDecoderTemplate.decode("[" + tmpl + "]")

    jsonNF  = ""
    try:
        jsonNF = jsonDecoderTemplate.decode(file)
    except:
        jsonNF = jsonDecoderTemplate.decode("[" + file + "]")

    try:
        artist = getTagInCurJson(searchForJson("$artist", jsonTemplate, []),jsonNF)
        title = getTagInCurJson(searchForJson("$title", jsonTemplate, []),jsonNF)
        cover = getTagInCurJson(searchForJson("$cover", jsonTemplate, []),jsonNF)
    except:
        artist = ""
        title = ""
        cover = ""

    if(artist == "" or title == "" or cover == ""):
        str_tools.printMsg("JSON" ,"The following items aren't found in the json source file:")
        if(artist == ""):
            str_tools.printMsg("JSON", "$artist, ")
        if(title == ""):
            str_tools.printMsg("JSON", "$title, ")
        if(cover == ""):
            str_tools.printMsg("JSON", "$cover")
    return artist, title, cover
Ejemplo n.º 5
0
def dabctlExtSend(cfg, mode, fileToSend):
    hostname = cfg.get('dabctl-ext', 'hostname')
    port = cfg.get('dabctl-ext', 'port')
    pi = cfg.get('dabctl-ext', 'pi')
    try:
        passkey = cfg.get('dabctl-ext', 'passkey')
    except:
        passkey = ""

    url = "http://" + hostname + ":" + str(port) + "/_ext"
    try:
        if (mode == "DLS"):
            dls = ""
            with open(fileToSend, 'r') as f:
                dls = f.readlines()[-1]
            args = {'PI': pi, 'key': passkey, 'variable': 'DLS', 'value': dls}
            ret = requests.post(url, data=args)
        elif (mode == "SLS"):
            args = {'PI': pi, 'key': passkey, 'variable': 'SLS'}
            files = {'file': open(fileToSend, 'rb')}
            ret = requests.post(url, data=args, files=files)
    except Exception as ex:
        str_tools.printMsg("Ext ", "Error requesting DAB-CTL Server : " + ex)
Ejemplo n.º 6
0
def driverInit():
    driver = None
    str_tools.printMsg ("Wdv ", "Initializing WebDriver...")
    try:
        #Formerly with PhantomJS until v0.8.0
        #driver = webdriver.PhantomJS(service_args=["--disk-cache=false", "--ignore-ssl-errors=true", "--ssl-protocol=any"])
        
        #Now with ChromeDriver since v0.9.0
        options = webdriver.ChromeOptions()
        options.add_argument('headless')
        options.add_argument('no-sandbox')
        options.add_argument('disable-dev-shm-usage')
        options.add_argument('hide-scrollbars')
        options.add_argument('log-level=2')

        driver = webdriver.Chrome(options=options)
        driver.set_window_size(320, 240)
        str_tools.printMsg ("Wdv ", "WebDriver Initialized")
    except Exception as error:
        str_tools.printMsg ("Wdv ", "WebDriver initialization error : " + str(error))
        sys.exit(2)
    return driver
Ejemplo n.º 7
0
def parseTxt(file, tmpl):
    artist = ""
    title = ""
    cover = ""

    try:
        file = file.decode("utf-8")
        file = file.split('\n')
        tmpl = tmpl.split('\n')
    except:
        file = str(file.decode("latin1"))
        file = file.split('\n')
        tmpl = tmpl.split('\n')

    idxArtistLine = -1
    idxArtistIdx = -1
    idxTitleLine = -1
    idxTitleIdx = -1
    idxCoverLine = -1
    idxCoverIdx = -1

    lenArtistTag = len("$artist")
    lenTitleTag = len("$title")
    lenCoverTag = len("$cover")

    count = 0
    for line in tmpl:
        if ("$artist" in line):
            idxArtistLine = count
            idxArtistIdx = line.index("$artist")
        if ("$title" in line):
            idxTitleLine = count
            idxTitleIdx = line.index("title")
        if ("$cover" in line):
            idxCoverLine = count
            idxCoverIdx = line.index("cover")
        count = count + 1

    if (idxArtistLine == idxTitleLine):
        file[idxArtistLine] = file[idxArtistLine].strip("\r")
        file[idxArtistLine] = file[idxArtistLine].strip("\n")

        #Case where the artist tag is located on the same line that the title tag
        offset = idxTitleIdx - idxArtistIdx
        separator = ""
        eol = ""
        if (offset > 0):
            #Case where the artist tag is located before the title tag
            separator = tmpl[idxArtistLine][idxArtistIdx +
                                            lenArtistTag:idxTitleIdx - 1]
            eol = tmpl[idxArtistLine][idxTitleIdx + lenTitleTag - 1:]
        elif (offset < 0):
            #Case where the title tag is located before the artist tag
            separator = tmpl[idxTitleLine][idxTitleIdx + lenTitleTag -
                                           1:idxArtistIdx]
            eol = tmpl[idxTitleLine][idxArtistIdx + lenArtistTag:]

        lenSeparator = len(separator)
        lenEol = len(eol)
        idxFileSeparator = file[idxArtistLine].index(separator)

        if (offset > 0):
            artist = file[idxArtistLine][idxArtistIdx:idxFileSeparator]
            if (lenEol > 0):
                title = file[idxTitleLine][idxFileSeparator +
                                           lenSeparator:-lenEol]
            else:
                title = file[idxTitleLine][idxFileSeparator + lenSeparator:]
        elif (offset < 0):
            title = file[idxTitleLine][idxTitleIdx - 1:idxFileSeparator]
            if (lenEol > 0):
                artist = file[idxArtistLine][idxFileSeparator +
                                             lenSeparator:-lenEol]
            else:
                artist = file[idxArtistLine][idxFileSeparator + lenSeparator:]
    else:
        if (idxArtistLine != -1):
            if (len(tmpl[idxArtistLine]) != lenArtistTag):
                extraBe = tmpl[idxArtistLine].index("$artist")
                extraAf = len(tmpl[idxArtistLine]) - (
                    tmpl[idxArtistLine].index("$artist") + lenArtistTag)
                artist = file[idxArtistLine][extraBe:-extraAf]
                str_tools.printMsg("TXT ", "Artist value : '" + artist + "'")
            else:
                artist = file[idxArtistLine]
                str_tools.printMsg("TXT ", "Artist value : '" + artist + "'")
        if (idxTitleLine != -1):
            if (len(tmpl[idxTitleLine]) != lenTitleTag):
                extraBe = tmpl[idxTitleLine].index("$title")
                extraAf = len(tmpl[idxTitleLine]) - (
                    tmpl[idxTitleLine].index("$title") + lenTitleTag)
                title = file[idxTitleLine][extraBe:-extraAf]
                str_tools.printMsg("TXT ", "Title value : '" + title + "'")
            else:
                title = file[idxTitleLine]
                str_tools.printMsg("TXT ", "Title value : '" + title + "'")
        if (idxCoverLine != -1):
            if (len(tmpl[idxCoverLine]) != lenCoverTag):
                extraBe = tmpl[idxCoverLine].index("$cover")
                extraAf = len(tmpl[idxCoverLine]) - (
                    tmpl[idxCoverLine].index("$cover") + lenCoverTag)
                cover = file[idxCoverLine][extraBe:-extraAf]
                str_tools.printMsg("TXT ", "Cover value : '" + cover + "'")
            else:
                cover = file[idxCoverLine]
                str_tools.printMsg("TXT ", "Cover value : '" + cover + "'")

    if (artist == "" or title == "" or cover == ""):
        str_tools.printMsg("TXT ", "The following items aren't found :")
        if (artist == ""):
            str_tools.printMsg("TXT ", "$artist, ")
        if (title == ""):
            str_tools.printMsg("TXT ", "$title, ")
        if (cover == ""):
            str_tools.printMsg("TXT ", "$cover")
    return artist, title, cover
Ejemplo n.º 8
0
def generate(cfg=None, lastArtist="", lastTitle="", mode="standalone", artistFromServer="", titleFromServer="", coverFromServer=""):
    # Avoid SSL errors
    ssl._create_default_https_context = ssl._create_unverified_context

    # Parameters to generate SLS from the config file
    compAtc = -1
    try: 
        logo = cfg.get('general', 'logoUrl')
        color1 = cfg.get('general', 'color1')
        color2 = cfg.get('general', 'color2')
        backUrl = cfg.get('general', 'backUrl')
        theme = "themes/" + cfg.get('general', 'theme')
        radioName = cfg.get('general', 'radioName')
        slogan = cfg.get('general', 'slogan')
        outFolder = cfg.get('general', 'outFolder')
        try:
            compAtc = cfg.get('quality', 'atc')
            if(int(compAtc) < 0 or int(compAtc) > 100):
                str_tools.printMsg("ATC ", "The quality ratio setting is not correct. Provided " + str(compAtc) + "%. The value must be between 0-100%")
                compAtc = atcCompressionRatio    
        except:
            str_tools.printMsg("ATC ", "No quality ratio setting defined for ATC slides. Using default value: " + str(atcCompressionRatio) +"%")
            compAtc = atcCompressionRatio
    except configparser.NoOptionError as error:
        str_tools.printMsg("ATC ", "Mandatory parameter is missing : " + str(error))
        sys.exit(2)

    # Local Vars
    tempArtist = ""
    tempTitle = ""

    # Opening Template
    file = "" 
    cptFails = 0 # Count connection failures, exits the app when not reached for 5 times.

    # Checking connecion failures
    while True:
        try: 
            req = Request(cfg.get('source', 'url'), headers={'User-Agent': 'Mozilla/5.0'})
            file = urlopen(req).read()
            cptFails = 0
            break
        except Exception as ex: 
            cptFails = cptFails + 1
            if(cptFails < 5):
                str_tools.printMsg("ATC ", "[" + str(cptFails) + "/5] Failed to open source file ("+str(ex)+"). Retrying in 10secs...")
                time.sleep(10)
            else:
                str_tools.printMsg("ATC ", "[" + str(cptFails) + "/5] Failed 5 times to open source file. PadTool will exits...")
                sys.exit(2)
        
    # Parsing formalisms for $artist and $title tags
    artistForm = 0
    titleForm = 0
    try:
        artistForm = cfg.get('general','artistForm')
        if(artistForm == ""): 
            artistForm = 0
    except:
        artistForm = 0
    try:
        titleForm = cfg.get('general','titleForm')
        if(titleForm == ""): 
            titleForm = 0
    except:
        titleForm = 0

    tmpl = ""
    with open(cfg.get('source', 'template'), "r") as template:
        for line in template:
            tmpl = tmpl + line

    ret = []
    if(mode == "server"):
        ret = [artistFromServer, titleFromServer, coverFromServer]
    else:
        if (cfg.get('source','format') == "json"):
            ret = json_file.parseJson(file, tmpl)
        elif (cfg.get('source','format') == "xml"):
            ret = xml_file.parseXml(file,tmpl)
        elif (cfg.get('source','format') == "txt"):
            ret = txt_file.parseTxt(file,tmpl)

    artist = str_tools.formString(str(html.unescape(str(ret[0]))), int(artistForm)).strip()
    title  = str_tools.formString(str(html.unescape(str(ret[1]))), int(titleForm)).strip()
    cover  = html.unescape(str(ret[2]))

    if(artist == lastArtist and title == lastTitle):
        str_tools.printMsg("ATC ", "SLS/DLS already generated, passing...")
        return artist, title

    # Filters management for artist tag
    filterFound = False

    try:
        filterArtist = json.loads(cfg.get('filter', 'artist'))
        str_tools.printMsg("ATC ", "Filters defined for artist tag")

        for fart in filterArtist:
            if (str(fart) == artist):
                filterFound = True
                str_tools.printMsg ("ATC ", "Filter '" + str(fart) +"' found in artist tag")

            if(mode == "dabctl"):
                try:
                    tmpPath = "/tmp/PadTool-" + os.getpid()
                    if(os.path.isfile(tmpPath + "/music.jpg")):
                        str_tools.printMsg ("ATC " ,"Slide exists, deleting slide...")
                        os.remove(tmpPath + "/music.jpg")
                except:
                    str_tools.printMsg ("ATC ", "Slide removal error : " + str(ex))
            else:
                if(os.path.isfile(outFolder + "/music.jpg")):
                    os.remove(outFolder + "/music.jpg")
                    str_tools.printMsg ("ATC ", "SLS exists, deleting slide...")
                    # Create file REQUEST_SLIDES_DIR_REREAD
                    f = open( outFolder + '/REQUEST_SLIDES_DIR_REREAD', 'w' )
                    f.write("")
                    f.close()  
    except configparser.NoOptionError as error:
        str_tools.printMsg("ATC ", "No filters defined for artist tag, ignoring...")
    except configparser.NoSectionError as error:
        str_tools.printMsg("ATC ", "No filters defined for artist tag, ignoring...")
    except json.decoder.JSONDecodeError as ex:
        str_tools.printMsg("ATC ", "No filters defined for artist tag (bad format or empty), ignoring...")

    # Filters management for title tag
    try:
        filterTitle = json.loads(cfg.get('filter', 'title'))
        str_tools.printMsg("ATC ", "Filters defined for title tag")

        for ftit in filterTitle:
            if (str(ftit) == title):
                filterFound = True
                str_tools.printMsg ("ATC ", "Filter '" + str(ftit) + "' found in title tag")
                if(os.path.isfile(outFolder + "/music.jpg")):
                    str_tools.printMsg ("ATC ", "SLS exists, deleting slide...")
                    os.remove(outFolder + "/music.jpg")
                    # Create file REQUEST_SLIDES_DIR_REREAD
                    f = open( outFolder + '/REQUEST_SLIDES_DIR_REREAD', 'w' )
                    f.write("")
                    f.close() 
                break
    except configparser.NoOptionError as error:
        str_tools.printMsg("ATC ", "No filters defined for title tag, ignoring...")
    except configparser.NoSectionError as error:
        str_tools.printMsg("ATC ", "No filters defined for title tag, ignoring...")
    except json.decoder.JSONDecodeError as ex:
        str_tools.printMsg("ATC ", "No filters defined for title tag (bad format or empty), ignoring...")

    try:
        if(cfg.get('slides', 'music') == "1"):
            # Find the cover on CoverPy or Sacad
            coverPyEnabled = "0"
            coverPyFound = False

            try:
                coverPyEnabled = cfg.get('source', 'researchCover')
            except:
                pass
            
            albumFromCpy = ""
            # Search a cover via CoverPy if enabled
            if not cover and coverPyEnabled == "1":
                cpy = coverpy.CoverPy()
                try:
                    str_tools.printMsg ("ATC ", "No cover URL provided, using CoverPy to find one cover...")
                    result = cpy.get_cover(artist + " - " + title, 1)
                    cover = result.artwork(300)
                    albumFromCpy = result.album
                    coverPyFound = True
                    str_tools.printMsg ("ATC ", "Cover found using CoverPy : " + cover)
                except coverpy.exceptions.NoResultsException:
                    str_tools.printMsg ("ATC ", "No cover found using CoverPy")
                except:
                    str_tools.printMsg ("ATC ", "Error with CoverPy")

            # If no cover found via CoverPy, then call to Sacad to find a cover
            if not cover and coverPyEnabled == "1":
                try:
                    str_tools.printMsg ("ATC ", "Using Sacad to find a cover")
                    if(albumFromCpy == ""):
                        albumFromCpy = title
                    os.system("sacad \"" + artist + "\" \"" + albumFromCpy + "\" " + " 300 PadTool-Art-" + str(os.getpid()) + ".jpg -a fr")
                    with open("PadTool-Art-" + str(os.getpid()) + ".jpg", "rb") as image_file:
                        cover = "data:image/jpg;base64," + str(base64.b64encode(image_file.read()).decode())
                        if (os.path.isdir("PadTool-Art-" + str(os.getpid()) + ".jpg", "rb")):
                            shutil.rmtree("PadTool-Art-" + str(os.getpid()) + ".jpg", "rb")
                        coverPyFound = True
                    str_tools.printMsg("ATC ", "Cover found via Sacad")
                    time.sleep(1)
                except:
                    str_tools.printMsg ("ATC ", "Error with Sacad or cover not found")

            # Put default cover when no cover image provided (eg. logo of the radio station)
            if (not cover and coverPyFound == False) or filterFound == True:
                str_tools.printMsg ("ATC ", "Putting default cover as no URL has been provided or if a filter has been found")
                try:
                    cover = cfg.get('source','defaultCover')
                except configparser.NoOptionError as error:
                    str_tools.printMsg("ATC ", "Mandatory parameter is missing : " + str(error))
                    sys.exit(2)

            tempArtist = str(lastArtist).replace("...", "")
            tempTitle = str(lastTitle).replace("...", "")

            # Some APIs do not use http or https prefix, add http:// when it's the case
            if (len(cover) > 0):
                if("http" not in cover):
                    cover = str(cfg.get('general', 'prefix')) + cover
                    if(filterFound == True or (artist == "" and title == "")):
                        try:
                            contentDls = cfg.get('dls', 'defaultDls')
                        except:
                            contentDls = "$radioName, $slogan"
                        if(os.path.isfile(outFolder + "/music.jpg")):
                            os.remove(outFolder + "/music.jpg")
                    else:
                        contentDls = cfg.get('dls', 'text')

            # Data masking replacement with correct values
            content = ""
            with io.open(theme + '.html', 'r', encoding="utf-8") as f:
                content = f.read()
    except:
        pass    

    if (cfg.get('dls','enabled') == "1"):
        if((artist not in tempArtist and title not in tempTitle) or (artist == "" or title == "")):
            str_tools.printMsg ("ATC ", "Generating DLS...")
            if(filterFound == True or (artist == "" or title == "")):
                try:
                    contentDls = cfg.get('dls', 'defaultDls')
                except:
                    contentDls = "$radioName, $slogan"
                if(os.path.isfile(outFolder + "/music.jpg")):
                    os.remove(outFolder + "/music.jpg")
            else:
                contentDls = cfg.get('dls', 'text')

            lenDls       = len(contentDls)
            lenArtist    = len(str(artist))
            lenTitle     = len(str(title))
            lenRadioName = len(radioName)

            contentDls = contentDls.replace("$artist", artist)
            contentDls = contentDls.replace("$title", title)
            contentDls = contentDls.replace("$radioName", radioName)
            contentDls = contentDls.replace("$slogan", slogan)

            idxArtist    = -1
            idxTitle     = -1
            idxRadioName = -1

            if (artist in contentDls and artist != ""):
                idxArtist = contentDls.index(artist)
            if (title in contentDls and title != ""):
                idxTitle = contentDls.index(title)
            if (radioName in contentDls and radioName != ""):
                idxRadioName = contentDls.index(radioName)

            dlsPlusEnabled = "0"
            try:
                # Parsing option in the config file if the DLS+ is enabled or not.
                if(cfg.get('dls', 'dlsPlus') != "" and mode != "dabctl-ext"):
                    dlsPlusEnabled = cfg.get('dls', 'dlsPlus')
            except:
                dlsPlusEnabled = "0"

            if(dlsPlusEnabled == "1"):    
                dlPlus = "##### parameters { #####\nDL_PLUS=1\nDL_PLUS_ITEM_TOGGLE=0\nDL_PLUS_ITEM_RUNNING=1\n"
                
                if (idxRadioName != -1):
                    dlPlus = dlPlus + "DL_PLUS_TAG=32 " + str(idxRadioName) + " " + str(lenRadioName -1) + "\n"
                if (idxTitle != -1):
                    dlPlus = dlPlus + "DL_PLUS_TAG=1 " + str(idxTitle) + " " + str(lenTitle - 1) + "\n"
                if (idxArtist != -1):
                    dlPlus = dlPlus + "DL_PLUS_TAG=4 " + str(idxArtist) + " " + str(lenArtist - 1) + "\n"
                dlPlus = dlPlus + "##### parameters } #####"
            outDls = outFolder + '/dls.txt'
            try:
                # Parsing option in the config file if the DLS file should be generated in an other path.
                if(cfg.get('dls', 'outFile') != ""):
                    outDls = cfg.get('dls', 'outFile') 
            except:
                pass
            f = ""

            if(mode == "dabctl"):
                f = open("/tmp/PadTool-" + str(os.getpid()) + "/dls.txt", "w")
            else:
                f = open(outDls, 'w')

            if(dlsPlusEnabled == "1"):   
                f.write(dlPlus + "\n" + contentDls)
            else:
                f.write(contentDls)
            f.close()

            try:
                if(cfg.get('dls', 'outFile') != ""):
                    if(dlsPlusEnabled == "1"):
                        str_tools.printMsg ("ATC ", "DLS exported with DLS+ : '" + contentDls + "' at '" + outDls + "'")
                    else:
                        str_tools.printMsg ("ATC ", "DLS exported : '" + contentDls + "' at '" + outDls + "'")
            except:
                if(dlsPlusEnabled == "1"):   
                    str_tools.printMsg ("ATC ", "DLS exported with DLS+ : '" + contentDls + "' at '" + outFolder + "/dls.txt'")
                else:
                    str_tools.printMsg ("ATC ", "DLS exported : '" + contentDls + "' at '" + outDls + "'")

    # If a filter has been found, we don't generate any artist, title slide
    if(filterFound == True):
        return artist, title

    # If a there is no artist nor title, we don't generate any artist, title slide
    if(artist == "" or title == ""):
        return artist, title

    # If title and/or artist are too long to be displayed on a slide, we reduce them
    if(len(str(artist)) > 35):
        artist = str(artist)[0:35] + "..."
    if(len(str(title)) > 35):
        title = str(title)[0:35] + "..."

    try:
        if(cfg.get('slides', 'music') == "1"):
            if(mode != "dabctl"):
                if(artist == lastArtist and title == lastTitle):
                    str_tools.printMsg("ATC ", "SLS/DLS already generated, passing...")
                    return artist, title

            str_tools.printMsg ("ATC ", "Generating Slide...")

            # content = content.replace("$artist", str(artist.encode("utf-8").decode('unicode_escape')))
            # content = content.replace("$title", str(title.encode("utf-8").decode('unicode_escape')))
            content = content.replace("$artist", str_tools.formString(str(artist), int(artistForm)).strip())
            content = content.replace("$title", str_tools.formString(str(title), int(titleForm)).strip())
            content = content.replace("$color1", color1)
            content = content.replace("$color2", color2)
            content = content.replace("$backurl", backUrl)
            content = content.replace("$logo", logo)
            try:
                # respCover = urlopen(cover).getcode()
                req = Request(cover, headers={'User-Agent': 'Mozilla/5.0'})
                readCover = urlopen(req).read()
            except:
                cover = cfg.get('source','defaultCover')
            content = content.replace("$cover", cover)

            try: 
                if(mode == "dabctl"):
                    img_file.generateImg(content, "/tmp/PadTool-" + str(os.getpid()) + "/music", int(compAtc))
                    str_tools.printMsg ("ATC ", "Slide generated at : '" + "/tmp/PadTool-" + str(os.getpid()) + "/music.jpg' and will be copied to '" + outFolder + "/music.jpg'")
                else:
                    img_file.generateImg(content, outFolder + "/music", int(compAtc))
                    str_tools.printMsg ("ATC ", "Slide generated at : '" + outFolder + "/music.jpg' (ratio: " + str(compAtc)+"%)")
            except Exception as ex:
                str_tools.printMsg ("ATC ", "Slide generation error : " + str(ex))
            
            # Create file REQUEST_SLIDES_DIR_REREAD
            if(mode != "dabctl" or mode != "dabctl-ext"):
                f = open(outFolder + '/REQUEST_SLIDES_DIR_REREAD', 'w' )
                f.write("")
                f.close()  
    except:
        pass

    return artist, title
Ejemplo n.º 9
0
def generate(cfg):
    # Parameters to generate SLS from the config file
    compLogo = -1
    try:
        logo = cfg.get('general', 'logoUrl')
        colorl = cfg.get('general', 'colorl')
        mode = cfg.get('general', 'mode')
        outFolder = cfg.get('general', 'outFolder')
        try:
            compLogo = cfg.get('quality', 'logo')
            if(int(compLogo) < 0 or int(compLogo) > 100):
                str_tools.printMsg("Logo", "The quality ratio setting is not correct. Provided " + str(compLogo) + "%. The value must be between 0-100%")
                compLogo = logoCompressionRatio    
        except:
            str_tools.printMsg("Logo", "No quality ratio setting defined for Logo slides. Using default value: " + str(logoCompressionRatio) +"%")
            compLogo = logoCompressionRatio
    except configparser.NoOptionError as error:
        str_tools.printMsg("Logo", "Mandatory parameter is missing : " + str(error))
        sys.exit(2)

    # Checking connection failures
    while True:
        try: 
            req = Request(cfg.get('source', 'url'), headers={'User-Agent': 'Mozilla/5.0'})
            file = urlopen(logo).read()
            cptFails = 0
            break
        except Exception as ex: 
            cptFails = cptFails + 1
            if(cptFails < 5):
                str_tools.printMsg("Logo", "[" + str(cptFails) + "/5] Failed to open source file ("+str(ex)+"). Retrying in 10secs...")
                time.sleep(10)
            else:
                str_tools.printMsg("Logo", "[" + str(cptFails) + "/5] Failed 5 times to open source file. PadTool will exits...")
                sys.exit(2)

    str_tools.printMsg ("Logo", "Generating Slide...")

    # Data masking replacement with correct values
    content = """
        <html>
            <head>
                <style type="text/css">
                    body { margin:auto; background-color:$colorl; background:$colorl;}
                    .conteneur{ width: 315px; height: 235px; text-align: center; display: table-cell; vertical-align: middle; }
                    img { max-width: 300px; max-height: 220px; }
                </style>
            </head>
            
            <body> <div class="conteneur"> <img src="$logo" /> </div> </body>
            <end></end>
        </html>
    """

    content = content.replace("$logo", logo)
    content = content.replace("$colorl", colorl)

    try: 
        if(mode == "dabctl"):
            img_file.generateImg(content, "/tmp/PadTool-" + str(os.getpid()) + "/logo", int(compLogo))
            str_tools.printMsg ("Logo", "Slide generated at : '" + "/tmp/PadTool-" + str(os.getpid()) + "/logo.jpg' and will be copied to '" + outFolder + "/logo.jpg' (ratio: " + str(compAtc)+"%)")
        else:
            img_file.generateImg(content, outFolder + "/logo", int(compLogo))
            str_tools.printMsg ("Logo", "Slide generated at : '" + outFolder + "/logo.jpg' (ratio: " + str(compLogo)+"%)")
    except Exception as ex:
        str_tools.printMsg ("Logo", "Slide generation error : " + str(ex))
Ejemplo n.º 10
0
def parseXml(file, tmpl):
    artist = ""
    title = ""
    cover = ""

    xmlf = ET.XML(file)
    xmlt = ET.XML(tmpl)

    # Init temporary work values for listing xml values

    idxLine = 0
    idxArtist = idxTitle = idxCover = -1

    # Identification of where are the $artist, the $title and the $cover tags are in the tmpl file

    for v in xmlt.iter():
        if (v.text == "$artist"):
            idxArtist = idxLine
        elif (v.text == "$title"):
            idxTitle = idxLine
        elif (v.text == "$cover"):
            idxCover = idxLine
        if (idxArtist != -1 and idxTitle != -1 and idxCover != -1):
            break
        idxLine = idxLine + 1

    # Retrieving info from the xml file with the help of the template file

    idxLine = 0
    for v in xmlf.iter():
        if (idxLine == idxArtist):
            artist = v.text
            str_tools.printMsg(
                "XML ", "Found artist tag, item nb '" + str(idxLine) +
                "' with value : '" + artist + "'")
        elif (idxLine == idxTitle):
            title = v.text
            str_tools.printMsg(
                "XML ", "Found title tag, item nb '" + str(idxLine) +
                "' with value : '" + title + "'")
        elif (idxLine == idxCover):
            cover = v.text
            str_tools.printMsg(
                "XML ", "Found cover tag, item nb '" + str(idxLine) +
                "' with value : '" + cover + "'")
        if (artist != "" and title != "" and cover != ""):
            break
        idxLine = idxLine + 1

    if (artist == "" or title == "" or cover == ""):
        str_tools.printMsg("XML ", "The following items aren't found :")
        if (artist == ""):
            str_tools.printMsg("XML ", "$artist, ")
        if (title == ""):
            str_tools.printMsg("XML ", "$title, ")
        if (cover == ""):
            str_tools.printMsg("XML ", "$cover")
    return artist, title, cover
Ejemplo n.º 11
0
def initPlugins(pathCfg, cfg, mode, timer):
    title = None
    artist = None

    # Server Mode (or server enabled)
    try:
        port = cfg.get("server", "port")
        user = cfg.get("server", "user")
        password = cfg.get("server", "password")

        if (mode == "server" or port != ""):
            webServer = server.Server(cfg, port, user, password)
            webServer.start()
        str_tools.printMsg(
            "Web ",
            "PadTool HTTP Server enabled, listening on port " + str(port))
    except:
        pass

    # Standalone Mode Management
    if (cfg.get('slides', 'logo') == "1"):
        templateLogo.generate(cfg)
    time.sleep(1)

    # Regular execution
    totalTime = 0

    triggerHour = True
    triggerQuarterHour = True
    triggerHalfHour = True
    triggerTenMin = True
    triggerFiveMin = True

    listFilesDabCtlSls = []
    listFilesDabCtlDls = []
    indexSlsDabCtlLoop = 0
    indexDlsDabCtlLoop = 0

    while True:
        # Generating artist/title/cover slide (with DLS+ if selected) if mode is not "server"
        if (mode != "server"):
            artist, title = templateATC.generate(cfg, artist, title, mode)

        # Timer reset at 0 when we get to an a new hour / Trigger 1 hour
        if (datetime.datetime.now().minute == 0
                and datetime.datetime.now().second <= int(timer)
                and triggerHour == False):
            totalTime = 0
            triggerHour = True
        if (datetime.datetime.now().minute != 0):
            triggerHour = False

        # Trigger 30min
        if (datetime.datetime.now().minute == 30
                and datetime.datetime.now().second <= int(timer)
                and triggerHalfHour == False):
            triggerHalfHour = True
        if (datetime.datetime.now().minute != 30):
            triggerHalfHour = False

        # Trigger 15min
        if (datetime.datetime.now().minute % 15 == 0
                and datetime.datetime.now().second <= int(timer)
                and triggerQuarterHour == False):
            triggerQuarterHour = True
        if (datetime.datetime.now().minute % 15 != 0):
            triggerQuarterHour = False

        # Trigger 10min
        if (datetime.datetime.now().minute % 10 == 0
                and datetime.datetime.now().second <= int(timer)
                and triggerTenMin == False):
            triggerTenMin = True
        if (datetime.datetime.now().minute % 10 != 0):
            triggerTenMin = False

        # Trigger 5min
        if (datetime.datetime.now().minute % 5 == 0
                and datetime.datetime.now().second <= int(timer)
                and triggerFiveMin == False):
            triggerFiveMin = True
        if (datetime.datetime.now().minute % 5 != 0):
            triggerFiveMin = False

        if (totalTime == 0 or triggerHour == True):
            triggerHour = False
            try:
                # print("Trigger hour")
                _pluginsManagement1h.generate(os.path.abspath(pathCfg))
                _pluginsManagement30min.generate(os.path.abspath(pathCfg))
            except:
                pass
        if (totalTime == 0 or triggerHalfHour == True):
            triggerHalfHour = False
            try:
                # print("Trigger half hour")
                _pluginsManagement30min.generate(os.path.abspath(pathCfg))
            except:
                pass
        if (totalTime == 0 or triggerQuarterHour == True):
            triggerQuarterHour = False
            try:
                # print("Trigger quarter hour")
                _pluginsManagement15min.generate(os.path.abspath(pathCfg))
            except:
                pass
        if (totalTime == 0 or triggerTenMin == True):
            triggerTenMin = False
            try:
                # print("Trigger ten minutes")
                _pluginsManagement10min.generate(os.path.abspath(pathCfg))
            except Exception as ex:
                pass
        if (totalTime == 0 or triggerFiveMin == True):
            triggerFiveMin = False
            try:
                # print("Trigger five minutes")
                _pluginsManagement5min.generate(os.path.abspath(pathCfg))
            except:
                pass

        # DAB-CTL mode, call at first start when all slides are generated
        if ((mode == "dabctl" or mode == 'dabctl-ext') and totalTime == 0):
            try:
                outFolder = cfg.get('general', 'outFolder')
            except configparser.NoOptionError as error:
                str_tools.printMsg(
                    "Ext ", "Mandatory parameter is missing : " + str(error))
                sys.exit(2)

            if (mode == 'dabctl'):
                tempFolder = "/tmp/PadTool-" + str(os.getpid())
            elif (mode == "dabctl-ext"):
                tempFolder = outFolder

            try:
                if (os.path.isdir(tempFolder)):
                    listFilesDabCtlSls = [
                        os.path.basename(x)
                        for x in glob.glob(tempFolder + '/*.jpg')
                    ]
                    listFilesDabCtlDls = [
                        os.path.basename(x)
                        for x in glob.glob(tempFolder + '/*.txt')
                    ]
            except:
                str_tools.printMsg(
                    "Ext ", "Mandatory parameter is missing : " + str(error))
                sys.exit(2)

        # DAB-CTL, call each time in loop
        if (mode == "dabctl" or mode == "dabctl-ext"):
            try:
                if (len(listFilesDabCtlSls) != len(
                        glob.glob(tempFolder + '/*.jpg'))):
                    listFilesDabCtlSls = [
                        os.path.basename(x)
                        for x in glob.glob(tempFolder + '/*.jpg')
                    ]
            except:
                pass
            try:
                if (len(listFilesDabCtlDls != len(
                        glob.glob(tempFolder + '/*.txt')))):
                    listFilesDabCtlDls = [
                        os.path.basename(x)
                        for x in glob.glob(tempFolder + '/*.txt')
                    ]
            except:
                pass

            # Copy SLS
            if (mode == "dabctl"):
                outFolderFilesCount = -1
                timeoutCount = 0
                while (
                        outFolderFilesCount != 0
                ):  # Is the folder empty of jpgs ? If then, we push an image.
                    try:
                        outFolderFilesCount = len(
                            glob.glob(outFolder + '/*.jpg'))
                        # print("SLS directory not empty, waiting...")
                    except:
                        outFolderFilesCount = 0
                        # print("SLS directory empty, copying...")
                    time.sleep(1)
                    timeoutCount = timeoutCount + 1
                    if (timeoutCount >= 30):
                        # print("Timeout 30s !")
                        outFolderFilesCount = 0

            try:
                if (len(listFilesDabCtlSls) > 0):
                    # print ("Copy SLS index " + str(indexSlsDabCtlLoop) + " on " + str(len(listFilesDabCtlSls)))
                    if (mode == "dabctl"):
                        shutil.copyfile(
                            tempFolder + '/' +
                            listFilesDabCtlSls[indexSlsDabCtlLoop],
                            outFolder + '/' + os.path.basename(
                                listFilesDabCtlSls[indexSlsDabCtlLoop]))
                    elif (mode == "dabctl-ext"):
                        dabctlExtSend(
                            cfg, "SLS", outFolder + '/' + os.path.basename(
                                listFilesDabCtlSls[indexSlsDabCtlLoop]))
            except Exception as ex:
                pass

            # Copy DLS
            try:
                if (len(listFilesDabCtlDls) > 0):
                    # print ("Copy DLS index " + str(indexDlsDabCtlLoop) + " on " + str(len(listFilesDabCtlDls)))
                    if (mode == "dabctl"):
                        try:
                            outFile = cfg.get('dls', 'outFile')
                        except:
                            str_tools.printMsg(
                                "Ext ", "Mandatory parameter is missing : " +
                                str(error))
                            sys.exit(2)

                        shutil.copyfile(
                            tempFolder + '/' +
                            listFilesDabCtlDls[indexDlsDabCtlLoop], outFile)
                    elif (mode == "dabctl-ext"):
                        dabctlExtSend(
                            cfg, "DLS", outFolder + '/' + os.path.basename(
                                listFilesDabCtlDls[indexDlsDabCtlLoop]))
            except Exception as ex:
                pass

            indexSlsDabCtlLoop = indexSlsDabCtlLoop + 1
            indexDlsDabCtlLoop = indexDlsDabCtlLoop + 1
            if (indexSlsDabCtlLoop >= len(listFilesDabCtlSls)):
                indexSlsDabCtlLoop = 0
            if (indexDlsDabCtlLoop >= len(listFilesDabCtlDls)):
                indexDlsDabCtlLoop = 0

        totalTime = totalTime + int(timer)
        if (totalTime >= 3600):
            totalTime = 1
        time.sleep(int(timer))