示例#1
0
def play_track(id: int, seconds: int, time: int):
    track = db.get(id)
    while seconds > 5:
        track.timesplayed += 1
        track.lastplayed = time

        if seconds > (track.length / 2) and get_settings("MALOJA_SCROBBLE"):

            starttime = time - seconds
            endtime = starttime + min(track.length, seconds)

            server = get_settings("MALOJA_SERVER")
            key = get_settings("MALOJA_KEY")
            url = server + "/api/newscrobble"
            data = {
                "artist": "/".join(a.name for a in track.artists),
                "title": track.title,
                "duration": max(seconds, track.length),
                "time": endtime,
                "key": key
            }

            requests.post(url, data=data)

        seconds -= track.length
示例#2
0
def send_stats():
    if settings.get_settings("SEND_STATS"):

        log("Sending daily stats report...")

        from .database import ARTISTS, TRACKS, SCROBBLES

        keys = {
            "url":
            "https://myrcella.krateng.ch/malojastats",
            "method":
            "POST",
            "headers": {
                "Content-Type": "application/json"
            },
            "data":
            json.dumps({
                "name": settings.get_settings("NAME"),
                "url": settings.get_settings("PUBLIC_URL"),
                "version": ".".join(str(d) for d in version),
                "artists": len(ARTISTS),
                "tracks": len(TRACKS),
                "scrobbles": len(SCROBBLES)
            }).encode("utf-8")
        }
        try:
            req = urllib.request.Request(**keys)
            response = urllib.request.urlopen(req)
            log("Sent daily report!")
        except:
            log("Could not send daily report!")
示例#3
0
def instructions(keys):
    authenticated = False
    if "Cookie" in request.headers:
        cookies = request.headers["Cookie"].split(";")
        for c in cookies:
            if c.strip().startswith("apikey="):
                authenticated = checkAPIkey(c.strip()[7:])

    if "token" in keys and authenticated:
        token = keys.get("token")
        parameters = {
            "method": "auth.getSession",
            "token": token,
            "api_key": get_settings("LASTFM_API_KEY")
        }
        response = urllib.request.urlopen(
            "http://ws.audioscrobbler.com/2.0/?" + lfmbuild(parameters))
        xml = response.read()
        data = ET.fromstring(xml)
        if data.attrib.get("status") == "ok":
            username = data.find("session").find("name").text
            sessionkey = data.find("session").find("key").text

            update_settings("settings/settings.ini", {
                "LASTFM_API_SK": sessionkey,
                "LASTFM_USERNAME": username
            },
                            create_new=True)

        return "/proxy"

    else:
        key, secret, sessionkey, name = get_settings("LASTFM_API_KEY",
                                                     "LASTFM_API_SECRET",
                                                     "LASTFM_API_SK",
                                                     "LASTFM_USERNAME")

        if key is None:
            lastfm = "<td>No Last.fm key provided</td>"
        elif secret is None:
            lastfm = "<td>No Last.fm secret provided</td>"
        elif sessionkey is None and authenticated:
            url = "http://www.last.fm/api/auth/?api_key=" + key + "&cb="
            lastfm = "<td class='button'><a id='lastfmlink' href='" + url + "'><div>Connect</div></a></td>"
        elif sessionkey is None:
            lastfm = "<td>Not active</td>"
        else:

            lastfm = "<td>Account: " + name + "</td>"

    return {"KEY_STATUS_LASTFM": lastfm}, []
示例#4
0
def start():
    setup()
    try:
        p = subprocess.Popen(["python3", "-m", "maloja.server"],
                             stdout=subprocess.DEVNULL,
                             stderr=subprocess.DEVNULL)
        sp = subprocess.Popen(["python3", "-m", "maloja.supervisor"],
                              stdout=subprocess.DEVNULL,
                              stderr=subprocess.DEVNULL)
        print(col["green"]("Maloja started!") + " PID: " + str(p.pid))

        from doreah import settings
        port = settings.get_settings("WEB_PORT")

        print("Visit your server address (Port " + str(port) +
              ") to see your web interface. Visit /setup to get started.")
        print(
            "If you're installing this on your local machine, these links should get you there:"
        )
        print("\t" + col["blue"]("http://localhost:" + str(port)))
        print("\t" + col["blue"]("http://localhost:" + str(port) + "/setup"))
        return True
    except:
        print("Error while starting Maloja.")
        return False
