<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Anders Hassis &#187; Python</title>
	<atom:link href="http://hassis.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://hassis.com</link>
	<description>Did mmorpgs overwrite your common sense?</description>
	<lastBuildDate>Sun, 06 May 2012 19:07:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Enkel IRC-bot med Spotify-koppling</title>
		<link>/2009/11/08/enkel-irc-bot-med-spotify-koppling/</link>
		<comments>/2009/11/08/enkel-irc-bot-med-spotify-koppling/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 19:27:27 +0000</pubDate>
		<dc:creator>Anders</dc:creator>
				<category><![CDATA[Programmering]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://hassis.com/?p=19</guid>
		<description><![CDATA[Än en gång saknade jag möjligheten att se vilka låtar som folk skriver i olika IRC-kanaler med Spotify-länkar. Gjorde därför &#8216;Ilsken&#8217; som är en enkel IRC-bot som letar efter Spotify-länkar och kastar ut titeln på dessa. import socket, re from SpotifyMetaData import Metadata #Import Spotimeta (http://pypi.python.org/pypi/spotimeta/0.2) &#160; # @todo: Multiple networks &#160; class IrcBot: network [...]]]></description>
			<content:encoded><![CDATA[<p>Än en gång saknade jag möjligheten att se vilka låtar som folk skriver i olika IRC-kanaler med Spotify-länkar. Gjorde därför &#8216;Ilsken&#8217; som är en enkel IRC-bot som letar efter Spotify-länkar och kastar ut titeln på dessa.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">socket</span>, <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">from</span> SpotifyMetaData <span style="color: #ff7700;font-weight:bold;">import</span> Metadata <span style="color: #808080; font-style: italic;">#Import Spotimeta (http://pypi.python.org/pypi/spotimeta/0.2)</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># @todo: Multiple networks</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> IrcBot:
    network = <span style="color: #483d8b;">''</span>
    port = <span style="color: #ff4500;">0</span>
    nick = <span style="color: #483d8b;">''</span>
    channel = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    irc = <span style="color: #008000;">None</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, params<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Init bot using served parameters&quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">network</span> = params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'server'</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">port</span> = params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'port'</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">nick</span> = params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'nick'</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">channel</span> = params<span style="color: black;">&#91;</span><span style="color: #483d8b;">'channel'</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> connect<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Connect bot to network and keep the connection going&quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">irc</span> = <span style="color: #dc143c;">socket</span>.<span style="color: #dc143c;">socket</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">socket</span>.<span style="color: black;">AF_INET</span>, <span style="color: #dc143c;">socket</span>.<span style="color: black;">SOCK_STREAM</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">irc</span>.<span style="color: black;">connect</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">network</span>, <span style="color: #008000;">self</span>.<span style="color: black;">port</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.__log<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>.<span style="color: black;">irc</span>.<span style="color: black;">recv</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">4096</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.__sysMsg <span style="color: black;">&#40;</span><span style="color: #483d8b;">'NICK '</span> + <span style="color: #008000;">self</span>.<span style="color: black;">nick</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__sysMsg <span style="color: black;">&#40;</span><span style="color: #483d8b;">'USER '</span> + <span style="color: #008000;">self</span>.<span style="color: black;">nick</span> + <span style="color: #483d8b;">' '</span> + <span style="color: #008000;">self</span>.<span style="color: black;">nick</span> + <span style="color: #483d8b;">' '</span> + <span style="color: #008000;">self</span>.<span style="color: black;">nick</span> + <span style="color: #483d8b;">' :Python IRC'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">for</span> chanItem <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">channel</span>:
            <span style="color: #008000;">self</span>.__sysMsg <span style="color: black;">&#40;</span><span style="color: #483d8b;">'JOIN '</span> + chanItem<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
            data = <span style="color: #008000;">self</span>.<span style="color: black;">irc</span>.<span style="color: black;">recv</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">4096</span><span style="color: black;">&#41;</span>
            dataSplit = data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
&nbsp;
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>dataSplit<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>lt<span style="color: #66cc66;">;</span>= <span style="color: #ff4500;">3</span> :
                <span style="color: #ff7700;font-weight:bold;">if</span> data.<span style="color: black;">find</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'PING'</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
                    <span style="color: #008000;">self</span>.__sysMsg <span style="color: black;">&#40;</span><span style="color: #483d8b;">'PONG '</span> + data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span> <span style="color: #ff4500;">1</span> <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                    <span style="color: #008000;">self</span>.__log<span style="color: black;">&#40;</span><span style="color: #483d8b;">'PONG '</span> + data.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span> <span style="color: #ff4500;">1</span> <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">if</span> data.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'PRIVMSG'</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
                    <span style="color: #008000;">self</span>.__handleData<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    <span style="color: #008000;">self</span>.__log<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __parseData<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Generate a dictionary for msg, channel and sender&quot;&quot;&quot;</span>
&nbsp;
        complete = msg<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">':'</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        info = complete<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">' '</span><span style="color: black;">&#41;</span>
        sender = info<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'!'</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span> <span style="color: #483d8b;">'channel'</span> : info<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'sender'</span> : sender<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'msg'</span> : <span style="color: #483d8b;">''</span> . <span style="color: black;">join</span><span style="color: black;">&#40;</span>complete<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __handleData<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, data<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Parse user submitted data and handle it appropriate&quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #008000;">self</span>.__log<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
        dataInfo = <span style="color: #008000;">self</span>.__parseData<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># Add Spotify-functionality</span>
        <span style="color: #008000;">self</span>.__handleSpotify<span style="color: black;">&#40;</span>dataInfo<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __handleSpotify<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, dataInfo<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Identify Spotify-tracks and albums and take result from MetaData-api&quot;&quot;&quot;</span>
&nbsp;
        spotPattern = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'spotify:(.*?):(.*?)<span style="color: #000099; font-weight: bold;">\s</span>'</span><span style="color: black;">&#41;</span>
        spotBark = spotPattern.<span style="color: black;">search</span><span style="color: black;">&#40;</span> dataInfo<span style="color: black;">&#91;</span><span style="color: #483d8b;">'msg'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> spotBark:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                spotGroups = spotBark.<span style="color: black;">groups</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #808080; font-style: italic;"># Init Metadata-lib</span>
                metacache = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
                metadata = Metadata<span style="color: black;">&#40;</span>cache=metacache<span style="color: black;">&#41;</span>
                metaInfo = metadata.<span style="color: black;">lookup</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'spotify:'</span>+spotGroups<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>+<span style="color: #483d8b;">&quot;:&quot;</span>+spotGroups<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
                <span style="color: #ff7700;font-weight:bold;">if</span> spotGroups<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'track'</span> <span style="color: #ff7700;font-weight:bold;">or</span> spotGroups<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'album'</span>:
                    r = metaInfo<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;result&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artist&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span> + <span style="color: #483d8b;">' - '</span> + metaInfo<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;result&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>:
                    r = <span style="color: #483d8b;">'(Not found)'</span>
            <span style="color: #ff7700;font-weight:bold;">except</span>:
                <span style="color: #808080; font-style: italic;"># @todo: Fetch RateLimiting instead of doing a &quot;casual case&quot; like this</span>
                r = <span style="color: #483d8b;">&quot;(Limit exceeded or wrong input)&quot;</span>
&nbsp;
            <span style="color: #008000;">self</span>.__privMsg<span style="color: black;">&#40;</span>dataInfo<span style="color: black;">&#91;</span><span style="color: #483d8b;">'channel'</span><span style="color: black;">&#93;</span>, dataInfo<span style="color: black;">&#91;</span><span style="color: #483d8b;">'sender'</span><span style="color: black;">&#93;</span> + <span style="color: #483d8b;">': '</span> + r<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __log<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, msg<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Log to command line with a following linebreak&quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">print</span> msg + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __sysMsg<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #dc143c;">cmd</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Send commands to server with appropriate <span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;&quot;&quot;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">irc</span>.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">cmd</span> + <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __privMsg<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, target, msg<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Send privMsg to target (user or channel)&quot;&quot;&quot;</span>
&nbsp;
        msg = <span style="color: #483d8b;">'PRIVMSG '</span> + target + <span style="color: #483d8b;">' :'</span> + msg
&nbsp;
        <span style="color: #008000;">self</span>.__sysMsg <span style="color: black;">&#40;</span> msg <span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__log<span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>
&nbsp;
params = <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">'server'</span> : <span style="color: #483d8b;">'irc.freenode.net'</span>, \
    <span style="color: #483d8b;">'port'</span> : <span style="color: #ff4500;">6667</span>, \
    <span style="color: #483d8b;">'nick'</span> : <span style="color: #483d8b;">'ilsken'</span>, \
    <span style="color: #483d8b;">'channel'</span> : <span style="color: black;">&#91;</span><span style="color: #483d8b;">'#fooc2p'</span><span style="color: black;">&#93;</span> \
        <span style="color: black;">&#125;</span>
&nbsp;
bot = IrcBot<span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
bot.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Jag använde mig av <a href="http://pypi.python.org/pypi/spotimeta/0.2">Spotimeta</a> för att parsa länkarna när de hittats.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">xml</span>.<span style="color: black;">dom</span> <span style="color: #ff7700;font-weight:bold;">import</span> minidom
&nbsp;
<span style="color: #808080; font-style: italic;"># extremely boring dom parsing ahead. Consider yourself warned.</span>
&nbsp;
API_VERSION = <span style="color: #483d8b;">&quot;1&quot;</span>
USER_AGENT = <span style="color: #483d8b;">&quot;Spotimeta %s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># The reason for the uri arg is that the xml returned from lookups do not</span>
<span style="color: #808080; font-style: italic;"># contain the href uri of the thing that was looked up. However, when an</span>
<span style="color: #808080; font-style: italic;"># element is encountered that is NOT the root of a query, it DOES contain</span>
<span style="color: #808080; font-style: italic;"># the href. We pass it in so the returned data will have the same format</span>
<span style="color: #808080; font-style: italic;"># always</span>
<span style="color: #ff7700;font-weight:bold;">def</span> parse_lookup_doc<span style="color: black;">&#40;</span>src, uri=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    doc = minidom.<span style="color: black;">parse</span><span style="color: black;">&#40;</span>src<span style="color: black;">&#41;</span>
    root = doc.<span style="color: black;">documentElement</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;artist&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;type&quot;</span>: <span style="color: #483d8b;">&quot;artist&quot;</span>, <span style="color: #483d8b;">&quot;result&quot;</span>: parse_artist<span style="color: black;">&#40;</span>root, uri<span style="color: black;">&#41;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;album&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;type&quot;</span>: <span style="color: #483d8b;">&quot;album&quot;</span>, <span style="color: #483d8b;">&quot;result&quot;</span>: parse_album<span style="color: black;">&#40;</span>root, uri<span style="color: black;">&#41;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;track&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;type&quot;</span>: <span style="color: #483d8b;">&quot;track&quot;</span>, <span style="color: #483d8b;">&quot;result&quot;</span>: parse_track<span style="color: black;">&#40;</span>root, uri<span style="color: black;">&#41;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;unknown node type! &quot;</span> + root.<span style="color: black;">nodeName</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># fixme: proper exception here</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_search_doc<span style="color: black;">&#40;</span>src<span style="color: black;">&#41;</span>:
    doc = minidom.<span style="color: black;">parse</span><span style="color: black;">&#40;</span>src<span style="color: black;">&#41;</span>
    root = doc.<span style="color: black;">documentElement</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;artists&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> parse_artist_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;albums&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> parse_album_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">elif</span> root.<span style="color: black;">nodeName</span> == <span style="color: #483d8b;">&quot;tracks&quot;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> parse_track_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;unknown node type! &quot;</span> + root.<span style="color: black;">nodeName</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># fixme: proper exception here</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_artist<span style="color: black;">&#40;</span>root, uri=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ret = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">hasAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#93;</span> = uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, elem <span style="color: #ff7700;font-weight:bold;">in</span> _nodes<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> name == <span style="color: #483d8b;">&quot;name&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span> = _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;albums&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;albums&quot;</span><span style="color: black;">&#93;</span> = parse_albumlist<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_artistlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span>parse_artist, _filter<span style="color: black;">&#40;</span>root, <span style="color: #483d8b;">&quot;artist&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_albumlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span>parse_album, _filter<span style="color: black;">&#40;</span>root, <span style="color: #483d8b;">&quot;album&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_tracklist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">map</span><span style="color: black;">&#40;</span>parse_track, _filter<span style="color: black;">&#40;</span>root, <span style="color: #483d8b;">&quot;track&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_album<span style="color: black;">&#40;</span>root, uri=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ret = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">hasAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#93;</span> = uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, elem <span style="color: #ff7700;font-weight:bold;">in</span> _nodes<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> name == <span style="color: #483d8b;">&quot;name&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span> = _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;released&quot;</span>:
            released = _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> released:
                ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;released&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;id&quot;</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #483d8b;">&quot;ids&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> ret:
                ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;ids&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;ids&quot;</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>parse_id<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;tracks&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;tracks&quot;</span><span style="color: black;">&#93;</span> = parse_tracklist<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
&nbsp;
    ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span> = parse_artistlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> == <span style="color: #ff4500;">1</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artist&quot;</span><span style="color: black;">&#93;</span> = ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artist&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">None</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># todo: availability stuff. RFH</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_id<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>:
    ret = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;type&quot;</span>: elem.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;type&quot;</span><span style="color: black;">&#41;</span>,
           <span style="color: #483d8b;">&quot;id&quot;</span>: _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> elem.<span style="color: black;">hasAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#93;</span> = elem.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_track<span style="color: black;">&#40;</span>root, uri=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
    ret = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">hasAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#93;</span> = uri <span style="color: #ff7700;font-weight:bold;">or</span> root.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;href&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, elem <span style="color: #ff7700;font-weight:bold;">in</span> _nodes<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> name == <span style="color: #483d8b;">&quot;name&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;name&quot;</span><span style="color: black;">&#93;</span> = _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;disc-number&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;disc-number&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;track-number&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;track-number&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;length&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;length&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;popularity&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;popularity&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;album&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;album&quot;</span><span style="color: black;">&#93;</span> = parse_album<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;id&quot;</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #483d8b;">&quot;ids&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> ret:
                ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;ids&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;ids&quot;</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>parse_id<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span> = parse_artistlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Following prop is there for backwards compat. It may be dropped in a</span>
    <span style="color: #808080; font-style: italic;"># future version</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span>:
        ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artist&quot;</span><span style="color: black;">&#93;</span> = ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;artists&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_opensearch<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    ret = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    elems = root.<span style="color: black;">getElementsByTagNameNS</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://a9.com/-/spec/opensearch/1.1/&quot;</span>, <span style="color: #483d8b;">&quot;*&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> name, elem <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>e.<span style="color: black;">localName</span>, e<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> e <span style="color: #ff7700;font-weight:bold;">in</span> elems<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> name == <span style="color: #483d8b;">&quot;Query&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;term&quot;</span><span style="color: black;">&#93;</span> = elem.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;searchTerms&quot;</span><span style="color: black;">&#41;</span>
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;start_page&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>elem.<span style="color: black;">getAttribute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;startPage&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;totalResults&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;total_results&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;startIndex&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;start_index&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> name == <span style="color: #483d8b;">&quot;itemsPerPage&quot;</span>:
            ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;items_per_page&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>_text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_album_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Note that the search result tags are not  tags or similar.</span>
    <span style="color: #808080; font-style: italic;"># Instead they are normal  tags with extra</span>
    <span style="color: #808080; font-style: italic;"># stuff from the opensearch namespace. That's why we cant just directly</span>
    <span style="color: #808080; font-style: italic;"># return the result from parse_albumlist</span>
    ret = parse_opensearch<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;result&quot;</span><span style="color: black;">&#93;</span> = parse_albumlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_artist_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    ret = parse_opensearch<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;result&quot;</span><span style="color: black;">&#93;</span> = parse_artistlist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> parse_track_search<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>:
    ret = parse_opensearch<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    ret<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;result&quot;</span><span style="color: black;">&#93;</span> = parse_tracklist<span style="color: black;">&#40;</span>root<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> ret
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> _nodes<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;return an generator yielding element nodes that are children
    of elem.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>e.<span style="color: black;">nodeName</span>, e<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> e
            <span style="color: #ff7700;font-weight:bold;">in</span> elem.<span style="color: black;">childNodes</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> e.<span style="color: black;">nodeType</span>==e.<span style="color: black;">ELEMENT_NODE</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> _text<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Returns a concatenation of all text nodes that are children
    of elem (roughly what elem.textContent does in web dom&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>e.<span style="color: black;">nodeValue</span> <span style="color: #ff7700;font-weight:bold;">for</span> e
                    <span style="color: #ff7700;font-weight:bold;">in</span> elem.<span style="color: black;">childNodes</span>
                    <span style="color: #ff7700;font-weight:bold;">if</span> e.<span style="color: black;">nodeType</span>==e.<span style="color: black;">TEXT_NODE</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> _filter<span style="color: black;">&#40;</span>elem, filtername<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Returns a generator yielding all child nodes with the nodeName name&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span>elem <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>name, elem<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">in</span> _nodes<span style="color: black;">&#40;</span>elem<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> name == filtername<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">email</span>.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> parsedate_tz, mktime_tz, formatdate
<span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ImportError</span>: <span style="color: #808080; font-style: italic;"># utils module name was lowercased after 2.4</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">email</span>.<span style="color: black;">Utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> parsedate_tz, mktime_tz, formatdate
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">urllib</span> <span style="color: #ff7700;font-weight:bold;">import</span> urlencode
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SpotimetaError<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Superclass for all spotimeta exceptions. Adds no functionality. Only
    there so it's possible to set up try blocks that catch all spotimeta
    errors, regardless of class&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> RequestTimeout<span style="color: black;">&#40;</span>SpotimetaError<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Raised when the timeout flag is in use and a request did not finish
    within the allotted time.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> NotFound<span style="color: black;">&#40;</span>SpotimetaError<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Raised when doing lookup on something that does not exist. Triggered
    by the 404 http status code&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> RateLimiting<span style="color: black;">&#40;</span>SpotimetaError<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Raised when the request was not completed due to rate limiting
    restrictions&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ServiceUnavailable<span style="color: black;">&#40;</span>SpotimetaError<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Raised when the metadata service is not available (that is, the server
    is up, but not accepting API requests at this time&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> ServerError<span style="color: black;">&#40;</span>SpotimetaError<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Raised when an internal server error occurs. According to the spotify
    documentation, this &quot;should not happen&quot;.&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> canonical<span style="color: black;">&#40;</span>url_or_uri<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;returns a spotify uri, regardless if a url or uri is passed in&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> url_or_uri.<span style="color: black;">startswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http&quot;</span><span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># assume it's a url</span>
        parts = url_or_uri.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;spotify:%s:%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>parts<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, parts<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> url_or_uri
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> entrytype<span style="color: black;">&#40;</span>url_or_uri<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Return &quot;album&quot;, &quot;artist&quot; or &quot;track&quot; based on the type of entry the uri
    or url refers to.&quot;&quot;&quot;</span>
    uri = canonical<span style="color: black;">&#40;</span>url_or_uri<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> uri.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;:&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">IndexError</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Metadata<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, cache=<span style="color: #008000;">None</span>, rate=<span style="color: #ff4500;">10</span>, timeout=<span style="color: #008000;">None</span>, user_agent=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">cache</span> = cache <span style="color: #808080; font-style: italic;"># not implemented yet</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">rate</span> = rate <span style="color: #808080; font-style: italic;"># not implemented yet</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = timeout
        <span style="color: #008000;">self</span>.<span style="color: black;">user_agent</span> = user_agent <span style="color: #ff7700;font-weight:bold;">or</span> USER_AGENT
        <span style="color: #008000;">self</span>._timeout_supported = <span style="color: #008000;">True</span>
        <span style="color: #008000;">self</span>._port = <span style="color: #483d8b;">&quot;80&quot;</span>
        <span style="color: #008000;">self</span>._host = <span style="color: #483d8b;">&quot;ws.spotify.com&quot;</span>
        <span style="color: #008000;">self</span>._detailtypes = <span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">&quot;artist&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #ff4500;">1</span>: <span style="color: #483d8b;">&quot;album&quot;</span>, <span style="color: #ff4500;">2</span>: <span style="color: #483d8b;">&quot;albumdetail&quot;</span><span style="color: black;">&#125;</span>,
            <span style="color: #483d8b;">&quot;album&quot;</span>: <span style="color: black;">&#123;</span><span style="color: #ff4500;">1</span>: <span style="color: #483d8b;">&quot;track&quot;</span>, <span style="color: #ff4500;">2</span>: <span style="color: #483d8b;">&quot;trackdetail&quot;</span><span style="color: black;">&#125;</span>
        <span style="color: black;">&#125;</span>
&nbsp;
        major, minor = <span style="color: #dc143c;">sys</span>.<span style="color: black;">version_info</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> <span style="color: #ff7700;font-weight:bold;">and</span> major == <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">and</span> minor <span style="color: #66cc66;">&amp;</span>lt<span style="color: #66cc66;">;</span><span style="color: #ff4500;">6</span>:
            <span style="color: #008000;">self</span>._timeout_supported = <span style="color: #008000;">False</span>
            <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">warnings</span>
            <span style="color: #dc143c;">warnings</span>.<span style="color: black;">warn</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Timeouts in urllib not supported in this version&quot;</span> +
                          <span style="color: #483d8b;">&quot; of python. timeout argument will be ignored!&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _do_request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, url, headers<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Perform an actual response. Deal with 200 and 304 responses
        correctly. If another error occurs, raise the appropriate
        exception&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>url, <span style="color: #008000;">None</span>, headers<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>._timeout_supported:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req, timeout=<span style="color: #008000;">self</span>.<span style="color: black;">timeout</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPError</span>, e:
            <span style="color: #ff7700;font-weight:bold;">if</span> e.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">304</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> e <span style="color: #808080; font-style: italic;"># looks wrong but isnt't. On non fatal errors the</span>
                         <span style="color: #808080; font-style: italic;"># exception behaves like the retval from urlopen</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> e.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">404</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> NotFound<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> e.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">403</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> RateLimiting<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> e.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">500</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> ServerError<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> e.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">503</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> ServiceUnavailable<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #808080; font-style: italic;"># this should never happen</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">URLError</span>, e:
            <span style="color: #483d8b;">&quot;&quot;&quot;Probably timeout. should do a better check. FIXME&quot;&quot;&quot;</span>
            <span style="color: #ff7700;font-weight:bold;">raise</span> RequestTimeout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span>
            <span style="color: #808080; font-style: italic;"># all the exceptions we don't know about yet. Probably</span>
            <span style="color: #808080; font-style: italic;"># some socket errors will come up here.</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _get_url<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, url, query, if_modified_since=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Perform an http requests and return the open file-like object, if
        there is one, as well as the expiry time and last-modified-time
        if they were present in the reply.
        If the if_modified_since variable is passed in, send it as the value
        of the If-Modified-Since header.&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> query:
            url = <span style="color: #483d8b;">&quot;%s?%s&quot;</span> <span style="color: #66cc66;">%</span><span style="color: black;">&#40;</span>url, urlencode<span style="color: black;">&#40;</span>query<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        headers = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'User-Agent'</span>: <span style="color: #008000;">self</span>.<span style="color: black;">user_agent</span><span style="color: black;">&#125;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> if_modified_since:
            headers<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;If-Modified-Since&quot;</span><span style="color: black;">&#93;</span> = formatdate<span style="color: black;">&#40;</span>if_modified_since, <span style="color: #008000;">False</span>, <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
&nbsp;
        fp = <span style="color: #008000;">self</span>._do_request<span style="color: black;">&#40;</span>url, headers<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># at this point we have something file like after the request</span>
        <span style="color: #808080; font-style: italic;"># finished with a 200 or 304.</span>
&nbsp;
        headers = fp.<span style="color: black;">info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> fp.<span style="color: #dc143c;">code</span> == <span style="color: #ff4500;">304</span>:
            fp = <span style="color: #008000;">None</span>
&nbsp;
        expires = <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;Expires&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> headers:
            expires = mktime_tz<span style="color: black;">&#40;</span>parsedate_tz<span style="color: black;">&#40;</span>headers.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Expires&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        modified = <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">&quot;Last-Modified&quot;</span> <span style="color: #ff7700;font-weight:bold;">in</span> headers:
            modified = mktime_tz<span style="color: black;">&#40;</span>parsedate_tz<span style="color: black;">&#40;</span>headers.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Last-Modified&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> fp, modified, expires
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> lookup<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, uri, detail=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Lookup metadata for a URI. Optionally ask for extra details.
        The details argument is an int: 0 for normal ammount of detauls, 1
        for extra details, and 2 for most details. For tracks the details
        argument is ignored, as the Spotify api only has one level of detail
        for tracks. For the meaning of the detail levels, look at the
        Spotify api docs&quot;&quot;&quot;</span>
&nbsp;
        key = <span style="color: #483d8b;">&quot;%s:%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>uri, detail<span style="color: black;">&#41;</span>
        res, modified, expires = <span style="color: #008000;">self</span>._cache_get<span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> res <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>lt<span style="color: #66cc66;">;</span> expires:
            <span style="color: #ff7700;font-weight:bold;">return</span> res
        <span style="color: #808080; font-style: italic;"># else, cache is outdated or entry not in it. Normal request cycle</span>
&nbsp;
        url = <span style="color: #483d8b;">&quot;http://%s:%s/lookup/%s/&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._host, <span style="color: #008000;">self</span>._port, API_VERSION<span style="color: black;">&#41;</span>
        uri = canonical<span style="color: black;">&#40;</span>uri<span style="color: black;">&#41;</span>
        query = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;uri&quot;</span>: uri<span style="color: black;">&#125;</span>
        kind = entrytype<span style="color: black;">&#40;</span>uri<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> detail <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> kind <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>._detailtypes.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            query<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;extras&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">self</span>._detailtypes<span style="color: black;">&#91;</span>kind<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span>detail<span style="color: black;">&#93;</span>
&nbsp;
        fp, new_modified, new_expires = <span style="color: #008000;">self</span>._get_url<span style="color: black;">&#40;</span>url, query, modified<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> fp: <span style="color: #808080; font-style: italic;"># We got data, sweet</span>
            res = parse_lookup_doc<span style="color: black;">&#40;</span>fp, uri=uri<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>._cache_put<span style="color: black;">&#40;</span>key, res, new_modified <span style="color: #ff7700;font-weight:bold;">or</span> modified, new_expires <span style="color: #ff7700;font-weight:bold;">or</span> expires<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> search_album<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, term, page=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;The first page is numbered 1!&quot;&quot;&quot;</span>
        url = <span style="color: #483d8b;">&quot;http://%s:%s/search/%s/album&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>
            <span style="color: #008000;">self</span>._host, <span style="color: #008000;">self</span>._port, API_VERSION<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._do_search<span style="color: black;">&#40;</span>url, term, page<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> search_artist<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, term, page=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;The first page is numbered 1!&quot;&quot;&quot;</span>
        url = <span style="color: #483d8b;">&quot;http://%s:%s/search/%s/artist&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>
            <span style="color: #008000;">self</span>._host, <span style="color: #008000;">self</span>._port, API_VERSION<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._do_search<span style="color: black;">&#40;</span>url, term, page<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> search_track<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, term, page=<span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;The first page is numbered 1!&quot;&quot;&quot;</span>
        url = <span style="color: #483d8b;">&quot;http://%s:%s/search/%s/track&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>
            <span style="color: #008000;">self</span>._host, <span style="color: #008000;">self</span>._port, API_VERSION<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>._do_search<span style="color: black;">&#40;</span>url, term, page<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _do_search<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, url, term, page<span style="color: black;">&#41;</span>:
        key = <span style="color: #483d8b;">&quot;%s:%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>term, page<span style="color: black;">&#41;</span>
&nbsp;
        res, modified, expires = <span style="color: #008000;">self</span>._cache_get<span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> res <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>lt<span style="color: #66cc66;">;</span> expires:
            <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
        query = <span style="color: black;">&#123;</span><span style="color: #483d8b;">&quot;q&quot;</span>: term.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'UTF-8'</span><span style="color: black;">&#41;</span><span style="color: black;">&#125;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> page <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            query<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;page&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>page<span style="color: black;">&#41;</span>
&nbsp;
        fp, new_modified, new_expires = <span style="color: #008000;">self</span>._get_url<span style="color: black;">&#40;</span>url, query, modified<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> fp: <span style="color: #808080; font-style: italic;"># We got data, sweet</span>
            res = parse_search_doc<span style="color: black;">&#40;</span>fp<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>._cache_put<span style="color: black;">&#40;</span>key, res, new_modified <span style="color: #ff7700;font-weight:bold;">or</span> modified, new_expires <span style="color: #ff7700;font-weight:bold;">or</span> expires<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _cache_get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, key<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Get a tuple containing data, last-modified, expires.
        If entry is not in cache return None, 0, 0
        &quot;&quot;&quot;</span>
        entry = <span style="color: #008000;">None</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">cache</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            entry = <span style="color: #008000;">self</span>.<span style="color: black;">cache</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span>key<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">return</span> entry <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> _cache_put<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, key, value, modified, expires<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot;Inverse of _cache_put&quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">cache</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">cache</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> = value, modified, expires</pre></div></div>

<p>Har ni några tips eller förslag på koden så är det välkommet! Kommentera eller använd kontaktformuläret.</p>
]]></content:encoded>
			<wfw:commentRss>/2009/11/08/enkel-irc-bot-med-spotify-koppling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

