| 256 | | if self.feed is None or len(self.feed.entries) <= 0: |
| 257 | | try: |
| 258 | | for i in range(3): |
| 259 | | xspf = self.webservices.request_xspf() |
| 260 | | if xspf != 'No recs :(': |
| | 259 | pop = None |
| | 260 | if self.feed is None: |
| | 261 | pop = PopupBox(text=_('Downloading, please wait...')) |
| | 262 | pop.show() |
| | 263 | |
| | 264 | try: |
| | 265 | if self.feed is None or len(self.feed.entries) <= 1: |
| | 266 | try: |
| | 267 | for i in range(3): |
| | 268 | xspf = self.webservices.request_xspf() |
| | 269 | if xspf != 'No recs :(': |
| | 270 | break |
| | 271 | time.sleep(2) |
| | 272 | else: |
| | 273 | if menuw: |
| | 274 | AlertBox(text='No recs :(').show() |
| | 275 | traceback.print_stack() |
| | 276 | rc.post_event(STOP) |
| | 277 | return |
| | 278 | |
| | 279 | self.feed = self.xspf.parse(xspf) |
| | 280 | if self.feed is None: |
| | 281 | if menuw: |
| | 282 | AlertBox(text=_('Cannot get XSFP')).show() |
| | 283 | traceback.print_stack() |
| | 284 | rc.post_event(STOP) |
| | 285 | return |
| | 286 | except LastFMError, why: |
| | 287 | _debug_(why, DWARNING) |
| | 288 | if menuw: |
| | 289 | AlertBox(text=str(why)).show() |
| | 290 | rc.post_event(STOP) |
| | 291 | return |
| | 292 | |
| | 293 | entry = self.feed.entries[0] |
| | 294 | _debug_('entry "%s / %s / %s" of %s' % (entry.artist, entry.album, entry.title, len(self.feed.entries))) |
| | 295 | self.stream_name = urllib.unquote_plus(self.feed.title) |
| | 296 | self.album = entry.album |
| | 297 | self.artist = entry.artist |
| | 298 | self.title = entry.title |
| | 299 | self.location_url = entry.location_url |
| | 300 | self.length = entry.duration |
| | 301 | basename = os.path.join(config.LASTFM_DIR, self.stream_name, entry.artist, entry.album, entry.title) |
| | 302 | self.basename = basename.lower().replace(' ', '_').\ |
| | 303 | replace('.', '').replace('\'', '').replace(':', '').replace(',', '') |
| | 304 | if not os.path.exists(os.path.dirname(self.basename)): |
| | 305 | _debug_('make directory %r' % (os.path.dirname(self.basename),), DINFO) |
| | 306 | os.makedirs(os.path.dirname(self.basename), 0777) |
| | 307 | # url is changed, to include file:// |
| | 308 | self.url = os.path.join(self.basename + os.path.splitext(entry.location_url)[1]) |
| | 309 | self.trackpath = os.path.join(self.basename + os.path.splitext(entry.location_url)[1]) |
| | 310 | self.track_downloader = self.webservices.download(self.location_url, self.trackpath) |
| | 311 | if entry.image_url: |
| | 312 | self.image = os.path.join(self.basename + os.path.splitext(entry.image_url)[1]) |
| | 313 | self.image_downloader = self.webservices.download(entry.image_url, self.image) |
| | 314 | # Wait three seconds for the image to be downloaded |
| | 315 | for i in range(30): |
| | 316 | if not self.image_downloader.isrunning(): |
| 357 | | |
| 358 | | |
| 359 | | |
| 360 | | |
| 361 | | class SmartRedirectHandler(urllib2.HTTPRedirectHandler): |
| 362 | | def http_error_301(self, req, fp, code, msg, headers): |
| 363 | | print 'DJW:http_error_301' |
| 364 | | result = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers) |
| 365 | | result.status = code |
| 366 | | return result |
| 367 | | |
| 368 | | def http_error_302(self, req, fp, code, msg, headers): |
| 369 | | print 'DJW:http_error_302' |
| 370 | | result = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers) |
| 371 | | result.status = code |
| 372 | | return result |
| 373 | | |
| 374 | | |
| 375 | | |
| 376 | | class LastFMDownloader(Thread): |
| 377 | | """ |
| 378 | | Download the stream to a file |
| 379 | | |
| 380 | | There is a bad bug im mplayer that corrupts the url passed, so we have to |
| 381 | | download it to a file and then play it |
| 382 | | """ |
| 383 | | @benchmark(benchmarking, benchmarkcall) |
| 384 | | def __init__(self, url, filename, headers=None): |
| 385 | | Thread.__init__(self) |
| 386 | | self.url = url |
| 387 | | self.filename = filename |
| 388 | | self.headers = headers |
| 389 | | self.running = True |
| 390 | | self.size = 0 |
| 391 | | |
| 392 | | |
| 393 | | @benchmark(benchmarking, benchmarkcall) |
| 394 | | def run(self): |
| 395 | | """ |
| 396 | | Execute a download operation. Stop when finished downloading or |
| 397 | | requested to stop. |
| 398 | | """ |
| 399 | | request = urllib2.Request(self.url, headers=self.headers) |
| 400 | | opener = urllib2.build_opener(SmartRedirectHandler()) |
| 401 | | try: |
| 402 | | f = opener.open(request) |
| 403 | | fd = open(self.filename, 'wb') |
| 404 | | while self.running: |
| 405 | | reply = f.read(1024 * 100) |
| 406 | | fd.write(reply) |
| 407 | | if len(reply) == 0: |
| 408 | | self.running = False |
| 409 | | print '%s downloaded' % self.filename |
| 410 | | # debugs fail during shutdown |
| 411 | | #_debug_('%s downloaded' % self.filename) |
| 412 | | # what we could do now is to add tags to track |
| 413 | | break |
| 414 | | self.size += len(reply) |
| 415 | | else: |
| 416 | | print '%s download aborted' % self.filename |
| 417 | | #_debug_('%s download aborted' % self.filename) |
| 418 | | os.remove(self.filename) |
| 419 | | fd.close() |
| 420 | | f.close() |
| 421 | | except ValueError, why: |
| 422 | | _debug_('%s: %s' % (self.url, why), DWARNING) |
| 423 | | except urllib2.HTTPError, why: |
| 424 | | _debug_('%s: %s' % (self.url, why), DWARNING) |
| 425 | | |
| 426 | | |
| 427 | | @benchmark(benchmarking, benchmarkcall) |
| 428 | | def filesize(self): |
| 429 | | """ |
| 430 | | Get the downloaded file size |
| 431 | | """ |
| 432 | | return self.size |
| 433 | | |
| 434 | | |
| 435 | | @benchmark(benchmarking, benchmarkcall) |
| 436 | | def stop(self): |
| 437 | | """ |
| 438 | | Stop the download thead running |
| 439 | | """ |
| 440 | | # this does not stop the download thread |
| 441 | | self.running = False |
| 442 | | |
| 443 | | |
| 444 | | @benchmark(benchmarking, benchmarkcall) |
| 445 | | def isrunning(self): |
| 446 | | """ |
| 447 | | See if the thread running |
| 448 | | """ |
| 449 | | return self.running |
| 450 | | |
| 451 | | |
| 452 | | |
| 453 | | class LastFMWebServices: |
| 454 | | """ |
| 455 | | Interface to LastFM web-services |
| 456 | | """ |
| 457 | | _version = '1.1.2' |
| 458 | | headers = { |
| 459 | | 'User-agent': 'Freevo-%s (r%s)' % (version.__version__, revision.__revision__) |
| 460 | | } |
| 461 | | |
| 462 | | @benchmark(benchmarking, benchmarkcall) |
| 463 | | def __init__(self): |
| 464 | | _debug_('LastFMWebServices.__init__()', 2) |
| 465 | | self.logincachefilename = os.path.join(config.FREEVO_CACHEDIR, 'lastfm.session') |
| 466 | | try: |
| 467 | | self.cachefd = open(self.logincachefilename, 'r') |
| 468 | | self.session = self.cachefd.readline().strip('\n') |
| 469 | | self.stream_url = self.cachefd.readline().strip('\n') |
| 470 | | self.base_url = self.cachefd.readline().strip('\n') |
| 471 | | self.base_path = self.cachefd.readline().strip('\n') |
| 472 | | self.downloader = None |
| 473 | | except IOError, why: |
| 474 | | self._login() |
| 475 | | |
| 476 | | |
| 477 | | @benchmark(benchmarking, benchmarkcall) |
| 478 | | def shutdown(self): |
| 479 | | """ |
| 480 | | Shutdown the lasf.fm webservices |
| 481 | | """ |
| 482 | | if self.downloader is not None: |
| 483 | | self.downloader.stop() |
| 484 | | |
| 485 | | |
| 486 | | @benchmark(benchmarking, benchmarkcall) |
| 487 | | def _urlopen(self, url, lines=True): |
| 488 | | """ |
| 489 | | Wrapper to see what is sent and received |
| 490 | | When lines is true then the reply is returned as a list of lines, |
| 491 | | otherwise it is returned as a block. |
| 492 | | |
| 493 | | @param url: Is the URL to read. |
| 494 | | @param data: Is the POST data. |
| 495 | | @param lines: return a list of lines, otherwise data block. |
| 496 | | @returns: reply from request |
| 497 | | """ |
| 498 | | _debug_('url=%r, lines=%r' % (url, lines), 1) |
| 499 | | request = urllib2.Request(url, headers=LastFMWebServices.headers) |
| 500 | | opener = urllib2.build_opener(SmartRedirectHandler()) |
| 501 | | try: |
| 502 | | if lines: |
| 503 | | reply = [] |
| 504 | | f = opener.open(request) |
| 505 | | lines = f.readlines() |
| 506 | | if lines is None: |
| 507 | | return [] |
| 508 | | for line in lines: |
| 509 | | reply.append(line.strip('\n')) |
| 510 | | _debug_('reply=%r' % (reply,), 1) |
| 511 | | else: |
| 512 | | reply = '' |
| 513 | | f = opener.open(request) |
| 514 | | reply = f.read() |
| 515 | | _debug_('len(reply)=%r' % (len(reply),), 1) |
| 516 | | return reply |
| 517 | | except urllib2.HTTPError, why: |
| 518 | | _debug_('%s: %s' % (url, why)) |
| 519 | | raise LastFMError(why) |
| 520 | | except Exception, why: |
| 521 | | _debug_('%s: %s' % (url, why)) |
| 522 | | raise LastFMError(why) |
| 523 | | |
| 524 | | |
| 525 | | @benchmark(benchmarking, benchmarkcall) |
| 526 | | def _login(self, arg=None): |
| 527 | | """Read session and stream url from ws.audioscrobbler.com""" |
| 528 | | _debug_('login(arg=%r)' % (arg,), 2) |
| 529 | | username = config.LASTFM_USER |
| 530 | | password_txt = config.LASTFM_PASS |
| 531 | | password = md5.new(config.LASTFM_PASS) |
| 532 | | login_url='http://ws.audioscrobbler.com/radio/handshake.php' + \ |
| 533 | | '?version=%s&platform=linux' % (LastFMWebServices._version) + \ |
| 534 | | '&username=%s&passwordmd5=%s' % (config.LASTFM_USER, password.hexdigest()) + \ |
| 535 | | '&debug=0&language=%s' % (config.LASTFM_LANG) |
| 536 | | stream_url = '' |
| 537 | | |
| 538 | | try: |
| 539 | | lines = self._urlopen(login_url) |
| 540 | | for line in lines: |
| 541 | | # this is a bit dangerous if a variable clashes |
| 542 | | exec('self.%s = "%s"' % tuple(line.split('=', 1))) |
| 543 | | # Save the lastfm session information |
| 544 | | fd = open(self.logincachefilename, 'w') |
| 545 | | print >>fd, self.session |
| 546 | | print >>fd, self.stream_url |
| 547 | | print >>fd, self.base_url |
| 548 | | print >>fd, self.base_path |
| 549 | | fd.close() |
| 550 | | except IOError, why: |
| 551 | | self.session = '' |
| 552 | | self.stream_url = '' |
| 553 | | self.base_url = '' |
| 554 | | self.base_path = '' |
| 555 | | |
| 556 | | |
| 557 | | @benchmark(benchmarking, benchmarkcall) |
| 558 | | def request_xspf(self): |
| 559 | | """Request a XSPF (XML Shareable Playlist File)""" |
| 560 | | _debug_('LastFMWebServices.request_xspf()', 1) |
| 561 | | if not self.session: |
| 562 | | self._login() |
| 563 | | request_url = 'http://%s%s/xspf.php?sk=%s&discovery=0&desktop=%s' % \ |
| 564 | | (self.base_url, self.base_path, self.session, LastFMWebServices._version) |
| 565 | | return self._urlopen(request_url, lines=False) |
| 566 | | |
| 567 | | |
| 568 | | @benchmark(benchmarking, benchmarkcall) |
| 569 | | def adjust_station(self, station_url): |
| 570 | | """Change Last FM Station""" |
| 571 | | _debug_('adjust_station(station_url=%r)' % (station_url,), 2) |
| 572 | | if not self.session: |
| 573 | | self._login() |
| 574 | | tune_url = 'http://ws.audioscrobbler.com/radio/adjust.php?session=%s&url=%s&lang=%s&debug=0' % \ |
| 575 | | (self.session, station_url, config.LASTFM_LANG) |
| 576 | | try: |
| 577 | | for line in self._urlopen(tune_url): |
| 578 | | if re.search('response=OK', line): |
| 579 | | return True |
| 580 | | return False |
| 581 | | except AttributeError, why: |
| 582 | | return None |
| 583 | | except IOError, why: |
| 584 | | return None |
| 585 | | |
| 586 | | |
| 587 | | @benchmark(benchmarking, benchmarkcall) |
| 588 | | def now_playing(self): |
| 589 | | """ |
| 590 | | Return Song Info and album Cover |
| 591 | | """ |
| 592 | | _debug_('now_playing()', 2) |
| 593 | | if not self.session: |
| 594 | | self._login() |
| 595 | | info_url = 'http://ws.audioscrobbler.com/radio/np.php?session=%s&debug=0' % (self.session,) |
| 596 | | reply = self._urlopen(info_url) |
| 597 | | if not reply or reply[0] == 'streaming=false': |
| 598 | | return None |
| 599 | | return reply |
| 600 | | |
| 601 | | |
| 602 | | @benchmark(benchmarking, benchmarkcall) |
| 603 | | def download(self, url, filename): |
| 604 | | """ |
| 605 | | Download album cover or track to last.fm directory. |
| 606 | | |
| 607 | | Add the session as a cookie to the request |
| 608 | | |
| 609 | | @param url: location of item to download |
| 610 | | @param filename: path to downloaded file |
| 611 | | """ |
| 612 | | _debug_('download(url=%r, filename=%r)' % (url, filename), 1) |
| 613 | | if not self.session: |
| 614 | | self._login() |
| 615 | | headers = { |
| 616 | | 'Cookie': 'Session=%s' % self.session, |
| 617 | | 'User-agent': 'Freevo-%s (r%s)' % (version.__version__, revision.__revision__) |
| 618 | | } |
| 619 | | self.downloader = LastFMDownloader(url, filename, headers) |
| 620 | | self.downloader.start() |
| 621 | | return self.downloader |
| 622 | | |
| 623 | | |
| 624 | | @benchmark(benchmarking, benchmarkcall) |
| 625 | | def skip(self): |
| 626 | | """Skip song""" |
| 627 | | _debug_('skip()', 2) |
| 628 | | if not self.session: |
| 629 | | self._login |
| 630 | | skip_url = 'http://ws.audioscrobbler.com/radio/control.php?session=%s&command=skip&debug=0' % \ |
| 631 | | (self.session) |
| 632 | | return self._urlopen(skip_url) |
| 633 | | |
| 634 | | |
| 635 | | @benchmark(benchmarking, benchmarkcall) |
| 636 | | def love(self): |
| 637 | | """Send "Love" information to audioscrobbler""" |
| 638 | | _debug_('love()', 2) |
| 639 | | if not self.session: |
| 640 | | self._login |
| 641 | | love_url = 'http://ws.audioscrobbler.com/radio/control.php?session=%s&command=love&debug=0' % \ |
| 642 | | (self.session) |
| 643 | | return self._urlopen(love_url) |
| 644 | | |
| 645 | | |
| 646 | | @benchmark(benchmarking, benchmarkcall) |
| 647 | | def ban(self): |
| 648 | | """Send "Ban" information to audioscrobbler""" |
| 649 | | _debug_('ban()', 2) |
| 650 | | if not self.session: |
| 651 | | self._login |
| 652 | | ban_url = 'http://ws.audioscrobbler.com/radio/control.php?session=%s&command=ban&debug=0' % \ |
| 653 | | (self.session) |
| 654 | | return self._urlopen(ban_url) |
| 655 | | |
| 656 | | |
| 657 | | @benchmark(benchmarking, benchmarkcall) |
| 658 | | def test_user_pass(self): |
| 659 | | """ |
| 660 | | Test User/Pass |
| 661 | | |
| 662 | | This way you can check, whether a user/pass is valid. |
| 663 | | |
| 664 | | http://ws.audioscrobbler.com/ass/pwcheck.php? |
| 665 | | time=[TS]&username=[USER]&auth=[AUTH1]&auth2=[AUTH2]&defaultplayer=[PLAYER] |
| 666 | | |
| 667 | | Variables: |
| 668 | | |
| 669 | | * TS: Unix timestamp of the current time. |
| 670 | | * USER: Username. |
| 671 | | * AUTH1: md5( md5(password) + Timestamp), An md5 sum of an md5 sum of the password, plus the timestamp as salt. |
| 672 | | * AUTH2: Second possible Password. The client uses md5( md5(toLower(password)) + Timestamp) |
| 673 | | * PLAYER: See Appendix |
| 674 | | """ |
| 675 | | timestamp = time.strftime('%s', time.gmtime(time.time())) |
| 676 | | username = config.LASTFM_USER |
| 677 | | password = config.LASTFM_PASS |
| 678 | | auth = md5.new(md5.new(password).hexdigest()+timestamp).hexdigest() |
| 679 | | auth2 = md5.new(md5.new(password.lower()).hexdigest()+timestamp).hexdigest() |
| 680 | | url = 'http://ws.audioscrobbler.com//ass/pwcheck.php?' + \ |
| 681 | | 'time=%s&' % timestamp + \ |
| 682 | | 'username=%s&' % username + \ |
| 683 | | 'auth=%s&' % auth + \ |
| 684 | | 'auth2=%s&' % auth2 + \ |
| 685 | | 'defaultplayer=fvo' |
| 686 | | return self._urlopen(url) |
| | 428 | class LastFMWebServices: |
| | 429 | """ |
| | 430 | Interface to LastFM web-services |
| | 431 | """ |
| | 432 | _version = '1.1.2' |
| | 433 | headers = { |
| | 434 | 'User-agent': 'Freevo-%s (r%s)' % (version.__version__, revision.__revision__) |
| | 435 | } |
| | 436 | |
| | 437 | @benchmark(benchmarking, benchmarkcall) |
| | 438 | def __init__(self): |
| | 439 | _debug_('LastFMWebServices.__init__()', 2) |
| | 440 | self.logincachefilename = os.path.join(config.FREEVO_CACHEDIR, 'lastfm.session') |
| | 441 | try: |
| | 442 | self.cachefd = open(self.logincachefilename, 'r') |
| | 443 | self.session = self.cachefd.readline().strip('\n') |
| | 444 | self.stream_url = self.cachefd.readline().strip('\n') |
| | 445 | self.base_url = self.cachefd.readline().strip('\n') |
| | 446 | self.base_path = self.cachefd.readline().strip('\n') |
| | 447 | self.downloader = None |
| | 448 | except IOError, why: |
| | 449 | self._login() |
| | 450 | |
| | 451 | |
| | 452 | @benchmark(benchmarking, benchmarkcall) |
| | 453 | def shutdown(self): |
| | 454 | """ |
| | 455 | Shutdown the lasf.fm webservices |
| | 456 | """ |
| | 457 | if self.downloader is not None: |
| | 458 | self.downloader.stop() |
| | 459 | |
| | 460 | |
| | 461 | @benchmark(benchmarking, benchmarkcall) |
| | 462 | def _urlopen(self, url, lines=True): |
| | 463 | """ |
| | 464 | Wrapper to see what is sent and received |
| | 465 | When lines is true then the reply is returned as a list of lines, |
| | 466 | otherwise it is returned as a block. |
| | 467 | |
| | 468 | @param url: Is the URL to read. |
| | 469 | @param data: Is the POST data. |
| | 470 | @param lines: return a list of lines, otherwise data block. |
| | 471 | @returns: reply from request |
| | 472 | """ |
| | 473 | _debug_('url=%r, lines=%r' % (url, lines), 1) |
| | 474 | request = urllib2.Request(url, headers=LastFMWebServices.headers) |
| | 475 | opener = urllib2.build_opener(SmartRedirectHandler()) |
| | 476 | try: |
| | 477 | if lines: |
| | 478 | reply = [] |
| | 479 | f = opener.open(request) |
| | 480 | lines = f.readlines() |
| | 481 | if lines is None: |
| | 482 | return [] |
| | 483 | for line in lines: |
| | 484 | reply.append(line.strip('\n')) |
| | 485 | _debug_('reply=%r' % (reply,), 1) |
| | 486 | else: |
| | 487 | reply = '' |
| | 488 | f = opener.open(request) |
| | 489 | reply = f.read() |
| | 490 | _debug_('len(reply)=%r' % (len(reply),), 1) |
| | 491 | return reply |
| | 492 | except urllib2.HTTPError, why: |
| | 493 | _debug_('%s: %s' % (url, why)) |
| | 494 | raise LastFMError(why, url) |
| | 495 | except Exception, why: |
| | 496 | _debug_('%s: %s' % (url, why)) |
| | 497 | raise LastFMError(why, url) |
| | 498 | |
| | 499 | |
| | 500 | @benchmark(benchmarking, benchmarkcall) |
| | 501 | def _login(self, arg=None): |
| | 502 | """Read session and stream url from ws.audioscrobbler.com""" |
| | 503 | _debug_('login(arg=%r)' % (arg,), 2) |
| | 504 | username = config.LASTFM_USER |
| | 505 | password_txt = config.LASTFM_PASS |
| | 506 | password = md5.new(config.LASTFM_PASS) |
| | 507 | login_url='http://ws.audioscrobbler.com/radio/handshake.php' + \ |
| | 508 | '?version=%s&platform=linux' % (LastFMWebServices._version) + \ |
| | 509 | '&username=%s&passwordmd5=%s' % (config.LASTFM_USER, password.hexdigest()) + \ |
| | 510 | '&debug=0&language=%s' % (config.LASTFM_LANG) |
| | 511 | stream_url = '' |
| | 512 | |
| | 513 | try: |
| | 514 | lines = self._urlopen(login_url) |
| | 515 | for line in lines: |
| | 516 | # this is a bit dangerous if a variable clashes |
| | 517 | exec('self.%s = "%s"' % tuple(line.split('=', 1))) |
| | 518 | # Save the lastfm session information |
| | 519 | fd = open(self.logincachefilename, 'w') |
| | 520 | print >>fd, self.session |
| | 521 | print >>fd, self.stream_url |
| | 522 | print >>fd, self.base_url |
| | 523 | print >>fd, self.base_path |
| | 524 | fd.close() |
| | 525 | except IOError, why: |
| | 526 | self.session = '' |
| | 527 | self.stream_url = '' |
| | 528 | self.base_url = '' |
| | 529 | self.base_path = '' |
| | 530 | |
| | 531 | |
| | 532 | @benchmark(benchmarking, benchmarkcall) |
| | 533 | def request_xspf(self): |
| | 534 | """Request a XSPF (XML Shareable Playlist File)""" |
| | 535 | _debug_('LastFMWebServices.request_xspf()', 1) |
| | 536 | if not self.session: |
| | 537 | self._login() |
| | 538 | request_url = 'http://%s%s/xspf.php?sk=%s&discovery=0&desktop=%s' % \ |
| | 539 | (self.base_url, self.base_path, self.session, LastFMWebServices._version) |
| | 540 | return self._urlopen(request_url, lines=False) |
| | 541 | |
| | 542 | |
| | 543 | @benchmark(benchmarking, benchmarkcall) |
| | 544 | def adjust_station(self, station_url): |
| | 545 | """Change Last FM Station""" |
| | 546 | _debug_('adjust_station(station_url=%r)' % (station_url,), 2) |
| | 547 | if not self.session: |
| | 548 | self._login() |
| | 549 | tune_url = 'http://ws.audioscrobbler.com/radio/adjust.php?session=%s&url=%s&lang=%s&debug=0' % \ |
| | 550 | (self.session, station_url, config.LASTFM_LANG) |
| | 551 | try: |
| | 552 | for line in self._urlopen(tune_url): |
| | 553 | if re.search('response=OK', line): |
| | 554 | return True |
| | 555 | return False |
| | 556 | except AttributeError, why: |
| | 557 | return None |
| | 558 | except IOError, why: |
| | 559 | return None |
| | 560 | |
| | 561 | |
| | 562 | @benchmark(benchmarking, benchmarkcall) |
| | 563 | def now_playing(self): |
| | 564 | """ |
| | 565 | Return Song Info and album Cover |
| | 566 | """ |
| | 567 | _debug_('now_playing()', 2) |
| | 568 | if not self.session: |
| | 569 | self._login() |
| | 570 | info_url = 'http://ws.audioscrobbler.com/radio/np.php?session=%s&debug=0' % (self.session,) |
| | 571 | reply = self._urlopen(info_url) |
| | 572 | if not reply or reply[0] == 'streaming=false': |
| | 573 | return None |
| | 574 | return reply |
| | 575 | |
| | 576 | |
| | 577 | @benchmark(benchmarking, benchmarkcall) |
| | 578 | def download(self, url, filename): |
| | 579 | """ |
| | 580 | Download album cover or track to last.fm directory. |
| | 581 | |
| | 582 | Add the session as a cookie to the request |
| | 583 | |
| | 584 | @param url: location of item to download |
| | 585 | @param filename: path to downloaded file |