示例#5
0
def trackInfo(track):
    charts = db_aggregate(by="TRACK")
    #scrobbles = len(db_query(artists=artists,title=title))	#chart entry of track always has right scrobble number, no countas rules here
    #c = [e for e in charts if set(e["track"]["artists"]) == set(artists) and e["track"]["title"] == title][0]
    c = [e for e in charts if e["track"] == track][0]
    scrobbles = c["scrobbles"]
    position = c["rank"]
    cert = None
    threshold_gold, threshold_platinum, threshold_diamond = settings.get_settings(
        "SCROBBLES_GOLD", "SCROBBLES_PLATINUM", "SCROBBLES_DIAMOND")
    if scrobbles >= threshold_diamond: cert = "diamond"
    elif scrobbles >= threshold_platinum: cert = "platinum"
    elif scrobbles >= threshold_gold: cert = "gold"

    return {
        "scrobbles":
        scrobbles,
        "position":
        position,
        "medals":
        MEDALS_TRACKS.get((frozenset(track["artists"]), track["title"])),
        "certification":
        cert,
        "topweeks":
        WEEKLY_TOPTRACKS.get(((frozenset(track["artists"]), track["title"])),
                             0)
    }
示例#6
0
def trackSearchLink(track):
	searchProvider = get_settings("TRACK_SEARCH_PROVIDER")
	if searchProvider is None: return ""

	link = "<a class='trackProviderSearch' href='"
	if searchProvider == "YouTube":
		link += "https://www.youtube.com/results?search_query="
	elif searchProvider == "YouTube Music":
		link += "https://music.youtube.com/search?q="
	elif searchProvider == "Google Play Music":
		link += "https://play.google.com/music/listen#/srs/"
	elif searchProvider == "Spotify":
		link += "https://open.spotify.com/search/results/"
	elif searchProvider == "Tidal":
		link += "https://listen.tidal.com/search/tracks?q="
	elif searchProvider == "SoundCloud":
		link += "https://soundcloud.com/search?q="
	elif searchProvider == "Amazon Music":
		link += "https://music.amazon.com/search/"
	elif searchProvider == "Deezer":
		link += "https://www.deezer.com/search/"
	else:
		link += "https://www.google.com/search?q=" # ¯\_(ツ)_/¯

	link += urllib.parse.quote(", ".join(track["artists"]) + " " + track["title"]) + "'>&#127925;</a>"
	return link
示例#7
0
def static_html(name):
    if name in aliases: redirect(aliases[name])
    linkheaders = ["</style.css>; rel=preload; as=style"]
    keys = remove_identical(FormsDict.decode(request.query))

    adminmode = request.cookies.get("adminmode") == "true" and auth.check(
        request)

    clock = Clock()
    clock.start()

    LOCAL_CONTEXT = {
        "adminmode": adminmode,
        "apikey": request.cookies.get("apikey") if adminmode else None,
        "_urikeys": keys,  #temporary!
    }
    lc = LOCAL_CONTEXT
    lc["filterkeys"], lc["limitkeys"], lc["delimitkeys"], lc["amountkeys"], lc[
        "specialkeys"] = uri_to_internal(keys)

    template = jinja_environment.get_template(name + '.jinja')
    try:
        res = template.render(**LOCAL_CONTEXT)
    except ValueError as e:
        abort(404, "Entity does not exist")

    if settings.get_settings("DEV_MODE"): jinja_environment.cache.clear()

    log("Generated page {name} in {time:.5f}s".format(name=name,
                                                      time=clock.stop()),
        module="debug_performance")
    return clean_html(res)
示例#8
0
def lfmbuild(parameters):
    m = hashlib.md5()
    keys = sorted(str(k) for k in parameters)
    m.update(utf("".join(str(k) + str(parameters[k]) for k in keys)))
    m.update(utf(get_settings("LASTFM_API_SECRET")))
    sig = m.hexdigest()
    return urllib.parse.urlencode(parameters) + "&api_sig=" + sig
