diff --git a/.gitignore b/.gitignore index cdfb66c..4d86e47 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules/ popup/popup.css popup/popup.js +background/background.js dist/ build/ \ No newline at end of file diff --git a/README.md b/README.md index c458725..e924ca1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Shazam2Spotify ===================== -Chrome extension used to export your Shazam tags to a Spotify playlist. +Chrome extension used to sync your Shazam tags to a Spotify playlist. [![ScreenShot](https://raw.githubusercontent.com/leeroybrun/chrome-shazam2spotify/master/promo_1400x560.png)](http://youtu.be/Zi1VRJqEI0Q) @@ -46,3 +46,9 @@ grunt build ``` grunt bundle ``` + +## Roadmap for v0.2.0 + +- Add custom update scripts, this let us manage how to handle updates per version + - Should call all update scripts from current version to new version + - Update script for v0.2.0 : clear data \ No newline at end of file diff --git a/_locales/en/messages.json b/_locales/en/messages.json index afcb51f..d175b5b 100755 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1,8 +1,54 @@ { "appDesc": { - "message":"Export your Shazam tags to a new Spotify playlist", + "message":"Sync your Shazam tags to a Spotify playlist", "description":"The description of the application, displayed in the web store." }, + + "introWelcome": { + "message": "Welcome", + "description": "" + }, + "introWelcomeText": { + "message": "

In just a few seconds, your Shazam tags will be synched with Spotify.

First, we need to connect
to Shazam and Spotify services.

", + "description": "" + }, + "introStart": { + "message": "Start >", + "description": "" + }, + "introNext": { + "message": "Next >", + "description": "" + }, + "introShazamLoggedOutText": { + "message": "

First, we need to be logged in on Shazam.

Open the login page and click on the « Login » button.

Once done, you can open Shazam2Spotify again.

", + "description": "" + }, + "introShazamLoggedInText": { + "message": "

Congratulations !

You have successfully logged in to Shazam.

Now, let’s go to the next step...

", + "description": "" + }, + "introOpenShazamLogin": { + "message": "Open the login page", + "description": "" + }, + "introSpotifyLoggedOutText": { + "message": "

Finally, you need to let us create and manage a Spotify playlist.

Click on the following button, and then follow the onscreen instructions.

", + "description": "" + }, + "introSpotifyLoggedInText": { + "message": "

We are now ready to
sync your Shazam tags
with Spotify.

The first sync will start now.

Then, when you need to update your tags, just
open the extension again.

", + "description": "" + }, + "introOpenSpotifyLogin": { + "message": "Authorize app", + "description": "" + }, + "introEnd": { + "message": "Start synchronization >", + "description": "" + }, + "myTags": { "message": "My Shazam Tags", "description": "" @@ -89,6 +135,10 @@ "message": "Cancel", "description": "" }, + "advancedSettings": { + "message": "Advanced settings", + "description": "" + }, "clearData": { "message": "Clear all data", "description": "" @@ -96,5 +146,13 @@ "clearDataText": { "message": "If you have some troubles with the extension, you can clear all it's stored data here.", "description": "" + }, + "exportLogs": { + "message": "Export logs", + "description": "" + }, + "exportLogsText": { + "message": "If you need to debug the extension, you can export the logs here.", + "description": "" } } diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index a235611..84f893e 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -1,8 +1,54 @@ { "appDesc": { - "message":"Exportez vos tags Shazam dans une playlist Spotify", + "message":"Synchronisez vos tags Shazam dans une playlist Spotify", "description":"The description of the application, displayed in the web store." }, + + "introWelcome": { + "message": "Bienvenue", + "description": "" + }, + "introWelcomeText": { + "message": "

D’ici quelques secondes, vos tags Shazam seront synchronisés vers Spotify.

Pour commencer, nous devons connecter les différents services.

", + "description": "" + }, + "introStart": { + "message": "Commencer >", + "description": "" + }, + "introNext": { + "message": "Continuer >", + "description": "" + }, + "introShazamLoggedOutText": { + "message": "

Commencons par nous connecter à Shazam.

Ouvrez la page de connexion et cliquez sur le bouton « Connexion ».

Une fois connecté, ouvrez à nouveau Shazam2Spotify.

", + "description": "" + }, + "introShazamLoggedInText": { + "message": "

Félicitations !

Vous êtes bien connecté
à Shazam.

Passons maintenant à la suite...

", + "description": "" + }, + "introOpenShazamLogin": { + "message": "Ouvrir la page de connexion", + "description": "" + }, + "introSpotifyLoggedOutText": { + "message": "

Pour terminer, vous devez nous autoriser à créer et gérer une playlist Spotify.

Cliquez sur le bouton ci-dessous, puis suivez les instructions affichées.

", + "description": "" + }, + "introSpotifyLoggedInText": { + "message": "

Nous sommes prêts à synchroniser vos tags Shazam dans Spotify.

La première synchronisation va maintenant s’effectuer.

Il vous suffira ensuite d’ouvrir à nouveau l’extension pour les
mettre à jour.

", + "description": "" + }, + "introOpenSpotifyLogin": { + "message": "Autoriser l’application", + "description": "" + }, + "introEnd": { + "message": "Lancer la synchronisation >", + "description": "" + }, + "myTags": { "message": "Mes tags Shazam", "description": "" @@ -89,6 +135,10 @@ "message": "Annuler", "description": "" }, + "advancedSettings": { + "message": "Paramètres avancés", + "description": "" + }, "clearData": { "message": "Effacer toutes les données", "description": "" @@ -96,5 +146,13 @@ "clearDataText": { "message": "Si vous avez des problèmes avec l'extension, vous pouvez effacer toutes les données enregistrées ici.", "description": "" + }, + "exportLogs": { + "message": "Exporter les logs", + "description": "" + }, + "exportLogsText": { + "message": "Afin de déceler et débugger d'éventuels problèmes, vous pouvez exporter les logs de l'application.", + "description": "" } } diff --git a/background/.gitkeep b/background/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/gruntfile.js b/gruntfile.js index 388066a..6e2f95c 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -5,12 +5,12 @@ module.exports = function(grunt) { archive_name: 'shazam2spotify-<%= pkg.version %>', jshint: { globals: { angular: true }, - all: ['gruntfile.js', 'src/popup/js/**/*.js'], + all: ['gruntfile.js', 'src/popup/js/**/*.js', 'src/background/**/*.js'], gruntfile: ['gruntfile.js'] }, concat: { options: { - separator: ';', + separator: '\n\n', }, css: { files: { @@ -22,6 +22,19 @@ module.exports = function(grunt) { 'popup/popup.js': [ 'src/popup/js/app.js', 'src/popup/js/**/*.js' + ], + 'background/background.js': [ + 'src/background/lib/*.js', + 'src/background/background.js', + 'src/background/Helper.js', + 'src/background/ChromeHelper.js', + 'src/background/CanvasIcon.js', + 'src/background/LoggerService.js', + 'src/background/StorageHelper.js', + 'src/background/SpotifyService.js', + 'src/background/ShazamService.js', + 'src/background/TagsService.js', + 'src/background/UpdateService.js', ] } } @@ -42,7 +55,7 @@ module.exports = function(grunt) { } }, js: { - files: ['src/popup/js/**/*.js'], + files: ['src/popup/js/**/*.js', 'src/background/**/*.js'], tasks: ['build:js'], options: { spawn: false, @@ -72,6 +85,7 @@ module.exports = function(grunt) { files: [ {expand: true, src: ['_locales/**'], dest: 'build/'}, {expand: true, src: ['icons/**'], dest: 'build/'}, + {expand: true, src: ['background/**'], dest: 'build/'}, {expand: true, src: ['popup/**'], dest: 'build/'}, {expand: true, src: ['LICENCE'], dest: 'build/'}, {expand: true, src: ['manifest.json'], dest: 'build/'}, diff --git a/manifest.json b/manifest.json index d38c3df..56e0d3d 100755 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "Shazam2Spotify", - "version": "0.1.6", + "version": "0.2.0", "manifest_version": 2, "description": "__MSG_appDesc__", "homepage_url": "http://www.leeroy.me", @@ -10,6 +10,9 @@ "128": "icons/icon128.png" }, "default_locale": "en", + "background": { + "scripts": ["background/background.js"] + }, "browser_action": { "default_icon": "icons/icon19.png", "default_title": "Shazam2Spotify", @@ -19,10 +22,11 @@ "tabs", "identity", "storage", + "background", "http://www.shazam.com/*", "https://www.shazam.com/*", "https://api.spotify.com/*", "https://accounts.spotify.com/api/*" ], - "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'" + "content_security_policy": "script-src 'self' https://ssl.google-analytics.com https://fonts.googleapis.com; object-src 'self'" } \ No newline at end of file diff --git a/package.json b/package.json index 0d1546a..ce5330f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chrome-shazam2spotify", - "version": "0.1.6", + "version": "0.2.0", "author": "Leeroy Brun ", "private": true, "description": "Chrome extension used to export your Shazam tags to a Spotify playlist", diff --git a/popup/img/placeholder.png b/popup/img/placeholder.png new file mode 100644 index 0000000..2bc8298 Binary files /dev/null and b/popup/img/placeholder.png differ diff --git a/popup/img/spiffygif_22x22.gif b/popup/img/spiffygif_22x22.gif new file mode 100644 index 0000000..2cee883 Binary files /dev/null and b/popup/img/spiffygif_22x22.gif differ diff --git a/popup/lib/angulartics-ga.min.js b/popup/lib/angulartics-ga.min.js new file mode 100755 index 0000000..9758cbe --- /dev/null +++ b/popup/lib/angulartics-ga.min.js @@ -0,0 +1,7 @@ +/** + * @license Angulartics v0.17.0 + * (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics + * Universal Analytics update contributed by http://github.com/willmcclellan + * License: MIT + */ +!function(a){"use strict";a.module("angulartics.google.analytics",["angulartics"]).config(["$analyticsProvider",function(a){a.settings.trackRelativePath=!0,a.registerPageTrack(function(a){window._gaq&&_gaq.push(["_trackPageview",a]),window.ga&&ga("send","pageview",a)}),a.registerEventTrack(function(a,b){if(b&&b.category){if(b.value){var c=parseInt(b.value,10);b.value=isNaN(c)?0:c}if(window._gaq)_gaq.push(["_trackEvent",b.category,a,b.label,b.value,b.noninteraction]);else if(window.ga){for(var d={eventCategory:b.category||null,eventAction:a||null,eventLabel:b.label||null,eventValue:b.value||null,nonInteraction:b.noninteraction||null},e=1;20>=e;e++)b["dimension"+e.toString()]&&(d["dimension"+e.toString()]=b["dimension"+e.toString()]),b["metric"+e.toString()]&&(d["metric"+e.toString()]=b["metric"+e.toString()]);ga("send","event",d)}}})}])}(angular); \ No newline at end of file diff --git a/popup/lib/angulartics.min.js b/popup/lib/angulartics.min.js new file mode 100755 index 0000000..3d85e00 --- /dev/null +++ b/popup/lib/angulartics.min.js @@ -0,0 +1,6 @@ +/** + * @license Angulartics v0.17.0 + * (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics + * License: MIT + */ +!function(a){"use strict";var b=window.angulartics||(window.angulartics={});b.waitForVendorCount=0,b.waitForVendorApi=function(a,c,d,e,f){f||b.waitForVendorCount++,e||(e=d,d=void 0),!Object.prototype.hasOwnProperty.call(window,a)||void 0!==d&&void 0===window[a][d]?setTimeout(function(){b.waitForVendorApi(a,c,d,e,!0)},c):(b.waitForVendorCount--,e(window[a]))},a.module("angulartics",[]).provider("$analytics",function(){var c={pageTracking:{autoTrackFirstPage:!0,autoTrackVirtualPages:!0,trackRelativePath:!1,autoBasePath:!1,basePath:""},eventTracking:{},bufferFlushDelay:1e3},d=["pageTrack","eventTrack","setAlias","setUsername","setUserProperties","setUserPropertiesOnce","setSuperProperties","setSuperPropertiesOnce"],e={},f={},g=function(a){return function(){b.waitForVendorCount&&(e[a]||(e[a]=[]),e[a].push(arguments))}},h=function(b,c){return f[b]||(f[b]=[]),f[b].push(c),function(){var c=arguments;a.forEach(f[b],function(a){a.apply(this,c)},this)}},i={settings:c},j=function(a,b){b?setTimeout(a,b):a()},k={$get:function(){return i},api:i,settings:c,virtualPageviews:function(a){this.settings.pageTracking.autoTrackVirtualPages=a},firstPageview:function(a){this.settings.pageTracking.autoTrackFirstPage=a},withBase:function(b){this.settings.pageTracking.basePath=b?a.element("base").attr("href").slice(0,-1):""},withAutoBase:function(a){this.settings.pageTracking.autoBasePath=a}},l=function(b,d){i[b]=h(b,d);var f=c[b],g=f?f.bufferFlushDelay:null,k=null!==g?g:c.bufferFlushDelay;a.forEach(e[b],function(a,b){j(function(){d.apply(this,a)},b*k)})},m=function(a){return a.replace(/^./,function(a){return a.toUpperCase()})},n=function(a){var b="register"+m(a);k[b]=function(b){l(a,b)},i[a]=h(a,g(a))};return a.forEach(d,n),k}).run(["$rootScope","$location","$window","$analytics","$injector",function(a,b,c,d,e){if(d.settings.pageTracking.autoTrackFirstPage){var f=!0;if(e.has("$route")){var g=e.get("$route");for(var h in g.routes){f=!1;break}}else if(e.has("$state")){var i=e.get("$state");for(var j in i.get()){f=!1;break}}if(f)if(d.settings.pageTracking.autoBasePath&&(d.settings.pageTracking.basePath=c.location.pathname),d.settings.trackRelativePath){var k=d.settings.pageTracking.basePath+b.url();d.pageTrack(k)}else d.pageTrack(b.absUrl())}d.settings.pageTracking.autoTrackVirtualPages&&(d.settings.pageTracking.autoBasePath&&(d.settings.pageTracking.basePath=c.location.pathname+"#"),e.has("$route")&&a.$on("$routeChangeSuccess",function(a,c){if(!c||!(c.$$route||c).redirectTo){var e=d.settings.pageTracking.basePath+b.url();d.pageTrack(e)}}),e.has("$state")&&a.$on("$stateChangeSuccess",function(){var a=d.settings.pageTracking.basePath+b.url();d.pageTrack(a)}))}]).directive("analyticsOn",["$analytics",function(b){function c(a){return["a:","button:","button:button","button:submit","input:button","input:submit"].indexOf(a.tagName.toLowerCase()+":"+(a.type||""))>=0}function d(a){return c(a)?"click":"click"}function e(a){return c(a)?a.innerText||a.value:a.id||a.name||a.tagName}function f(a){return"analytics"===a.substr(0,9)&&-1===["On","Event","If","Properties","EventType"].indexOf(a.substr(9))}function g(a){var b=a.slice(9);return"undefined"!=typeof b&&null!==b&&b.length>0?b.substring(0,1).toLowerCase()+b.substring(1):b}return{restrict:"A",scope:!0,link:function(c,h,i){var j=i.analyticsOn||d(h[0]);c.$analytics={},a.forEach(i.$attr,function(a,b){f(b)&&(c.$analytics[g(b)]=i[b],i.$observe(b,function(a){c.$analytics[g(b)]=a}))}),a.element(h[0]).bind(j,function(d){var f=i.analyticsEvent||e(h[0]);c.$analytics.eventType=d.type,(!i.analyticsIf||c.$eval(i.analyticsIf))&&(i.analyticsProperties&&a.extend(c.$analytics,c.$eval(i.analyticsProperties)),b.eventTrack(f,c.$analytics))})}}}])}(angular); \ No newline at end of file diff --git a/popup/lib/ga.js b/popup/lib/ga.js new file mode 100644 index 0000000..24c84ff --- /dev/null +++ b/popup/lib/ga.js @@ -0,0 +1,8 @@ +var _gaq = _gaq || []; +_gaq.push(['_setAccount', 'UA-57493072-3']); + +(function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); +})(); \ No newline at end of file diff --git a/popup/partials/intro.html b/popup/partials/intro.html new file mode 100644 index 0000000..df4bf26 --- /dev/null +++ b/popup/partials/intro.html @@ -0,0 +1,53 @@ +
+
+
+

introWelcome

+
introWelcomeText
+ +
+
+
+
+

+ + + + + + + + + Shazam +

+
introShazamLoggedOutText
+
introShazamLoggedInText
+ +
+
+
+
+

+ + + + + + + + + Spotify +

+
introSpotifyLoggedOutText
+
introSpotifyLoggedInText
+ +
+
+
\ No newline at end of file diff --git a/popup/partials/settings.html b/popup/partials/settings.html index 45c5f04..a3c2797 100644 --- a/popup/partials/settings.html +++ b/popup/partials/settings.html @@ -1,5 +1,5 @@
- backToTags + backToTags
@@ -14,69 +14,57 @@

settings

loginStatus