Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .csslintrc

This file was deleted.

14 changes: 2 additions & 12 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module.exports = function(grunt) {
var jsConnectorFiles = ['connectors/v2/*.js', 'connectors/22tracks.js', 'connectors/archive.js', 'connectors/bandcamp.js', 'connectors/blinkboxmusic.js', 'connectors/ambientsleepingpill.js']; // intentionally does not contain all files yet
var jsCoreFiles = ['Gruntfile.js', 'popup.js', 'core/**/*.js', 'options/options.js', 'popups/*.js'];
var jsonFiles = ['*.json', '.jshintrc'];
var htmlFiles = ['*.html', 'options/*.html', 'popups/*.html', 'dialogs/**/*.html'];
var cssFiles = ['options/options.css', 'popups/base.css', 'dialogs/base.css'];

grunt.initConfig({
Expand All @@ -30,7 +29,7 @@ module.exports = function(grunt) {
lintspaces: {
all: {
src: [
jsCoreFiles, jsConnectorFiles, cssFiles, htmlFiles
jsCoreFiles, jsConnectorFiles, cssFiles
],

options: {
Expand All @@ -45,14 +44,6 @@ module.exports = function(grunt) {
sample: {
src: [ jsonFiles ]
}
},
csslint: {
options: {
csslintrc: '.csslintrc'
},
strict: {
src: [cssFiles]
}
}
});

Expand All @@ -61,7 +52,6 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-lintspaces');
grunt.loadNpmTasks('grunt-jsonlint');
grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.registerTask('lint', ['jshint', 'csslint']);
grunt.registerTask('lint', ['jshint']);
grunt.registerTask('default', ['lint', 'lintspaces', 'jsonlint']);
};
140 changes: 140 additions & 0 deletions connectors/8tracks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Chrome-Last.fm-Scrobbler 8tracks Connector
*
* Matt Runkle - matt[at]mrunkle[dot]com
*
*/

/*** Configuration ***/

// Additions to this div will trigger update
WATCHED_CONTAINER = "#tracks_played";

// Returns the currently playing artist name
function getArtist( ) {
return cleanLabel( $("#now_playing div.title_artist > span.a:first").text() );
}

// Returns the currently playing track title
function getTrack( ) {
return cleanLabel( $("#now_playing div.title_artist > span.t:first").text() );
}

function getAlbum( ) {
return cleanLabel( $("#now_playing div.album > span.detail:first").text() );
}

// Returns the number of pixels denoting the time expired in the song
function getPercentDone( ) {
var width = parseInt( $("div#player_progress_bar").width() );
return parseInt( $("div#player_progress_bar_meter").width() ) / width;
}

// Perform some common cleanup of artist/song/album strings
function cleanLabel( label ) {
label = label.replace( '&', '&' );
return $.trim( label );
}

/*** Scrobbler Interface ***/
LAST_TRACK = "";
TIMEOUT = "";

TIME_PERCENT = 10;
START_TIME = 0;

// Since we can't just pull the song duration from the DOM
// we need to estimate. Luckily there is a nice progress bar
function tryScrobble() {
var ratio = getPercentDone();

if ( ratio > (1/TIME_PERCENT) ) {
// Measured enough, estimate time and scrobble
var endTime = new Date().getTime();
var elapsed = (endTime - START_TIME) / 1000;

TIMEOUT = "";
START_TIME = 0;
updateNowPlaying(elapsed);
return;
}

// Set timeout based on about how long we have left, max 50s / percent
TIMEOUT = setTimeout( tryScrobble, Math.min(500 / ratio, 50000 / TIME_PERCENT) );
}

// Validates and scrobbles the currently playing song
function updateNowPlaying(elapsed) {
elapsed = Math.floor(elapsed);
var duration = elapsed * TIME_PERCENT;
var title = getTrack();
var artist = getArtist();
var album = getAlbum();
var newTrack = title + " " + artist;

// Update scrobbler if necessary
if ( newTrack != " " && newTrack != LAST_TRACK ) {
//console.log("Submitting a now playing request. artist: "+artist+", title: "+title+", album: " + album + ", duration: " + duration);

LAST_TRACK = newTrack;
chrome.runtime.sendMessage({type: 'validate', artist: artist, track: title}, function(response) {
if (response != false) {
// submit the validated song for scrobbling
var song = response;
chrome.runtime.sendMessage({type: 'nowPlaying', artist: song.artist, track: song.track,
album: (album === "") ? null : album, currentTime: elapsed, duration: duration});
} else {
// on failure send nowPlaying 'unknown song'
console.log( "Song validation failed!" );
chrome.runtime.sendMessage({type: 'nowPlaying', currentTime: elapsed, duration: duration});
}
});
}
}

function triggerUpdate() {
var nowPlaying = getTrack() + " " + getArtist();

if ( nowPlaying != " " && nowPlaying != LAST_TRACK ) {
START_TIME = new Date().getTime();

// Stop any non-scrobbled songs (i.e. song skipped)
if( TIMEOUT != "" ) {
clearTimeout( TIMEOUT );
}

// Schedule the next scrobble
TIMEOUT = setTimeout( tryScrobble, 500 );

return;
}
}

// Attach listener for song changes, filter out duplicate event firings
$(function(){
console.log("8tracks module starting up");

// Attach listener to "recently played" song list
$(WATCHED_CONTAINER).live('DOMNodeInserted', function(e) {
setTimeout( triggerUpdate, 500 ); // let player update
});

$(window).unload(function() {
chrome.runtime.sendMessage({type: 'reset'});
return true;
});
});

/**
* Listen for requests from scrobbler.js
*/
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
switch(request.type) {
// background calls this to see if the script is already injected
case 'ping':
sendResponse(true);
break;
}
}
);
112 changes: 112 additions & 0 deletions connectors/archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Chrome-Last.fm-Scrobbler archive.org Connector by Malachi Soord
* (based on George Pollard's bandcamp connctor)
* v0.1
*/
'use strict';

var lastTrack = null;

$(function () {
// bind page unload function to discard current "now listening"
cancel();
});

var durationElapsed = '#jw6_controlbar_elapsed';
var durationTotal = '#jw6_controlbar_duration';
var durationRegex = /(\d+):(\d+)/;

function parseDuration(elapsed, total) {
try {
var mEla = durationRegex.exec(elapsed);
var mTot = durationRegex.exec(total);
return {
current: parseInt(mEla[1], 10) * 60 + parseInt(mEla[2], 10),
total: parseInt(mTot[1], 10) * 60 + parseInt(mTot[2], 10)
};
} catch (err) {
return 0;
}
}

function parseArtist() {
return $('span.key:contains("Artist/Composer:"), span.key:contains("Band/Artist:")').next().text();
}

function parseTitle() {

// Get title directly from player
var title = $('.playing > .ttl').text();

// Some titles are stored as artist - track # - title so strip out non-title elements
var parts = title.split('-');
if (parts.length === 3 && parts[0].trim() === parseArtist()) {
title = parts[2].trim();
}

return title;
}

function parseAlbum() {
var album = $('.x-archive-meta-title').text();

// Remove artist from album
var parts = album.split('-');
if (parts.length > 0 && parts[0].trim() === parseArtist()) {
album = album.substr(album.indexOf('-') + 1).trim();
}

return album;
}

function cancel() {
$(window).unload(function () {
// reset the background scrobbler song data
chrome.runtime.sendMessage({
type: 'reset'
});
return true;
});
}

// console.log('Archive.org: loaded');

$(durationElapsed).live('DOMSubtreeModified', function () {

var duration = parseDuration($(durationElapsed).text(), $(durationTotal).text());

// console.log('duration - ' + duration.current + ' / ' + duration.total);

if (duration.current > 0) { // it's playing

var artist = parseArtist();
var track = parseTitle();
var album = parseAlbum();

if (lastTrack !== track) {
lastTrack = track;

console.log('Archive.org: scrobbling - Artist: ' + artist + '; Album: ' + album + '; Track: ' + track + '; duration: ' + duration.total);
chrome.runtime.sendMessage({
type: 'validate',
artist: artist,
track: track
}, function (response) {
if (response !== false) {
chrome.runtime.sendMessage({
type: 'nowPlaying',
artist: response.artist,
track: response.track,
duration: duration.total,
album: album
});
} else {
chrome.runtime.sendMessage({
type: 'nowPlaying',
duration: duration.total
});
}
});
}
}
});
95 changes: 95 additions & 0 deletions connectors/turntable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Chrome-Last.fm-Scrobbler TurnTable.FM Connector
*
* Matt Runkle - matt[at]mrunkle[dot]com
*
* Inspired by Pandora connector, written by Jordan Perr, jordan[at]jperr[dot]com
*/

/*** Configuration ***/

// Additions to this div will trigger update
TT_WATCHED_CONTAINER = "div#song-log";

// Returns the currently playing artist name
function TT_getArtist( ) {
var details = $("div#song-log div.details span:first").html();
return TT_cleanLabel( details.replace(/^|<span.*\d+:\d+$/g, '') );
}

// Returns the currently playing track title
function TT_getTrack( ) {
return TT_cleanLabel( $("div#song-log div.title:first").text() );
}

// Returns the number of seconds left in the song
function TT_getTimeLeft( ) {
var remainingArr = $("div#time-left").text().split(":");
return parseInt( remainingArr[0] ) * 60 + parseInt( remainingArr[1] );
}

// Perform some common cleanup of artist/song strings
function TT_cleanLabel( label ) {
label = label.replace( '&amp;', '&' );
return $.trim( label );
}

/*** Scrobbler Interface ***/
TT_LAST_TRACK = "";
TT_TIMEOUT = "";


// Validates and scrobbles the currently playing song
function TT_updateNowPlaying() {
var title = TT_getTrack();
var artist = TT_getArtist();
var duration = TT_getTimeLeft();
var newTrack = title + " " + artist;

// Update scrobbler if necessary
if ( newTrack != " " && newTrack != TT_LAST_TRACK ) {
//console.log("Submitting a now playing request. artist: "+artist+", title: "+title+", duration: "+duration);

TT_LAST_TRACK = newTrack;
chrome.runtime.sendMessage({type: 'validate', artist: artist, track: title}, function(response) {
if (response != false) {
// submit the validated song for scrobbling
var song = response;
chrome.runtime.sendMessage({type: 'nowPlaying', artist: song.artist, track: song.track, duration: duration});
} else {
// on failure send nowPlaying 'unknown song'
console.log( "Song validation failed!" );
chrome.runtime.sendMessage({type: 'nowPlaying', duration: duration});
}
});
}
}

// Attach listener for song changes, filter out duplicate event firings
$(function(){
console.log("TurnTable.fm module starting up");

// Attach listener to "recently played" song list
$(TT_WATCHED_CONTAINER).live('DOMNodeInserted', function(e) {
//console.log( "Update triggered" );

var nowPlaying = TT_getTrack() + " " + TT_getArtist();

if ( nowPlaying != " " && nowPlaying != TT_LAST_TRACK ) {
// Stop any non-scrobbled songs (i.e. song skipped)
if( TT_TIMEOUT != "" ) {
clearTimeout( TT_TIMEOUT );
}

// Schedule the next scrobble
TT_TIMEOUT = setTimeout( TT_updateNowPlaying, 10000 );

return;
}
});

$(window).unload(function() {
chrome.runtime.sendMessage({type: 'reset'});
return true;
});
});
Loading