示例#9
0
def getArtistImage(artist, fast=False):

    #	obj = artist
    #	filename = re.sub("[^a-zA-Z0-9]","",artist)
    #	if filename == "": filename = str(hash(obj))
    #	filepath = "images/artists/" + filename
    #	#filepath_cache = "info/artists_cache/" + filename

    if settings.get_settings("USE_LOCAL_IMAGES"):

        try:
            return local_artist_cache.get(artist)
        except:
            images = local_files(artist=artist)
            if len(images) != 0:
                #return random.choice(images)
                res = random.choice(images)
                local_artist_cache.add(artist, res)
                return urllib.parse.quote(res)

    # check if custom image exists
#	if os.path.exists(filepath + ".png"):
#		imgurl = "/" + filepath + ".png"
#		return imgurl
#	elif os.path.exists(filepath + ".jpg"):
#		imgurl = "/" + filepath + ".jpg"
#		return imgurl
#	elif os.path.exists(filepath + ".jpeg"):
#		imgurl = "/" + filepath + ".jpeg"
#		return imgurl
#	elif os.path.exists(filepath + ".gif"):
#		imgurl = "/" + filepath + ".gif"
#		return imgurl

    try:
        #result = cachedArtists[artist]
        result = artist_cache.get(artist)  #artist_from_cache(artist)
        if result is not None: return result
        else: return ""
    except:
        pass

    # do we have an api key?


#	apikey = settings.get_settings("LASTFM_API_KEY")
#	if apikey is None: return "" # DO NOT CACHE THAT

# fast request only retuns cached and local results, generates redirect link for rest
    if fast: return "/image?artist=" + urllib.parse.quote(artist)

    # non-fast lookup (esentially only the resolver lookup)
    result = api_request_artist(artist=artist)

    # cache results (even negative ones)
    #cachedArtists[artist] = result
    artist_cache.add(artist, result)  #cache_artist(artist,result)

    if result is not None: return result
    else: return ""
示例#10
0
def instructions(keys):
	from ..utilities import getArtistImage, getTrackImage
	from ..htmlgenerators import artistLink
	from ..urihandler import compose_querystring, uri_to_internal
	from ..htmlmodules import module_trackcharts, module_filterselection, module_trackcharts_tiles
	from ..malojatime import range_desc
	from doreah.settings import get_settings

	filterkeys, timekeys, _, amountkeys = uri_to_internal(keys)

	if len(filterkeys) == 0:
		toptrackslink = "<a href='/top_tracks'><span>View #1 Tracks</span></a>"
	else:
		toptrackslink = ""


	limitstring = ""

	html_filterselector = module_filterselection(keys)

	html_charts, rep = module_trackcharts(**amountkeys,**timekeys,**filterkeys)



	html_tiles = ""

	if filterkeys.get("artist") is not None:
		imgurl = getArtistImage(filterkeys.get("artist"))
		limitstring = "by " + artistLink(filterkeys.get("artist"))
	elif rep is not None:
		imgurl = getTrackImage(rep["artists"],rep["title"])
	else:
		imgurl = ""

	html_tiles = ""
	if get_settings("CHARTS_DISPLAY_TILES"):
		html_tiles = module_trackcharts_tiles(timerange=timekeys["timerange"])
		imgurl = "favicon.png"

	imgdiv = '<div style="background-image:url('+imgurl+')"></div>'



	limitstring += " " + timekeys["timerange"].desc(prefix=True)

	pushresources = [{"file":imgurl,"type":"image"}] if imgurl.startswith("/") else []



	replace = {
		"KEY_TOPARTIST_IMAGEDIV":imgdiv,
		"KEY_TRACKCHART":html_tiles,
		"KEY_TRACKLIST":html_charts,
		"KEY_LIMITS":limitstring,
		"KEY_FILTERSELECTOR":html_filterselector,
		"TOP_TRACKS_LINK":toptrackslink,
	}

	return (replace,pushresources)
示例#11
0
 def __init__(self):
     # populate from settings file once on creation
     # avoid constant disk access, restart on adding services is acceptable
     for key in self.settings:
         self.settings[key] = get_settings(self.settings[key])
     try:
         self.authorize()
     except:
         pass
