Commit 574829dd authored by Mitchell Augustin's avatar Mitchell Augustin

Added files to repository

parents
node_modules/
This diff is collapsed.
#Spotify Playlist Analyzer
Copyright 2017 Mitchell Augustin
A simple graphical analyzer for Spotify playlists that represents the artists of any playlist graphically.
http://playlistanalyzer.mitchellaugustin.com
This program is free to use & modify. By using this program, you agree to the terms of the Apache License v 2.0 as well as the Spotify terms of use.
/**
* This is an example of a basic node.js script that performs
* the Authorization Code oAuth2 flow to authenticate against
* the Spotify Accounts.
*
* For more information, read
* https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow
*/
var express = require('express'); // Express web server framework
var request = require('request'); // "Request" library
var querystring = require('querystring');
var cookieParser = require('cookie-parser');
var client_id = '8568cf489b66452584b9eccf1917d67a'; // Your client id
var client_secret = 'd27ed87cbf1d488880e2aff44993bc6e'; // Your secret
var redirect_uri = 'http://server.mitchellaugustin.com:8888/callback'; // Your redirect uri
/**
* Generates a random string containing numbers and letters
* @param {number} length The length of the string
* @return {string} The generated string
*/
var generateRandomString = function(length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var stateKey = 'spotify_auth_state';
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cookieParser());
app.get('/login', function(req, res) {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// your application requests authorization
var scope = 'user-read-private user-read-email playlist-read-private playlist-read-collaborative';
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
var code = req.query.code || null;
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
if (state === null || state !== storedState) {
res.redirect('/#' +
querystring.stringify({
error: 'state_mismatch'
}));
} else {
res.clearCookie(stateKey);
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: redirect_uri,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token,
refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
// we can also pass the token to the browser to make requests from there
res.redirect('/#' +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token
}));
} else {
res.redirect('/#' +
querystring.stringify({
error: 'invalid_token'
}));
}
});
}
});
app.get('/refresh_token', function(req, res) {
// requesting access token from refresh token
var refresh_token = req.query.refresh_token;
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.send({
'access_token': access_token
});
}
});
});
console.log('Listening on 8888');
app.listen(8888);
{
"directory": "site/bower_components"
}
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
# modules
node_modules/
site/bower_components/
# build
.tmp/
.public/
# dist/
# generated
.sass-cache
# debug
npm-debug.log
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": false,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"latedef": true,
"newcap": false,
"noarg": true,
"quotmark": "single",
"regexp": true,
"undef": true,
"unused": true,
"strict": true,
"validthis": true,
"trailing": true,
"smarttabs": true,
"globals": {
"angular": false,
"jQuery": false,
"$": false,
"SVG": false,
"Snap": false,
"Foundation": false
}
}
language: node_js
node_js:
- '5.5.0'
before_script:
- 'npm install -g bower grunt-cli'
- 'bower install'
This diff is collapsed.
This diff is collapsed.
# Contributing to chartist-js
- [Issues and Bugs](#issue)
- [Submission Guidelines](#submit)
- [Coding Conventions](#conventions)
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
## Pre-requisites
You will need the following to run a local development enviroment.
- Node.js & npm
- Bower (`sudo npm install bower -g`)
- Grunt (`sudo npm install grunt-cli -g`)
- Text editor of your choice
## How to Run a Local Distribution
1. `cd` into your local copy of the repository.
2. Run `npm install` to install dependencies located in `package.json`.
3. Run `bower install` to install bower dependencies.
5. Run `grunt preview` to start the watch task, and the web server should automatically open. Congrats, you should now be able to see your local copy of the demo site.
## <a name="submit"></a> Submission Guidelines
If you are creating a Pull Request, fork the repository and make any changes on the `develop` branch.
### <a name="conventions"></a> Conventions
Check out the [Coding Style document](CODINGSTYLE.md)
### Grunt
We have five grunt tasks:
1. `grunt build` - Combines the scripts and creates the library for distribution
2. `grunt public` - Creates the distribution of the example / demo site which is used as visual development help of the charts but also serves as the documentation site / gh-pages.
3. `grunt dev` - Starts watch with livereload that is executing the same things as the site build default task but for live development.
4. `grunt preview` - Executes a dist and serves the directory statically in order to serve with the production example / demo site.
5. `grunt test` - Executes jasmine tests separately, although we have a very big lack of tests.
`dist` should **not** be included in any Pull Requests. So please ensure that code is not being committed as part of the Pull Request.
### Documentation
- Everything is already in place and in the `sitedist` there is a `apidoc` folder generated by [doxication](https://github.com/gionkunz/grunt-doxication) generator that uses JSDoc like comments to generate documentation meta files. Always use proper JSDoc comments when documenting methods and API interfaces. Also assign documentation blocks using @memberof to the virtual module they belong to.
- The site documentation is built with [Assemble.io](http://assemble.io/). Generally a component based approach should be followed where there are already Handlebar partials / helpers in order to create whole sites based on components that can be specified by type and with their data in yaml files.
### Important missing stuff
1. Jasmine Tests!
2. Documentation: JSDoc, Getting started documentation and landing page
3. Better accessibility using ARIA and other optimizations
4. Better interfaces to the library (i.e. jQuery with data-* attributes for configuration), Angular.js directive etc.
5. Richer Sass / CSS framework
6. Other charts types (spider etc.)
/**
* Grunt Configurations
* ====================
*
* Seperate tasks and configurations are declared in '/tasks'.
*
* Link: https://github.com/firstandthird/load-grunt-config
*/
'use strict';
module.exports = function (grunt) {
// tracks how long a tasks take
require('time-grunt')(grunt);
// load task and configurations
require('load-grunt-config')(grunt, {
configPath: __dirname + '/tasks',
data: {
pkg: grunt.file.readJSON('package.json'),
year: new Date().getFullYear()
},
jitGrunt: {
staticMappings: {
'useminPrepare': 'grunt-usemin',
'assemble': 'assemble'
}
}
});
};
Copyright (c) 2013 Gion Kunz <gion.kunz@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
# Big welcome by the Chartist Guy
[![Join the chat at https://gitter.im/gionkunz/chartist-js](https://badges.gitter.im/gionkunz/chartist-js.svg)](https://gitter.im/gionkunz/chartist-js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](http://img.shields.io/npm/v/chartist.svg)](https://npmjs.org/package/chartist) [![build status](http://img.shields.io/travis/gionkunz/chartist-js.svg)](https://travis-ci.org/gionkunz/chartist-js) [![Inline docs](http://inch-ci.org/github/gionkunz/chartist-js.svg?branch=develop)](http://inch-ci.org/github/gionkunz/chartist-js)
![The Chartist Guy](https://raw.github.com/gionkunz/chartist-js/develop/site/images/chartist-guy.gif "The Chartist Guy")
*Checkout the documentation site at http://gionkunz.github.io/chartist-js/*
*Checkout this lightning talk that gives you an overview of Chartist in 5 minutes https://www.youtube.com/watch?v=WdYzPhOB_c8*
*Guest talk of the Chartist.js Guy at the Treehouse Show https://www.youtube.com/watch?v=h9oH0iDaZDQ&t=2m40s*
Chartist.js is a simple responsive charting library built with SVG. There are hundreds of nice charting libraries already
out there, but they are either:
* not responsive
* use the wrong technologies for illustration (canvas)
* are not flexible enough while keeping the configuration simple
* are not friendly to your own code
* are not friendly to designers
* have unnecessary dependencies to monolithic libraries
* more annoying things
That's why we started Chartist.js and our goal is to solve all of the above issues.
## What is it made for?
Chartist's goal is to provide a simple, lightweight and unintrusive library to responsively craft charts on your website.
It's important to understand that one of the main intentions of Chartist.js is to rely on standards rather than providing
it's own solution to a problem which is already solved by those standards. We need to leverage the power of browsers
today and say good bye to the idea of solving all problems ourselves.
Chartist works with inline-SVG and therefore leverages the power of the DOM to provide parts of its functionality. This
also means that Chartist does not provide it's own event handling, labels, behaviors or anything else that can just be
done with plain HTML, JavaScript and CSS. The single and only responsibility of Chartist is to help you drawing "Simple
responsive Charts" using inline-SVG in the DOM, CSS to style and JavaScript to provide an API for configuring your charts.
## Example site
You can visit this Site http://gionkunz.github.io/chartist-js/ which is in fact a build of the current project.
We are still developing and constantly add features but you can already use Chartist.js in your projects as we have
reached a stable and reliable state already.
## Version notes
We are currently still heavily developing in order to make Chartist.js better. Your help is needed! Please contribute
to the project if you like the idea and the concept and help us to bring nice looking responsive open-source charts
to the masses.
### Important missing stuff
1. Jasmine Tests!
2. Documentation: JSDoc, Getting started documentation and landing page
3. Better accessibility using ARIA and other optimizations
4. Better interfaces to the library (i.e. jQuery with data-* attributes for configuration), Angular.js directive etc.
5. Richer Sass / CSS framework
6. Other charts types (spider etc.)
## Plugins
Some features aren't right for the core product
but there is a great set of plugins available
which add features like:
* [Axis labels](http://gionkunz.github.io/chartist-js/plugins.html#axis-title-plugin)
* [Tooltips at data points](https://gionkunz.github.io/chartist-js/plugins.html#tooltip-plugin)
* [Coloring above/below a threshold](https://gionkunz.github.io/chartist-js/plugins.html#threshold-plugin)
and more.
See all the plugins [here](https://gionkunz.github.io/chartist-js/plugins.html).
## Contribution
We are looking for people who share the idea of having a simple, flexible charting library that is responsive and uses
modern and future-proof technologies. The goal of this project is to create a responsive charting library where developers
have their joy in using it and designers love it because of the designing flexibility they have.
Contribute if you like the Chartist Guy!
{
"name": "chartist",
"main": [
"./dist/chartist.js",
"./dist/chartist.css"
],
"devDependencies": {
"snap.svg": "~0.3.0",
"foundation": "~5.5.1",
"highlightjs": "~8.4.0",
"compass-mixins": "~1.0.2",
"codemirror": "~4.12.0",
"base64": "~0.3.0",
"chartist-plugin-pointlabels": "~0.0.4",
"chartist-plugin-accessibility": "~0.0.2",
"chartist-plugin-tooltip": "~0.0.12",
"chartist-plugin-axistitle": "~0.0.1",
"chartist-plugin-threshold": "~0.0.1",
"chartist-plugin-fill-donut": "~0.0.1",
"chartist-plugin-zoom": "~0.2.1",
"matchMedia": "~0.2.0",
"moment": "^2.14.1"
},
"ignore": [
".*",
"Gruntfile.js",
"tasks",
"package.json",
"node_modules",
"public",
"site",
"src",
"test"
],
"resolutions": {
"chartist": "~0.9.0"
}
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
@import "settings/chartist-settings";
@mixin ct-responsive-svg-container($width: 100%, $ratio: $ct-container-ratio) {
display: block;
position: relative;
width: $width;
&:before {
display: block;
float: left;
content: "";
width: 0;
height: 0;
padding-bottom: $ratio * 100%;
}
&:after {
content: "";
display: table;
clear: both;
}
> svg {
display: block;
position: absolute;
top: 0;
left: 0;
}
}
@mixin ct-align-justify($ct-text-align: $ct-text-align, $ct-text-justify: $ct-text-justify) {
-webkit-box-align: $ct-text-align;
-webkit-align-items: $ct-text-align;
-ms-flex-align: $ct-text-align;
align-items: $ct-text-align;
-webkit-box-pack: $ct-text-justify;
-webkit-justify-content: $ct-text-justify;
-ms-flex-pack: $ct-text-justify;
justify-content: $ct-text-justify;
// Fallback to text-align for non-flex browsers
@if($ct-text-justify == 'flex-start') {
text-align: left;
} @else if ($ct-text-justify == 'flex-end') {
text-align: right;
} @else {
text-align: center;
}
}
@mixin ct-flex() {
// Fallback to block
display: block;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
@mixin ct-chart-label($ct-text-color: $ct-text-color, $ct-text-size: $ct-text-size, $ct-text-line-height: $ct-text-line-height) {
fill: $ct-text-color;
color: $ct-text-color;
font-size: $ct-text-size;
line-height: $ct-text-line-height;
}
@mixin ct-chart-grid($ct-grid-color: $ct-grid-color, $ct-grid-width: $ct-grid-width, $ct-grid-dasharray: $ct-grid-dasharray) {
stroke: $ct-grid-color;
stroke-width: $ct-grid-width;
@if ($ct-grid-dasharray) {
stroke-dasharray: $ct-grid-dasharray;
}
}
@mixin ct-chart-point($ct-point-size: $ct-point-size, $ct-point-shape: $ct-point-shape) {
stroke-width: $ct-point-size;
stroke-linecap: $ct-point-shape;
}
@mixin ct-chart-line($ct-line-width: $ct-line-width, $ct-line-dasharray: $ct-line-dasharray) {
fill: none;
stroke-width: $ct-line-width;
@if ($ct-line-dasharray) {
stroke-dasharray: $ct-line-dasharray;
}
}
@mixin ct-chart-area($ct-area-opacity: $ct-area-opacity) {
stroke: none;
fill-opacity: $ct-area-opacity;
}
@mixin ct-chart-bar($ct-bar-width: $ct-bar-width) {
fill: none;
stroke-width: $ct-bar-width;
}
@mixin ct-chart-donut($ct-donut-width: $ct-donut-width) {
fill: none;
stroke-width: $ct-donut-width;
}
@mixin ct-chart-series-color($color) {
.#{$ct-class-point}, .#{$ct-class-line}, .#{$ct-class-bar}, .#{$ct-class-slice-donut} {
stroke: $color;
}
.#{$ct-class-slice-pie}, .#{$ct-class-slice-donut-solid}, .#{$ct-class-area} {
fill: $color;
}