-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #25 from citelao/feature-composer
Rewritten with Composer
- Loading branch information
Showing
37 changed files
with
1,188 additions
and
261 deletions.
There are no files selected for viewing
Binary file not shown.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"autoload": { | ||
"psr-4": { | ||
"OhAlfred\\": "src/citelao/OhAlfred/", | ||
"Spotifious\\": "src/citelao/Spotifious/" | ||
} | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,209 +1,25 @@ | ||
<?php | ||
// thanks to http://www.alfredforum.com/topic/1788-prevent-flash-of-no-result | ||
mb_internal_encoding("UTF-8"); | ||
include_once('include/helper.php'); | ||
date_default_timezone_set('America/New_York'); | ||
|
||
use OhAlfred\OhAlfred; | ||
use Spotifious\Spotifious; | ||
require 'vendor/autoload.php'; | ||
|
||
/** | ||
* Spotifious (v0.7) | ||
* a natural Spotify controller for Alfred <https://github.com/citelao/Spotify-for-Alfred/> | ||
* an Alfred extension by Ben Stolovitz <http://github.com/citelao/> | ||
**/ | ||
|
||
$alfred = new OhAlfred(); | ||
$spotifious = new Spotifious(); | ||
|
||
/* Parse the query. */ | ||
$results = array(); | ||
$showImages = ($argv[1] == 'yes') ? true : false; | ||
$rawQuery = normalize($argv[2]); | ||
$imgdResults = 6; | ||
$maxResults = 15; | ||
|
||
$queryBits = str_replace("►", "", explode("►", $rawQuery)); | ||
array_walk($queryBits, 'trim_value'); | ||
$query = $queryBits[count($queryBits)-1]; | ||
|
||
if(mb_strlen($rawQuery) < 3) { | ||
/* If the query is tiny, show the main menu. */ | ||
|
||
/* Get now-playing info. */ | ||
$current = now(); | ||
$currentTrack = $current[0]; | ||
$currentAlbum = $current[1]; | ||
$currentArtist = $current[2]; | ||
$currentURL = $current[3]; | ||
$currentStatus = ($current[4] == 'playing') ? "include/images/paused.png" : "include/images/playing.png"; | ||
|
||
if($showImages) { | ||
$currentArtistArtwork = getArtistArtwork($currentArtist); // TODO use API to query artist URL? or just use plaintext from now on? | ||
$currentAlbumArtwork = getTrackArtwork($currentURL); | ||
} | ||
|
||
/* Output now-playing info. */ | ||
$results[0][title] = "$currentTrack"; | ||
$results[0][subtitle] = "$currentAlbum by $currentArtist"; | ||
$results[0][arg] = "playpause"; | ||
$results[0][icon] = $currentStatus; | ||
|
||
$results[1][title] = "$currentAlbum"; | ||
$results[1][subtitle] = "More from this album..."; | ||
$results[1][autocomplete] = "$currentAlbum"; // TODO change to albumdetail | ||
$results[1][valid] = "no"; | ||
$results[1][icon] = (!file_exists($currentAlbumArtwork)) ? 'include/images/album.png' : $currentAlbumArtwork; | ||
|
||
$results[2][title] = "$currentArtist"; | ||
$results[2][subtitle] = "More by this artist..."; | ||
$results[2][autocomplete] = $currentArtist; // TODO change to artistdetail | ||
$results[2][valid] = "no"; | ||
$results[2][icon] = (!file_exists($currentArtistArtwork)) ? 'include/images/artist.png' : $currentArtistArtwork; | ||
|
||
$results[3][title] = "Search for music..."; | ||
$results[3][subtitle] = "Begin typing to search"; | ||
$results[3][valid] = "no"; | ||
$results[3][icon] = "include/images/search.png"; | ||
} elseif(mb_substr($rawQuery, -1, 1) == "►") { | ||
// If the query is an unmodified machine-generated one, generate a detail menu. | ||
|
||
// If the query is two levels deep, generate the detail menu of the second | ||
// URL. Otherwise generate a detail menu based on the first (or only) URL. | ||
|
||
/* Do additional query-parsing. */ | ||
$detailURL = (mb_substr($rawQuery, -2, 1) == "►") ? $queryBits[1] : $queryBits[0]; | ||
$detailBits = explode(":", $detailURL); | ||
$type = $detailBits[1]; | ||
$provided = ($detailBits[1] == "artist") ? "album" : "track"; | ||
$query = $queryBits[count($queryBits)-2]; | ||
|
||
/* Fetch and parse the details. */ | ||
$json = fetch("http://ws.spotify.com/lookup/1/.json?uri=$detailURL&extras=$provided" . "detail"); | ||
|
||
if(empty($json)) | ||
alfredify(array(array('title' => 'Sorry, there was an error', 'subtitle' => 'Please try again'))); // TODO better error | ||
|
||
$json = json_decode($json); | ||
|
||
/* Output the details. */ | ||
$results[0][title] = $json->$type->name; | ||
$results[0][subtitle] = "View $type in Spotify"; | ||
$results[0][arg] = 'activate (open location "' . $detailURL . '")'; | ||
|
||
if($showImages) { | ||
$results[0][icon] = getTrackArtwork($detailURL); | ||
} else { | ||
$results[0][icon] = "include/images/$type.png"; | ||
} | ||
|
||
if($provided == "album") { | ||
$currentResultNumber = 1; | ||
$albums = array(); | ||
foreach ($json->$type->{$provided . "s"} as $key => $value) { | ||
if($currentResultNumber > $maxResults) | ||
continue; | ||
|
||
$value = $value->$provided; | ||
|
||
if(in_array($value->name, $albums)) | ||
continue; | ||
|
||
$currentResult[title] = $value->name; | ||
$currentResult[subtitle] = "Open this $provided..."; | ||
$currentResult[valid] = "no"; | ||
$currentResult[autocomplete] = "$detailURL ► $value->href ► $query ►►"; | ||
|
||
if($showImages && $currentResultNumber <= $imgdResults) { | ||
$currentResult[icon] = getTrackArtwork($value->href); | ||
} else { | ||
$currentResult[icon] = "include/images/album.png"; | ||
} | ||
|
||
$results[] = $currentResult; | ||
$albums[] = "$value->name"; | ||
$currentResultNumber++; | ||
} | ||
} else { | ||
$currentResultNumber = 1; | ||
foreach ($json->$type->{$provided . "s"} as $key => $value) { | ||
$starString = floatToStars($value->popularity); | ||
|
||
$currentResult[title] = "$currentResultNumber. $value->name"; | ||
$currentResult[subtitle] = "$starString " . beautifyTime($value->length); | ||
$currentResult[arg] = 'open location "' . $value->href . '"'; | ||
$currentResult[icon] = "include/images/track.png"; | ||
|
||
$results[] = $currentResult; | ||
$currentResultNumber++; | ||
} | ||
} | ||
|
||
|
||
} else { | ||
// If the query is completely user-generated, or the user has modified it, show the search menu. | ||
|
||
// Run the search using all three types of API queries | ||
foreach (array('artist','album','track') as $type) { | ||
/* Fetch and parse the search results. */ | ||
$json = fetch("http://ws.spotify.com/search/1/$type.json?q=" . str_replace("%3A", ":", urlencode($queryBits[count($queryBits)-1]))); | ||
|
||
if(empty($json)) | ||
continue; // TODO output a better error. | ||
|
||
$json = json_decode($json); | ||
|
||
/* Output the results. */ | ||
$currentResultNumber = 1; | ||
foreach ($json->{$type . "s"} as $key => $value) { | ||
if($currentResultNumber > $maxResults / 3) | ||
continue; | ||
|
||
/* Weight popularity. */ | ||
$popularity = $value->popularity; | ||
|
||
if($type == 'artist') | ||
$popularity += .5; | ||
if($type == 'album') | ||
$popularity += .15; | ||
|
||
/* Convert popularity to stars. */ | ||
$starString = floatToStars($popularity); | ||
|
||
if($type == 'track') { | ||
$subtitle = "$starString " . $value->album->name . " by " . $value->artists[0]->name; | ||
$genericResultArtwork = "include/images/track.png"; | ||
} elseif($type == 'album') { | ||
$subtitle = "$starString Album by " . $value->artists[0]->name; | ||
$genericResultArtwork = "include/images/album.png"; | ||
} else { | ||
$subtitle = "$starString " . ucfirst($type); | ||
$genericResultArtwork = "include/images/artist.png"; | ||
} | ||
|
||
$currentResult[title] = $value->name; | ||
$currentResult[subtitle] = $subtitle; | ||
|
||
$currentResult[uid] = "bs-spotify-$query-$type"; | ||
$currentResult[popularity] = $popularity; | ||
|
||
// `arg` is only used if item is valid, likewise `autocomplete` is | ||
// only used if item is not valid. Tracks run an action, everything | ||
// else autocompletes. | ||
$currentResult[valid] = ($type == 'track') ? 'yes' : 'no'; | ||
$currentResult[arg] = "open location \"$value->href\""; | ||
$currentResult[autocomplete] = "$value->href ► $query ►"; | ||
|
||
if($showImages && $currentResultNumber <= $imgdResults / 3) { | ||
$currentResult[icon] = getTrackArtwork($value->href); | ||
} else { | ||
$currentResult[icon] = $genericResultArtwork; | ||
} | ||
|
||
$results[] = $currentResult; | ||
$currentResultNumber++; | ||
} | ||
} | ||
|
||
/* Sort results by popularity. */ | ||
if(!empty($results)) | ||
usort($results, "popularitySort"); | ||
} | ||
set_exception_handler(array($alfred, 'exceptionify')); | ||
set_error_handler(array($alfred, 'errorify'), E_ALL); | ||
|
||
alfredify($results); | ||
$query = $argv[1]; | ||
$results = $spotifious->run($query); | ||
|
||
?> | ||
$alfred->alfredify($results); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
namespace OhAlfred\Applescript; | ||
|
||
class Applescript { | ||
protected $script; | ||
|
||
public function __construct() { | ||
$args = func_get_args(); | ||
|
||
$script = "osascript "; | ||
|
||
for ($i = 0; $i < func_num_args(); $i++) { | ||
$script .= " -e '" . $args[$i] . "'"; | ||
} | ||
|
||
$this->script = $script; | ||
} | ||
|
||
public function run() { | ||
return exec($this->script); | ||
} | ||
} |
Oops, something went wrong.