示例#12
0
def refresh_metadata(audio_ids=None):
    if audio_ids is None:
        audios = db.getall(Audio)
    else:
        audios = [db.get(id) for id in audio_ids]

    dirs = get_settings("MUSIC_DIRECTORIES")
    trees = scan(dirs)
    build_metadata(audios, trees)
示例#13
0
def getTrackImage(artists, title, fast=False):

    if settings.get_settings("USE_LOCAL_IMAGES"):

        try:
            return local_track_cache.get((frozenset(artists), title))
        except:
            images = local_files(artists=artists, title=title)
            if len(images) != 0:
                #return random.choice(images)
                res = random.choice(images)
                local_track_cache.add((frozenset(artists), title), res)
                return urllib.parse.quote(res)

    try:
        # check our cache
        # if we have cached the nonexistence of that image, we immediately return the redirect to the artist and let the resolver handle it
        # (even if we're not in a fast lookup right now)
        #result = cachedTracks[(frozenset(artists),title)]
        result = track_cache.get(
            (frozenset(artists), title))  #track_from_cache(artists,title)
        if result is not None: return result
        else:
            for a in artists:
                res = getArtistImage(artist=a, fast=True)
                if res != "": return res
            return ""
    except:
        pass

    # do we have an api key?


#	apikey = settings.get_settings("LASTFM_API_KEY")
#	if apikey is None: return "" # DO NOT CACHE THAT

# fast request only retuns cached and local results, generates redirect link for rest
    if fast:
        return "/image?title=" + urllib.parse.quote(title) + "&" + "&".join(
            ["artist=" + urllib.parse.quote(a) for a in artists])

    # non-fast lookup (esentially only the resolver lookup)
    result = api_request_track((artists, title))

    # cache results (even negative ones)
    #cachedTracks[(frozenset(artists),title)] = result
    track_cache.add((frozenset(artists), title),
                    result)  #cache_track(artists,title,result)

    # return either result or redirect to artist
    if result is not None: return result
    else:
        for a in artists:
            res = getArtistImage(artist=a, fast=False)
            if res != "": return res
        return ""
示例#14
0
def server_info():

    response.set_header("Access-Control-Allow-Origin", "*")
    response.set_header("Content-Type", "application/json")

    return {
        "name": settings.get_settings("NAME"),
        "version": version,
        "versionstring": ".".join(str(n) for n in version)
    }
示例#15
0
	def parseArtists(self,a):

		if isinstance(a,list):
			res = [self.parseArtists(art) for art in a]
			return [a for group in res for a in group]

		if a.strip() in settings.get_settings("INVALID_ARTISTS"):
			return []

		if a.strip().lower() in self.rules_ignoreartist:
			return []

		if a.strip() == "":
			return []

		if a.strip() in self.rules_notanartist:
			return []

		if " performing " in a.lower():
			return self.parseArtists(re.split(" [Pp]erforming",a)[0])

		if a.strip() in self.rules_belongtogether:
			return [a.strip()]
		if a.strip().lower() in self.rules_replaceartist:
			return self.rules_replaceartist[a.strip().lower()].split("␟")



		for d in self.delimiters_feat:
			if re.match(r"(.*) \(" + d + " (.*)\)",a) is not None:
				return self.parseArtists(re.sub(r"(.*) \(" + d + " (.*)\)",r"\1",a)) + \
						self.parseArtists(re.sub(r"(.*) \(" + d + " (.*)\)",r"\2",a))



		for d in (self.delimiters_feat + self.delimiters):
			if ((" " + d + " ") in a):
				ls = []
				for i in a.split(" " + d + " "):
					ls += self.parseArtists(i)
				return ls

		for d in self.delimiters_formal:
			if (d in a):
				ls = []
				for i in a.split(d):
					ls += self.parseArtists(i)
				return ls





		return [a.strip()]
示例#16
0
文件: database.py 项目: FoxxMD/maloja
def info():
	totalscrobbles = get_scrobbles_num()
	artists = {}

	return {
		"name":settings.get_settings("NAME"),
		"artists":{
			chartentry["artist"]:round(chartentry["scrobbles"] * 100 / totalscrobbles,3)
			for chartentry in get_charts_artists() if chartentry["scrobbles"]/totalscrobbles >= 0
		},
		"known_servers":list(KNOWN_SERVERS)
	}
示例#17
0
def post_endpoint(endpoint):

    data = request.json
    log("Received request to endpoint " + endpoint)
    try:
        cls = db._getclassbyname(endpoint)
        log("Mapped to class " + str(cls))
    except:
        log("Does not exist!")
        return 404

    # instantiate a new object of this class
    if settings.get_settings("ACCEPT_STATS"):
        cls(**data)
        db.save()
    else:
        log("Not accepting any stats right now.")
示例#18
0
def getArtistImage(artist, fast=False):

    if settings.get_settings("USE_LOCAL_IMAGES"):

        try:
            return thumborize(local_artist_cache.get(artist))
            # Local cached image
        except:
            # Get all local images, select one if present
            images = local_files(artist=artist)
            if len(images) != 0:
                #return random.choice(images)
                res = random.choice(images)
                local_artist_cache.add(artist, res)
                return thumborize(urllib.parse.quote(res))

    # if no local images (or setting to not use them)
    try:
        # check cache for foreign image
        result = artist_cache.get(artist)
        if result is not None: return thumborize(result)
        else: return ""
        # none means non-existence is cached, return empty
    except:
        pass
        # no cache entry, go on

    # do we have an api key?


#	apikey = settings.get_settings("LASTFM_API_KEY")
#	if apikey is None: return "" # DO NOT CACHE THAT

# fast request only retuns cached and local results, generates redirect link for rest
    if fast: return "/image?artist=" + urllib.parse.quote(artist)

    # non-fast lookup (esentially only the resolver lookup)
    result = api_request_artist(artist=artist)

    # cache results (even negative ones)
    #cachedArtists[artist] = result
    artist_cache.add(artist, result)  #cache_artist(artist,result)

    if result is not None: return thumborize(result)
    else: return ""
示例#19
0
    def parseTitle(self, t):
        if t.strip().lower() in self.rules_replacetitle:
            return self.rules_replacetitle[t.strip().lower()]

        t = t.replace("[", "(").replace("]", ")")

        t = re.sub(r" \(as made famous by .*?\)", "", t)
        t = re.sub(r" \(originally by .*?\)", "", t)
        t = re.sub(r" \(.*?Remaster.*?\)", "", t)

        for s in settings.get_settings("REMOVE_FROM_TITLE"):
            if s in t:
                t = t.replace(s, "")

        t = t.strip()
        #for p in self.plugin_titleparsers:
        #	t = p(t).strip()
        return t
示例#20
0
def start():
	if getInstanceSupervisor() is not None:
		print("Maloja is already running.")
	else:
		setup()
		try:
			#p = subprocess.Popen(["python3","-m","maloja.server"],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
			sp = subprocess.Popen(["python3","-m","maloja.proccontrol.supervisor"],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
			print(col["green"]("Maloja started!"))

			port = settings.get_settings("WEB_PORT")

			print("Visit your server address (Port " + str(port) + ") to see your web interface. Visit /setup to get started.")
			print("If you're installing this on your local machine, these links should get you there:")
			print("\t" + col["blue"]("http://localhost:" + str(port)))
			print("\t" + col["blue"]("http://localhost:" + str(port) + "/setup"))
			return True
		except:
			print("Error while starting Maloja.")
			return False
示例#21
0
def subsonicauth(request):

    try:
        token = request.query.get("t")
        salt = request.query.get("s")

        key = settings.get_settings("SUBSONIC_KEY")

        m = hashlib.md5()
        m.update(key.encode())
        m.update(salt.encode())

        if m.hexdigest() == token:
            #			print("Success!")
            return True

        assert False
    except:
        raise
        return False
示例#22
0
def instructions(keys):
    from ..utilities import getArtistImage
    from ..urihandler import compose_querystring, uri_to_internal
    from ..htmlmodules import module_artistcharts, module_filterselection, module_artistcharts_tiles
    from ..malojatime import range_desc
    from doreah.settings import get_settings

    _, timekeys, _, amountkeys = uri_to_internal(keys)

    limitstring = timekeys["timerange"].desc(prefix=True)

    html_filterselector = module_filterselection(keys)

    html_charts, rep = module_artistcharts(**amountkeys, **timekeys)

    if rep is not None:
        imgurl = getArtistImage(rep)
    else:
        imgurl = ""

    html_tiles = ""
    if get_settings("CHARTS_DISPLAY_TILES"):
        html_tiles = module_artistcharts_tiles(timerange=timekeys["timerange"])
        imgurl = "favicon.png"

    imgdiv = '<div style="background-image:url(' + imgurl + ')"></div>'

    pushresources = [{
        "file": imgurl,
        "type": "image"
    }] if imgurl.startswith("/") else []

    replace = {
        "KEY_TOPARTIST_IMAGEDIV": imgdiv,
        "KEY_ARTISTCHART": html_tiles,
        "KEY_ARTISTLIST": html_charts,
        "KEY_RANGE": limitstring,
        "KEY_FILTERSELECTOR": html_filterselector
    }

    return (replace, pushresources)
示例#23
0
def get_scrobbles(tracks):

    tracks = {(frozenset(a.name.lower()
                         for a in t.artists), t.title.lower()): t
              for t in tracks}
    matched_tracks = {}

    malserver = get_settings("MALOJA_SERVER")
    if malserver is None:
        malserver = input("Please enter the URL of your Maloja server: ")

    # list of tracks
    url = malserver + "/api/tracks"
    result = requests.get(url)
    result = result.json()["list"]
    for r in result:
        tr = (frozenset(a.lower() for a in r["artists"]), r["title"].lower())
        if tr in tracks:
            matched_tracks[tracks[tr]] = r

    #print(matched_tracks)

    url = malserver + "/api/trackinfo"
    i = 0
    tracknumber = len(matched_tracks)
    for t in matched_tracks:
        i += 1
        trackinfo = matched_tracks[t]
        info = []
        for a in trackinfo["artists"]:
            info.append(("artist", a))
        info.append(("title", trackinfo["title"]))
        #	trackurl = url + "?" + "&".join(["artist=" + a for a in trackinfo["artists"]]) + "&title=" + trackinfo["title"]
        trackurl = url + "?" + urllib.parse.urlencode(info)
        #	print("Making request",trackurl)
        result = requests.get(trackurl)
        result = result.json()
        #print(t,"has",result["scrobbles"],"scrobbles")
        print_progress_bar(num=(i, tracknumber), prefix="Importing scrobbles ")
        t.timesplayed = result["scrobbles"]
示例#24
0
文件: scanner.py 项目: krateng/albula
def scan_dir(dir, progressbar):
    d = Directory(name=dir.split("/")[-1])

    dirlist = os.listdir(dir)
    progressbar.godeeper(len(dirlist))
    for f in dirlist:
        fullpath = os.path.join(dir, f)

        if f in get_settings("IGNORE_FILES"):
            break
        if f.startswith("."):
            progressbar.progress(step=f)
            continue
        if os.path.isdir(fullpath):
            d.subdirs.append(scan_dir(fullpath, progressbar))
        else:
            ext = f.split(".")[-1].lower()
            if ext in AUDIOFORMATS: d.add_file(Audio(path=fullpath))
            elif ext in IMAGEFORMATS: d.add_file(Artwork(path=fullpath))
            elif f in ["artist.yml", "artist.yaml"]:
                with open(fullpath, "r") as fil:
                    #files.append({**yaml.safe_load(fil),"type":"artist"})
                    info = yaml.safe_load(fil)
                    d.artist = Artist(name=info["name"])
            elif f in ["album.yml", "album.yaml"]:
                with open(fullpath, "r") as fil:
                    #files.append({**yaml.safe_load(fil),"type":"album"})
                    info = yaml.safe_load(fil)
                    d.album = Album(name=info["name"],
                                    albumartists=[
                                        Artist(name=a)
                                        for a in info["albumartists"]
                                    ])

            #else: print("File",f,"has unknown format")
            progressbar.progress(step=f)

    progressbar.done()
    return d
示例#25
0
文件: auth.py 项目: krateng/aservmr
def validate_challenge(challenge,response):
	update()
	lock.acquire()
	if challenge not in [challenge_current, challenge_old]:
		lock.release()
		print("Invalid challenge")
		return False

	pub = str(get_settings("PUBLIC_KEY"))

	if combine(pub,challenge) == combine(response,COMMON):
		# invalidate challenges
		stop_issue = 0
		expire = 0
		update()

		lock.release()
		return True

	else:
		print("Invalid response")
		lock.release()
		return False
示例#26
0
文件: scanner.py 项目: krateng/albula
def scan(dirs):
    old_audiofiles = db.getall(Audio)
    for a in old_audiofiles:
        if not os.path.exists(a.path):
            a.track.audiofiles.remove(a)
            db.delete(a)

    scan_dir_prog = NestedProgressBar(len(dirs),
                                      prefix="Scanning directories",
                                      manual=True)
    trees = []
    new_audiofiles = []
    for dir in dirs:
        d = scan_dir(dir, progressbar=scan_dir_prog)
        trees.append(d)

    new_audiofiles = [a for a in db.getall(Audio) if a not in old_audiofiles]

    old_tracks = db.getall(Track)

    #when scanning, also call metadata refresher for newly added files
    from ..dbbuild.parser import build_metadata
    build_metadata(new_audiofiles, trees)

    new_tracks = [t for t in db.getall(Track) if t not in old_tracks]

    # import maloja data for new tracks
    malserver = get_settings("MALOJA_SERVER")
    if malserver is not None:
        from ..dbbuild.malojareader import get_scrobbles
        get_scrobbles(new_tracks)

    from ..dbbuild.pruner import prune_database
    prune_database()

    return trees
示例#27
0
def static_html(name):
    linkheaders = ["</style.css>; rel=preload; as=style"]
    keys = remove_identical(FormsDict.decode(request.query))

    pyhp_file = os.path.exists(pthjoin(WEBFOLDER, "pyhp", name + ".pyhp"))
    html_file = os.path.exists(pthjoin(WEBFOLDER, name + ".html"))
    jinja_file = os.path.exists(pthjoin(WEBFOLDER, "jinja", name + ".jinja"))
    pyhp_pref = settings.get_settings("USE_PYHP")
    jinja_pref = settings.get_settings("USE_JINJA")

    adminmode = request.cookies.get(
        "adminmode") == "true" and database.checkAPIkey(
            request.cookies.get("apikey")) is not False

    clock = Clock()
    clock.start()

    # if a jinja file exists, use this
    if (jinja_file and jinja_pref) or (jinja_file and not html_file
                                       and not pyhp_file):
        LOCAL_CONTEXT = {
            "adminmode": adminmode,
            "apikey": request.cookies.get("apikey") if adminmode else None,
            "_urikeys": keys,  #temporary!
        }
        LOCAL_CONTEXT["filterkeys"], LOCAL_CONTEXT["limitkeys"], LOCAL_CONTEXT[
            "delimitkeys"], LOCAL_CONTEXT["amountkeys"] = uri_to_internal(keys)

        template = jinjaenv.get_template(name + '.jinja')

        res = template.render(**LOCAL_CONTEXT)
        log("Generated page {name} in {time:.5f}s (Jinja)".format(
            name=name, time=clock.stop()),
            module="debug")
        return res

    # if a pyhp file exists, use this
    elif (pyhp_file and pyhp_pref) or (pyhp_file and not html_file):

        #things we expose to the pyhp pages
        environ = {
            "adminmode": adminmode,
            "apikey": request.cookies.get("apikey") if adminmode else None,
            # maloja
            "db": database,
            "htmlmodules": htmlmodules,
            "htmlgenerators": htmlgenerators,
            "malojatime": malojatime,
            "utilities": utilities,
            "urihandler": urihandler,
            "settings": settings.get_settings,
            # external
            "urllib": urllib
        }
        # request
        environ["filterkeys"], environ["limitkeys"], environ[
            "delimitkeys"], environ["amountkeys"] = uri_to_internal(keys)
        environ["_urikeys"] = keys  #temporary!

        #response.set_header("Content-Type","application/xhtml+xml")
        res = pyhpfile(pthjoin(WEBFOLDER, "pyhp", name + ".pyhp"), environ)
        log("Generated page {name} in {time:.5f}s (PYHP)".format(
            name=name, time=clock.stop()),
            module="debug")
        return res

    # if not, use the old way
    else:

        with open(pthjoin(WEBFOLDER, name + ".html")) as htmlfile:
            html = htmlfile.read()

        # apply global substitutions
        with open(pthjoin(WEBFOLDER, "common/footer.html")) as footerfile:
            footerhtml = footerfile.read()
        with open(pthjoin(WEBFOLDER, "common/header.html")) as headerfile:
            headerhtml = headerfile.read()
        html = html.replace("</body>", footerhtml + "</body>").replace(
            "</head>", headerhtml + "</head>")

        # If a python file exists, it provides the replacement dict for the html file
        if os.path.exists(pthjoin(WEBFOLDER, name + ".py")):
            #txt_keys = SourceFileLoader(name,"web/" + name + ".py").load_module().replacedict(keys,DATABASE_PORT)
            try:
                module = importlib.import_module(".web." + name,
                                                 package="maloja")
                txt_keys, resources = module.instructions(keys)
            except Exception as e:
                log("Error in website generation: " + str(sys.exc_info()),
                    module="error")
                raise

            # add headers for server push
            for resource in resources:
                if all(ord(c) < 128 for c in resource["file"]):
                    # we can only put ascii stuff in the http header
                    linkheaders.append("<" + resource["file"] +
                                       ">; rel=preload; as=" +
                                       resource["type"])

            # apply key substitutions
            for k in txt_keys:
                if isinstance(txt_keys[k], list):
                    # if list, we replace each occurence with the next item
                    for element in txt_keys[k]:
                        html = html.replace(k, element, 1)
                else:
                    html = html.replace(k, txt_keys[k])

        response.set_header("Link", ",".join(linkheaders))
        log("Generated page {name} in {time:.5f}s (Python+HTML)".format(
            name=name, time=clock.stop()),
            module="debug")
        return html
示例#28
0
# technical
#from importlib.machinery import SourceFileLoader
import importlib
import _thread
import sys
import signal
import os
import setproctitle
import pkg_resources
import math
# url handling
import urllib

#settings.config(files=["settings/default.ini","settings/settings.ini"])
#settings.update("settings/default.ini","settings/settings.ini")
MAIN_PORT = settings.get_settings("WEB_PORT")
HOST = settings.get_settings("HOST")
THREADS = 24
BaseRequest.MEMFILE_MAX = 15 * 1024 * 1024

WEBFOLDER = pkg_resources.resource_filename(__name__, "web")
STATICFOLDER = pkg_resources.resource_filename(__name__, "static")
DATAFOLDER = DATA_DIR

webserver = Bottle()

pthjoin = os.path.join


def generate_css():
    import lesscpy
示例#29
0
import urllib.parse, urllib.request
import json
import base64
from doreah.settings import get_settings
from doreah.logging import log
import hashlib
import xml.etree.ElementTree as ET

### PICTURES

apis_artists = []

if get_settings("LASTFM_API_KEY") not in [
        None, "ASK"
] and get_settings("FANARTTV_API_KEY") not in [None, "ASK"]:
    apis_artists.append({
        "name":
        "LastFM + Fanart.tv",
        #"check":get_settings("LASTFM_API_KEY") not in [None,"ASK"] and get_settings("FANARTTV_API_KEY") not in [None,"ASK"],
        "steps":
        [("get",
          "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist={artiststring}&api_key="
          + str(get_settings("LASTFM_API_KEY")) + "&format=json"),
         ("parse", ["artist", "mbid"]),
         ("get", "http://webservice.fanart.tv/v3/music/{var}?api_key=" +
          str(get_settings("FANARTTV_API_KEY"))),
         ("parse", ["artistthumb", 0, "url"])]
    })

if get_settings("SPOTIFY_API_ID") not in [
        None, "ASK"
示例#30
0
def clean_html(inp):
    if settings.get_settings("DEV_MODE"): return inp
    else: return html_minify(inp)