Compare commits

...

71 Commits

Author SHA1 Message Date
aj
48b058030a fixed bar chart colour, added now time to scrobble pane 2019-08-21 11:15:33 +01:00
aj
73b74bcee3 added image url checking, removed redundant url type 2019-05-30 23:13:09 +01:00
aj
6904663e59 added top album tab, moved error catching from invocation to implicit 2019-05-30 17:08:21 +01:00
aj
59bb4fdb6f added testing 2019-05-25 15:02:15 +01:00
aj
d720645735 updating fxml to fx 11, javafx version 12 2019-05-25 13:31:50 +01:00
aj
d0671eb970 utilising api call exception 2019-05-25 12:54:18 +01:00
aj
a78f520f2f migrated to java 11 2019-05-25 09:17:48 +01:00
aj
d0615e84b1 gradle and markdown updates 2019-05-24 10:50:08 +01:00
aj
8b6340ae6c divider dark theme 2019-05-23 16:20:35 +01:00
aj
da87697dc2 removed chart padding, fixed button text wrapping 2019-05-23 16:01:02 +01:00
aj
f9b81093db added artist scrobble getting 2019-05-23 15:09:07 +01:00
aj
d9fb9195f9 added get artist top tracks 2019-05-23 14:39:19 +01:00
aj
2ca1930615 keyboard shortcuts 2019-05-23 14:12:52 +01:00
aj
4ff50048e0 added cumulative check box 2019-05-23 11:21:54 +01:00
aj
c35be3b731 added multiple show types for scrobble chart 2019-05-23 11:13:20 +01:00
aj
0dd9e5dda6 cumulative scrobble graph and dark theme 2019-05-23 09:54:17 +01:00
aj
7503faa70f added scrobble pane chart 2019-05-22 16:47:53 +01:00
aj
410dc9e75a changed refresh buttons to pull from cache 2019-05-22 13:49:52 +01:00
aj
e31716db04 added first start up config variable getting 2019-05-22 13:41:20 +01:00
aj
d3a094b83d removed boolean for std out console, objectified 2019-05-22 13:29:21 +01:00
aj
b37a16bb89 added expiry options for cache 2019-05-22 13:21:31 +01:00
aj
0cc4807d93 css changes for piechart dark theme 2019-05-22 13:21:24 +01:00
aj
0c527dffbf css updates 2019-05-17 16:52:21 +01:00
aj
8180f9c1da fixed hiding wiki if null 2019-05-17 16:01:40 +01:00
aj
6328348b22 implemented scrobbling 2019-05-17 15:30:47 +01:00
aj
43ea2868eb added scrobble tab 2019-05-17 14:09:49 +01:00
aj
49b1838e75 added cache functionality 2019-05-17 12:14:36 +01:00
aj
12508ea57d added cacheable, removed tag pool 2019-05-17 07:34:04 +01:00
aj
6ef7488495 added cache 2019-05-17 06:49:06 +01:00
aj
d2f09e5033 fixed context menu colouring 2019-05-13 16:19:42 +01:00
aj
2cdc15a248 dark chart 2019-05-13 16:06:43 +01:00
aj
d035193976 added authing from ui 2019-05-13 14:55:00 +01:00
aj
23d2b1cffa implemented authentication 2019-05-13 13:37:22 +01:00
aj
7a6b9e34c3 to strings and added print config 2019-05-13 07:56:11 +01:00
aj
0371080b00 added json persister, added config reading and writing to file 2019-05-13 07:46:52 +01:00
aj
bb829f875d dark theme implemented 2019-05-12 22:42:37 +01:00
aj
4639ecd318 implemented config system, broke get last track 2019-05-12 21:39:28 +01:00
aj
64029f1d6f caught not checking for album 2019-05-10 19:38:12 +01:00
aj
3bc0cdcc63 tag menu disabled until loaded, console uneditable, scrobble scrollpane 2019-05-10 18:58:59 +01:00
aj
e3309746fd track scrobble viewing implemented 2019-05-10 06:58:30 +01:00
aj
3f30e5e67e added album to scrobble generation in get track scrobbles 2019-05-09 18:49:00 +01:00
aj
e2cd31f242 added album to scrobble 2019-05-09 18:42:04 +01:00
aj
6b465e25fe added gettrackscrobbles 2019-05-09 11:48:10 +01:00
aj
7ae40b1c8c shifted genre pie charts to separate tab 2019-05-07 21:20:53 +01:00
aj
903f474b8c added get top tracks 2019-05-07 19:14:14 +01:00
aj
04fee12fa4 implementing get top albums and artists 2019-05-07 17:36:18 +01:00
aj
3ab02eb4cb re-added pie chart menu 2019-05-07 15:07:55 +01:00
aj
9078986b3c lower case tab titles, ready to handle keyboard tab closing 2019-05-07 14:37:17 +01:00
aj
56436c8cca add view album/artist buttons 2019-05-07 11:00:43 +01:00
aj
fdac060b98 ready for cache implementations, started on get artist tracks 2019-05-04 13:26:16 +01:00
aj
2bc9aff667 added scrobble viewing 2019-05-04 13:04:54 +01:00
aj
c6cf7123bb migrating track to dynamic panes 2019-05-04 12:56:34 +01:00
aj
3e8cd92fe7 migrated albums to dynamic panes 2019-05-04 12:51:19 +01:00
aj
e4957364d2 started adding pane and pane switch handling 2019-05-04 12:26:32 +01:00
aj
b776e91436 added abstract getScrobbles method, fixed get recent scrobbles 2019-05-04 02:21:31 +01:00
aj
f1f85ada87 hiding split pane by default 2019-05-04 00:22:04 +01:00
aj
191b38524a streamlining for reduced api calls 2019-05-03 23:30:13 +01:00
aj
b56bfec0b7 separating services and working on threading 2019-05-03 23:19:55 +01:00
aj
994b8e2e6b removed system prints, replaced with logs 2019-05-03 20:44:42 +01:00
aj
1726d38f0c added logging 2019-05-02 22:56:15 +01:00
aj
26c9e2d17a added scrobble and get recent tracks 2019-05-02 22:48:41 +01:00
aj
1e77a32b94 initial scrobble impl. 2019-05-02 20:51:55 +01:00
aj
402491949b logging to correct list, fixed return types 2019-05-02 15:14:24 +01:00
aj
0ecc01c1be Merge branch 'master' of github.com:Sarsoo/fmframework 2019-05-02 14:53:40 +01:00
aj
8fb151f7fd stripping deprecated code 2019-05-02 14:53:20 +01:00
aj
729a1e14c2 stripping deprecated code 2019-05-02 14:50:56 +01:00
aj
27b26c5eda commented log dump in testing 2019-05-02 11:37:34 +01:00
aj
fbe5b3fa30 minor ui changes, number formatting and button width 2019-05-02 11:35:46 +01:00
aj
a98fa05b8f added log dump to file 2019-05-02 10:38:06 +01:00
aj
d80ba0c3ce added logging 2019-05-02 10:04:35 +01:00
aj
f4f2fbf4e6 remove unused imports 2019-05-02 06:55:59 +01:00
136 changed files with 6780 additions and 4732 deletions

2
.gitignore vendored
View File

@ -1,5 +1,6 @@
fmframework/src/sarsoo/fmframework/net/Key.java fmframework/src/sarsoo/fmframework/net/Key.java
.fm
# Directories # # Directories #
/build/ /build/
@ -12,7 +13,6 @@ target/
*.class *.class
# Package Files # # Package Files #
*.jar
*.war *.war
*.ear *.ear
*.db *.db

View File

@ -1,6 +1,4 @@
fmframework fmframework
============== ==============
*project working on a wrapper and frontend toolset for last.fm* *java fx last.fm client*
wrapper on internal java http connections and parsed from xml

View File

@ -7,58 +7,53 @@
*/ */
// Apply the java plugin to add support for Java plugins {
apply plugin: 'java' id 'java'
apply plugin: 'application' id 'application'
apply plugin: 'eclipse' id 'eclipse'
id 'com.github.johnrengelman.shadow' version '5.0.0'
id 'org.openjfx.javafxplugin' version '0.0.7'
}
mainClassName = 'sarsoo.fmframework.fx.FmFramework' application {
mainClassName = 'sarsoo.fmframework.fx.FmFramework'
}
version = '0.1.0' javafx {
sourceCompatibility = 1.8 version = "12.0.1"
targetCompatibility = 1.8 modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.graphics', 'javafx.web' ]
}
version = '0.9.0'
sourceCompatibility = 11
targetCompatibility = 11
// In this section you declare where to find the dependencies of your project
repositories { repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral() mavenCentral()
} }
// In this section you declare the dependencies for your production and test code
dependencies { dependencies {
// The production code uses the SLF4J logging API at compile time // The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.25' compileOnly 'org.slf4j:slf4j-api:1.7.25'
compile 'com.mashape.unirest:unirest-java:1.4.9' implementation 'com.mashape.unirest:unirest-java:1.4.9'
compile group: 'org.json', name: 'json', version: '20180130' implementation 'org.json:json:20180813'
// Declare the dependency for your favourite test framework you want to use in your tests. testImplementation('org.junit.jupiter:junit-jupiter-api:5.4.2')
// TestNG is also supported by the Gradle Test task. Just change the testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add }
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12' test {
useJUnitPlatform()
} }
/*
jar { jar {
manifest { manifest {
attributes 'Implementation-Title': 'fmframework', attributes 'Implementation-Title': 'fmframework',
'Implementation-Version': '0.1.0', 'Implementation-Version': version,
'Main-Class': 'sarsoo.fmframework.fx.FmFramework' 'Main-Class': 'sarsoo.fmframework.fx.FmFramework'
} }
baseName = 'fmframework' baseName = project.name
version = version version = version
}*/
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'fmframework',
'Implementation-Version': version,
'Main-Class': 'sarsoo.fmframework.fx.FmFramework'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
} }

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip zipStorePath=wrapper/dists

18
gradlew vendored Normal file → Executable file
View File

@ -1,5 +1,21 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
## Gradle start up script for UN*X ## Gradle start up script for UN*X
@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="" DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"

18
gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome

View File

@ -1,65 +0,0 @@
{
"pie":
{
"tags":[
"jazz",
"blues",
"rnb",
"soulfunk",
],
"hierarchies":[
"rap",
"rock",
"metal"
]
}
,
"genrehierarchy":{
"genres":[
{
"tags":[
"rap",
"classic rap",
"grime",
"trap",
"uk hip-hop"
],
"name":"rap"
},
{
"tags":[
"rock",
"classic rock",
"indie",
"pop punk",
"punk",
"emo"
],
"name":"rock"
},
{
"tags":[
"metal",
"industrial",
"thrash",
"metalcore",
],
"name":"metal"
},
{
"tags":[
"electronic",
"house",
"dnb",
"future bass",
"edm",
"garage"
],
"name":"electronic"
}
]
}
}

View File

@ -0,0 +1,21 @@
package sarsoo.fmframework.cache;
import sarsoo.fmframework.cache.puller.Puller;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist;
public class AlbumCache<S> extends StaticCache<Album, S> {
private StaticCache<Artist, Artist> artistPool;
public AlbumCache(Puller<Album, S> puller, StaticCache<Artist, Artist> artistCache) {
super(puller);
this.artistPool = artistCache;
}
@Override
protected void propagateCache(Album in) {
artistPool.add(in.getArtist());
}
}

View File

@ -0,0 +1,28 @@
package sarsoo.fmframework.cache;
import java.time.LocalDateTime;
public class CacheEntry<T> {
private LocalDateTime date;
private T subject;
public CacheEntry(T input) {
date = LocalDateTime.now();
subject = input;
}
public LocalDateTime getTime() {
return date;
}
public T getSubject() {
return subject;
}
@Override
public String toString() {
return date.toString() + ' ' + subject.toString();
}
}

View File

@ -0,0 +1,7 @@
package sarsoo.fmframework.cache;
public interface Cacheable {
public boolean matches(Object o);
}

View File

@ -0,0 +1,16 @@
package sarsoo.fmframework.cache;
import sarsoo.fmframework.cache.puller.Puller;
import sarsoo.fmframework.log.Log;
public interface IEphemeralCache<T> {
public <S> T get(Puller<T, S> input);
public <S> T getNew(Puller<T, S> input);
public void flush();
public void dumpToLog(Log log);
}

View File

@ -0,0 +1,17 @@
package sarsoo.fmframework.cache;
import sarsoo.fmframework.log.Log;
public interface IStaticCache<T, S> {
public T get(S input);
public T getNew(S input);
public void add(T input);
public void flush();
public void dumpToLog(Log log);
}

View File

@ -0,0 +1,130 @@
package sarsoo.fmframework.cache;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Optional;
import sarsoo.fmframework.cache.puller.Puller;
import sarsoo.fmframework.log.Log;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class StaticCache<T extends Cacheable, S> implements IStaticCache<T, S> {
private ArrayList<CacheEntry<T>> pool;
private Puller<T, S> puller;
private int expiryMinutes = 10;
private boolean expires = false;
public StaticCache(Puller<T, S> puller) {
pool = new ArrayList<CacheEntry<T>>();
this.puller = puller;
}
public StaticCache(Puller<T, S> puller, int expiry) {
pool = new ArrayList<CacheEntry<T>>();
this.puller = puller;
this.expires = true;
this.expiryMinutes = expiry;
}
public void setExpiryMinutes(int minutes) {
this.expiryMinutes = minutes;
}
public void setExpires(boolean choice) {
this.expires = choice;
}
public void setPuller(Puller<T, S> puller) {
this.puller = puller;
}
@Override
public T get(S input) {
Optional<CacheEntry<T>> item = pool.stream().filter(i -> i.getSubject().matches(input)).findFirst();
if (item.isPresent()) {
Logger.getLog().log(new LogEntry("getCachedItem").addArg("found").addArg(input.toString()));
if (expires) {
if (item.get().getTime().isBefore(LocalDateTime.now().minusMinutes(expiryMinutes))) {
pool.remove(item.get());
return get(input);
}
}
return item.get().getSubject();
} else {
Logger.getLog().log(new LogEntry("getCachedItem").addArg("pulling").addArg(input.toString()));
T pulled = puller.pull(input);
if (pulled != null) {
Logger.getLog().log(new LogEntry("getCachedItem").addArg("pulled").addArg(input.toString()));
pool.add(new CacheEntry<T>(pulled));
propagateCache(pulled);
return pulled;
} else {
Logger.getLog().logError(new ErrorEntry("getCachedItem").addArg("null item").addArg(input.toString()));
return null;
}
}
}
@Override
public T getNew(S input) {
Optional<CacheEntry<T>> item = pool.stream().filter(i -> i.getSubject().matches(input)).findFirst();
if (item.isPresent()) {
Logger.getLog().log(new LogEntry("getNewCachedItem").addArg("removed").addArg(input.toString()));
pool.remove(item.get());
}
Logger.getLog().log(new LogEntry("getNewCachedItem").addArg("pulling").addArg(input.toString()));
T pulled = puller.pull(input);
if (pulled != null) {
Logger.getLog().log(new LogEntry("getNewCachedItem").addArg("pulled").addArg(input.toString()));
pool.add(new CacheEntry<T>(pulled));
propagateCache(pulled);
return pulled;
} else {
Logger.getLog().logError(new ErrorEntry("getNewCachedItem").addArg("null item").addArg(input.toString()));
return null;
}
}
@Override
public void add(T input) {
Optional<CacheEntry<T>> item = pool.stream().filter(i -> i.getSubject().matches(input)).findFirst();
Logger.getLog().log(new LogEntry("addCachedItem").addArg(input.toString()));
if (item.isPresent()) {
Logger.getLog().log(new LogEntry("addCachedItem").addArg("replaced").addArg(input.toString()));
pool.remove(item.get());
}
pool.add(new CacheEntry<T>(input));
}
protected void propagateCache(T in) {
}
@Override
public void flush() {
pool.clear();
}
@Override
public void dumpToLog(Log log) {
pool.stream().forEach(i -> log.log(new LogEntry("dumpCache").addArg(i.toString())));
}
}

View File

@ -0,0 +1,28 @@
package sarsoo.fmframework.cache;
import sarsoo.fmframework.cache.puller.Puller;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Track;
public class TrackCache<S> extends StaticCache<Track, S> {
private StaticCache<Album, Album> albumPool;
private StaticCache<Artist, Artist> artistPool;
public TrackCache(Puller<Track, S> puller, StaticCache<Album, Album> albumCache,
StaticCache<Artist, Artist> artistCache) {
super(puller);
this.albumPool = albumCache;
this.artistPool = artistCache;
}
@Override
protected void propagateCache(Track in) {
if (in.getAlbum() != null) {
albumPool.add(in.getAlbum());
}
artistPool.add(in.getArtist());
}
}

View File

@ -0,0 +1,23 @@
package sarsoo.fmframework.cache.puller;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmNetwork;
import sarsoo.fmframework.music.Album;
public class AlbumPuller implements Puller<Album, Album> {
private FmNetwork net;
public AlbumPuller(FmNetwork net) {
this.net = net;
}
public Album pull(Album album) {
try {
return net.refresh(album);
} catch (ApiCallException e) {}
return null;
}
}

View File

@ -0,0 +1,28 @@
package sarsoo.fmframework.cache.puller;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmNetwork;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist;
public class ArtistPuller implements Puller<Artist, Artist> {
private FmNetwork net;
public ArtistPuller(FmNetwork net) {
this.net = net;
}
public ArtistPuller(FmNetwork net, Artist artist) {
this.net = net;
}
public Artist pull(Artist artist) {
try {
return net.refresh(artist);
} catch (ApiCallException e) {}
return null;
}
}

View File

@ -0,0 +1,23 @@
package sarsoo.fmframework.cache.puller;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.util.FMObjList;
public class ArtistTagPuller implements Puller<FMObjList, String> {
private FmUserNetwork net;
public ArtistTagPuller(FmUserNetwork net) {
this.net = net;
}
public FMObjList pull(String name) {
try {
return net.getPopulatedArtistTag(name);
} catch (ApiCallException e) {}
return null;
}
}

View File

@ -0,0 +1,38 @@
package sarsoo.fmframework.cache.puller;
import sarsoo.fmframework.cache.StaticCache;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.util.FMObjList;
public class CachedArtistTagPuller implements Puller<FMObjList, String> {
private FmUserNetwork net;
private StaticCache<Artist, Artist> artistPool;
public CachedArtistTagPuller(FmUserNetwork net, StaticCache<Artist, Artist> artistPool) {
this.net = net;
this.artistPool = artistPool;
}
public FMObjList pull(String name) {
FMObjList list;
try {
list = net.getArtistTag(name);
FMObjList returned = new FMObjList();
returned.setGroupName(list.getGroupName());
for(int i = 0; i < list.size(); i++) {
returned.add(artistPool.get((Artist) list.get(i)));
}
return returned;
} catch (ApiCallException e) {}
return null;
}
}

View File

@ -0,0 +1,7 @@
package sarsoo.fmframework.cache.puller;
public interface Puller<T, S> {
public T pull(S input);
}

View File

@ -0,0 +1,23 @@
package sarsoo.fmframework.cache.puller;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmNetwork;
import sarsoo.fmframework.music.Track;
public class TrackPuller implements Puller<Track, Track> {
private FmNetwork net;
public TrackPuller(FmNetwork net) {
this.net = net;
}
public Track pull(Track track) {
try {
return net.refresh(track);
} catch (ApiCallException e) {}
return null;
}
}

View File

@ -0,0 +1,74 @@
package sarsoo.fmframework.config;
import java.util.ArrayList;
import java.util.List;
public class Config {
protected List<ConfigVariable> variables;
public Config() {
this.variables = new ArrayList<ConfigVariable>();
}
public Config(ArrayList<ConfigVariable> variables) {
for (ConfigVariable i : variables) {
addVariable(i);
}
}
public Config addVariable(ConfigVariable variable) {
for (ConfigVariable i : variables) {
if (variable.getKey().equalsIgnoreCase(i.getKey())) {
i.setValue(variable.getValue());
for (VariableListener j : variable.getListeners()) {
i.addListener(j);
}
return this;
}
}
variables.add(variable);
return this;
}
public ConfigVariable getVariable(String key) {
for (ConfigVariable i : variables) {
if (i.getKey().equalsIgnoreCase(key)) {
return i;
}
}
return null;
}
public List<ConfigVariable> getVariables() {
return variables;
}
public String getValue(String key) {
ConfigVariable variable = getVariable(key);
if (variable != null) {
return variable.getValue();
}
return null;
}
public String toString() {
String string = "config:";
for(ConfigVariable i: variables) {
string += " " + i.toString();
}
return string;
}
}

View File

@ -0,0 +1,73 @@
package sarsoo.fmframework.config;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import sarsoo.fmframework.file.JSONPersister;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.InfoEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class ConfigPersister {
protected String variableTag = "vars";
public Config readConfig(String path) {
Logger.getLog().log(new LogEntry("read config").addArg(path));
JSONPersister persist = new JSONPersister();
JSONObject obj = persist.readJSONFromFile(path + "config.json");
Config config = new Config();
if (obj != null) {
JSONArray array = obj.getJSONArray(variableTag);
for (int i = 0; i < array.length(); i++) {
JSONObject var = (JSONObject) array.get(i);
String key = var.keys().next();
config.addVariable(new ConfigVariable(key, var.getString(key)));
// Logger.getLog().logInfo(
// new InfoEntry("read config").addArg(path).addArg("inserted " + key + " " + var.getString(key)));
}
} else {
Logger.getLog().logError(new ErrorEntry("read config").addArg(path).addArg("null json read"));
}
return config;
}
public void saveConfig(String path, Config config) {
JSONObject object = new JSONObject();
JSONArray array = new JSONArray();
List<ConfigVariable> variables = config.getVariables();
for (ConfigVariable i : variables) {
if (!i.isTemporary()) {
JSONObject obj = new JSONObject();
obj.put(i.getKey(), i.getValue());
array.put(obj);
}
}
object.put(variableTag, array);
JSONPersister persist = new JSONPersister();
persist.saveJSONtoFile(object, path + "config.json");
}
}

View File

@ -0,0 +1,75 @@
package sarsoo.fmframework.config;
import java.util.ArrayList;
import java.util.List;
public class ConfigVariable {
protected String key;
protected String value;
protected boolean temporary;
protected List<VariableListener> listeners;
public ConfigVariable(String key, String value) {
this.key = key;
this.value = value;
this.temporary = false;
this.listeners = new ArrayList<VariableListener>();
}
public ConfigVariable(String key, String value, boolean temporary) {
this.key = key;
this.value = value;
this.temporary = temporary;
this.listeners = new ArrayList<VariableListener>();
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
public boolean isTemporary() {
return temporary;
}
public void setTemporary(boolean temporary) {
this.temporary = temporary;
}
public void setValue(String value) {
this.value = value;
VariableEvent event = new VariableEvent(this);
for(VariableListener i: listeners) {
i.listen(event);
}
}
public void addListener(VariableListener listener) {
listeners.add(listener);
}
public List<VariableListener> getListeners() {
return listeners;
}
@Override
public String toString() {
String string = getKey() + ": " + getValue();
if(isTemporary())
string += " (temp)";
return string;
}
}

View File

@ -0,0 +1,17 @@
package sarsoo.fmframework.config;
public class VariableEvent {
protected ConfigVariable variable;
public VariableEvent(ConfigVariable variable) {
this.variable = variable;
}
public ConfigVariable getVariable() {
return variable;
}
}

View File

@ -0,0 +1,7 @@
package sarsoo.fmframework.config;
public interface VariableListener {
public void listen(VariableEvent event);
}

View File

@ -1,52 +1,48 @@
package sarsoo.fmframework.error; package sarsoo.fmframework.error;
import sarsoo.fmframework.log.Log;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
public class ApiCallException extends Exception { public class ApiCallException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private int failureCode; private int failureCode;
private String failureString;
private String method;
public ApiCallException(int failureCode) { public ApiCallException(String method, int failureCode, String failureDescription) {
this.failureCode = failureCode; this.failureCode = failureCode;
this.failureString = failureDescription;
this.method = method;
Logger.getLog().logError(getLogEntry());
}
public ApiCallException(String method, int failureCode, String failureDescription, Log log) {
this.method = method;
this.failureCode = failureCode;
this.failureString = failureDescription;
log.logError(getLogEntry());
}
private ErrorEntry getLogEntry() {
return new ErrorEntry("ApiCallException").addArg(method).addArg(Integer.toString(failureCode)).addArg(failureString);
}
public String getCauseMethod() {
return method;
} }
public int getFailureCode() { public int getFailureCode() {
return failureCode; return failureCode;
} }
public String getError() { public String getFailureMessage() {
switch(failureCode) { return failureString;
case 2:
return "Invalid service - This service does not exist";
case 3:
return "Invalid Method - No method with that name in this package";
case 4:
return "Authentication Failed - You do not have permissions to access the service";
case 5:
return "Invalid format - This service doesn't exist in that format";
case 6:
return "Invalid parameters - Your request is missing a required parameter";
case 7:
return "Invalid resource specified";
case 8:
return "Operation failed - Something else went wrong";
case 9:
return "Invalid session key - Please re-authenticate";
case 10:
return "Invalid API key - You must be granted a valid key by last.fm";
case 11:
return "Service Offline - This service is temporarily offline. Try again later.";
case 13:
return "Invalid method signature supplied";
case 16:
return "There was a temporary error processing your request. Please try again";
case 26:
return "Suspended API key - Access for your account has been suspended, please contact Last.fm";
case 29:
return "Rate limit exceeded - Your IP has made too many requests in a short period";
case 400:
return "Bad Request";
default:
return null;
}
} }
} }

View File

@ -0,0 +1,68 @@
package sarsoo.fmframework.file;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.json.JSONObject;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class JSONPersister {
public void saveJSONtoFile(JSONObject obj, String path) {
try (FileWriter file = new FileWriter(path)) {
file.write(obj.toString());
Logger.getLog().log(new LogEntry("save json").addArg("json saved"));
} catch (IOException e) {
Logger.getLog().logError(new ErrorEntry("save json").addArg("io exception"));
}
}
public JSONObject readJSONFromFile(String path) {
if (new File(path).isFile()) {
File file = new File(path);
return readJSONFromFile(file);
}else {
Logger.getLog().logError(new ErrorEntry("json load " + path).addArg("invalid path"));
}
return null;
}
public JSONObject readJSONFromFile(File file) {
try {
if (file.isFile()) {
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String jsonLine = br.readLine();
while (jsonLine != null) {
sb.append(jsonLine);
jsonLine = br.readLine();
}
br.close();
String jsonString = sb.toString();
JSONObject rootParsedJsonObj = new JSONObject(jsonString);
return rootParsedJsonObj;
}
} catch (IOException e) {
Logger.getLog().logError(new ErrorEntry("failed to load json " + file));
}
return null;
}
}

View File

@ -1,9 +1,257 @@
package sarsoo.fmframework.fm; package sarsoo.fmframework.fm;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.json.JSONException;
import org.json.JSONObject;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.HttpRequest;
import com.mashape.unirest.request.HttpRequestWithBody;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.LogEntry;
import sarsoo.fmframework.music.Scrobble;
public class FmAuthNetwork extends FmUserNetwork { public class FmAuthNetwork extends FmUserNetwork {
public FmAuthNetwork(String key, String userName) { protected String secretKey;
public FmAuthNetwork(String key, String secretKey, String userName) {
super(key, userName); super(key, userName);
this.secretKey = secretKey;
}
public JSONObject scrobble(Scrobble scrobble, String sk) throws ApiCallException {
Logger.getLog().log(new LogEntry("scrobble").addArg(scrobble.toString()));
HashMap<String, String> params = new HashMap<String, String>();
params.put("artist", scrobble.getTrack().getArtist().getName());
params.put("track", scrobble.getTrack().getName());
params.put("timestamp", Long.toString(scrobble.getUTS()));
params.put("sk", sk);
if(scrobble.getAlbum() != null) {
params.put("album", scrobble.getAlbum().getName());
params.put("albumArtist", scrobble.getAlbum().getArtist().getName());
}
JSONObject obj = makeAuthPostRequest("track.scrobble", params);
return obj;
}
public String getToken() throws ApiCallException {
Logger.getLog().log(new LogEntry("getToken"));
JSONObject obj = makeAuthGetRequest("auth.gettoken");
return obj.getString("token");
}
public String getSession(String token) throws ApiCallException {
Logger.getLog().log(new LogEntry("getSession"));
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", token);
JSONObject obj = makeAuthPostRequest("auth.getSession", params);
return obj.getJSONObject("session").getString("key");
}
public String getApiSignature(HashMap<String, String> parameters) {
TreeMap<String, String> sorted = new TreeMap<>(parameters);
String apiSig = new String();
for (Entry<String, String> i : sorted.entrySet()) {
if (!i.getKey().equals("format") && !i.getKey().equals("callback")) {
apiSig += i.getKey() + i.getValue();
}
}
apiSig += secretKey;
try {
byte[] sigBytes = apiSig.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(sigBytes);
StringBuilder b = new StringBuilder(32);
for(byte aByte : digest) {
String hex = Integer.toHexString((int) aByte & 0xFF);
if(hex.length() == 1) {
b.append('0');
}
b.append(hex);
}
return b.toString();
} catch (UnsupportedEncodingException e) {
Logger.getLog().logError(new ErrorEntry("make API signature").addArg("unsupported encoding"));
}
catch (NoSuchAlgorithmException e) {
Logger.getLog().logError(new ErrorEntry("make API signature").addArg("can't get md5 instance"));
}
return null;
}
protected JSONObject makeAuthGetRequest(String method) throws ApiCallException {
return makeAuthGetRequest(method, new HashMap<String, String>(), null);
}
protected JSONObject makeAuthGetRequest(String method, HashMap<String, String> parameters) throws ApiCallException {
return makeAuthGetRequest(method, parameters, null);
}
protected JSONObject makeAuthGetRequest(String method, HashMap<String, String> parameters,
HashMap<String, String> headers) throws ApiCallException {
HttpRequest request;
try {
request = Unirest.get("https://ws.audioscrobbler.com/2.0/").header("Accept", "application/json")
.header("User-Agent", "fmframework");
parameters.put("method", method);
parameters.put("api_key", key);
parameters.put("format", "json");
parameters.put("api_sig", getApiSignature(parameters).toString());
if (headers != null) {
for (String key : headers.keySet()) {
request = request.header(key, headers.get(key));
}
}
if (parameters != null) {
for (String key : parameters.keySet()) {
request = request.queryString(key, parameters.get(key));
}
}
HttpResponse<JsonNode> response = request.asJson();
if (response.getStatus() == 200) {
return new JSONObject(response.getBody().toString());
} else {
JSONObject obj = new JSONObject(response.getBody().toString());
throw new ApiCallException(method, obj.getInt("error"), obj.getString("message"));
}
} catch (UnirestException e) {
e.printStackTrace();
}
return null;
}
protected JSONObject makeAuthPostRequest(String method) throws ApiCallException {
return makeAuthPostRequest(method, new HashMap<String, String>(), null);
}
protected JSONObject makeAuthPostRequest(String method, HashMap<String, String> parameters) throws ApiCallException {
return makeAuthPostRequest(method, parameters, null);
}
protected JSONObject makeAuthPostRequest(String method, HashMap<String, String> parameters,
HashMap<String, String> headers) throws ApiCallException {
HttpRequestWithBody request;
try {
request = Unirest.post("https://ws.audioscrobbler.com/2.0/").header("Accept", "application/json")
.header("User-Agent", "fmframework");
parameters.put("method", method);
parameters.put("api_key", key);
parameters.put("format", "json");
String apiSig = getApiSignature(parameters).toString();
parameters.put("api_sig", apiSig);
if (headers != null) {
for (String key : headers.keySet()) {
request = request.header(key, headers.get(key));
}
}
String body = new String();
if (parameters != null) {
body = getBodyString(parameters);
request.body(body);
}
HttpResponse<JsonNode> response = request.asJson();
if (response.getStatus() >= 200 && response.getStatus() < 300) {
return new JSONObject(response.getBody().toString());
} else {
JSONObject obj = new JSONObject(response.getBody().toString());
throw new ApiCallException(method, obj.getInt("error"), obj.getString("message"));
}
} catch (UnirestException e) {
e.printStackTrace();
}
return null;
}
public String getBodyString(Map<String, String> params) {
String body = new String();
TreeMap<String, String> sorted = new TreeMap<>(params);
for (Iterator<Entry<String, String>> it = sorted.entrySet().iterator(); it.hasNext();) {
Entry<String, String> entry = it.next();
body += entry.getKey();
body += '=';
body += entry.getValue();
if(it.hasNext()) {
body += '&';
}
}
return body;
} }
} }

View File

@ -1,5 +1,11 @@
package sarsoo.fmframework.fm; package sarsoo.fmframework.fm;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.log.Log;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.InfoEntry;
import sarsoo.fmframework.log.entry.LogEntry;
import sarsoo.fmframework.music.Album; import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Album.AlbumBuilder; import sarsoo.fmframework.music.Album.AlbumBuilder;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
@ -8,10 +14,11 @@ import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.music.Track.TrackBuilder; import sarsoo.fmframework.music.Track.TrackBuilder;
import sarsoo.fmframework.music.Wiki; import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.util.ConsoleHandler; import sarsoo.fmframework.util.FMObjList;
import java.util.HashMap; import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -35,10 +42,8 @@ public class FmNetwork {
this.key = key; this.key = key;
} }
@Deprecated public Album getAlbum(String name, String artist) throws ApiCallException {
public FmNetwork(String key, String userName) { return getAlbum(name, getArtist(artist));
this.key = key;
this.userName = userName;
} }
/** /**
@ -47,15 +52,18 @@ public class FmNetwork {
* @param name Album Name * @param name Album Name
* @param artist Artist Name * @param artist Artist Name
* @return Album * @return Album
* @throws ApiCallException
* @throws JSONException
*/ */
public Album getAlbum(String name, String artist) { public Album getAlbum(String name, Artist artist) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getAlbum: " + name + " " + artist); Log log = Logger.getLog();
log.log(new LogEntry("getAlbum").addArg(name).addArg(artist.getName()));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("album", name); parameters.put("album", name);
parameters.put("artist", artist); parameters.put("artist", artist.getName());
if (userName != null) if (userName != null)
parameters.put("username", userName); parameters.put("username", userName);
@ -63,57 +71,55 @@ public class FmNetwork {
JSONObject obj = makeGetRequest("album.getinfo", parameters); JSONObject obj = makeGetRequest("album.getinfo", parameters);
String nameIn; String nameIn;
String artistIn;
try { try {
JSONObject albumJson = obj.getJSONObject("album"); JSONObject albumJson = obj.getJSONObject("album");
nameIn = albumJson.getString("name"); nameIn = albumJson.getString("name");
artistIn = albumJson.getString("artist");
AlbumBuilder builder = new AlbumBuilder(nameIn, getArtist(artistIn)); AlbumBuilder builder = new AlbumBuilder(nameIn, artist);
try { try {
builder.setMbid(albumJson.getString("mbid")); builder.setMbid(albumJson.getString("mbid"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) // log.logInfo(new InfoEntry("getAlbum").addArg("no mbid for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No MBID for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No MBID for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setUrl(albumJson.getString("url")); builder.setUrl(albumJson.getString("url"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getAlbum").addArg("no url for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No Url for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No Url for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setListeners(albumJson.getInt("listeners")); builder.setListeners(albumJson.getInt("listeners"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getAlbum").addArg("no listeners for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No listeners for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No listeners for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setPlayCount(albumJson.getInt("playcount")); builder.setPlayCount(albumJson.getInt("playcount"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(
ConsoleHandler.getConsole().write("ERROR: No play count for " + nameIn + " , " + e.getMessage()); new InfoEntry("getAlbum").addArg("no play count for").addArg(nameIn).addArg(e.getMessage()));
else
System.err.println("ERROR: No play count for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setUserPlayCount(albumJson.getInt("userplaycount")); builder.setUserPlayCount(albumJson.getInt("userplaycount"));
} catch (JSONException e) { } catch (JSONException e) {
log.logInfo(new InfoEntry("getAlbum").addArg("no user play count for").addArg(nameIn)
.addArg(e.getMessage()));
}
try {
JSONArray imageArray = albumJson.getJSONArray("image");
JSONObject imageObj = (JSONObject) imageArray.get(imageArray.length() - 1);
builder.setImageUrl(imageObj.getString("#text"));
} catch (JSONException e) {
log.logInfo(new InfoEntry("getAlbum").addArg("no image for").addArg(nameIn)
.addArg(e.getMessage()));
} }
try { try {
@ -125,19 +131,13 @@ public class FmNetwork {
builder.setWiki(wiki); builder.setWiki(wiki);
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getAlbum").addArg("no wiki for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No wiki for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No wiki for " + nameIn + " , " + e.getMessage());
} }
return builder.build(); return builder.build();
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getAlbum").addArg("album name not found").addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: Album Name Not Found, " + e.getMessage());
else
System.err.println("ERROR: Album Name Not Found, " + e.getMessage());
} }
return null; return null;
@ -149,10 +149,13 @@ public class FmNetwork {
* *
* @param name Artist Name * @param name Artist Name
* @return Artist * @return Artist
* @throws ApiCallException
* @throws JSONException
*/ */
public Artist getArtist(String name) { public Artist getArtist(String name) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getArtist: " + name); Log log = Logger.getLog();
log.log(new LogEntry("getArtist").addArg(name));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
@ -176,44 +179,34 @@ public class FmNetwork {
try { try {
builder.setMbid(artistJson.getString("mbid")); builder.setMbid(artistJson.getString("mbid"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("no mbid for").addArg(artistName).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No MBID for " + artistName + " , " + e.getMessage());
else
System.err.println("ERROR: No MBID for " + artistName + " , " + e.getMessage());
} }
try { try {
builder.setUrl(artistJson.getString("url")); builder.setUrl(artistJson.getString("url"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("no url for").addArg(artistName).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No Url for " + artistName + " , " + e.getMessage());
else
System.err.println("ERROR: No Url for " + artistName + " , " + e.getMessage());
} }
try { try {
builder.setListeners(artistJson.getJSONObject("stats").getInt("listeners")); builder.setListeners(artistJson.getJSONObject("stats").getInt("listeners"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("no listeners for").addArg(artistName)
ConsoleHandler.getConsole().write("ERROR: No listeners for " + artistName + " , " + e.getMessage()); .addArg(e.getMessage()));
else
System.err.println("ERROR: No listeners for " + artistName + " , " + e.getMessage());
} }
try { try {
builder.setPlayCount(artistJson.getJSONObject("stats").getInt("playcount")); builder.setPlayCount(artistJson.getJSONObject("stats").getInt("playcount"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("no play count for").addArg(artistName)
ConsoleHandler.getConsole() .addArg(e.getMessage()));
.write("ERROR: No play count for " + artistName + " , " + e.getMessage());
else
System.err.println("ERROR: No play count for " + artistName + " , " + e.getMessage());
} }
try { try {
builder.setUserPlayCount(artistJson.getJSONObject("stats").getInt("userplaycount")); builder.setUserPlayCount(artistJson.getJSONObject("stats").getInt("userplaycount"));
} catch (JSONException e) { } catch (JSONException e) {
log.logInfo(new InfoEntry("getArtist").addArg("no user play count for").addArg(artistName)
.addArg(e.getMessage()));
} }
try { try {
@ -225,39 +218,40 @@ public class FmNetwork {
builder.setWiki(wiki); builder.setWiki(wiki);
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("no wiki for").addArg(artistName).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No wiki for " + artistName + " , " + e.getMessage());
else
System.err.println("ERROR: No wiki for " + artistName + " , " + e.getMessage());
} }
return builder.build(); return builder.build();
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("getArtist").addArg("artist name not found").addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: Arist Name Not Found, " + e.getMessage());
else
System.err.println("ERROR: Arist Name Not Found, " + e.getMessage());
} }
return null; return null;
} }
public Track getTrack(String name, String artist) throws ApiCallException {
return getTrack(name, getArtist(artist));
}
/** /**
* Get a track from Last.FM * Get a track from Last.FM
* *
* @param name Track Name * @param name Track Name
* @param artist Artist Name * @param artist Artist Name
* @return Track * @return Track
* @throws ApiCallException
* @throws JSONException
*/ */
public Track getTrack(String name, String artist) { public Track getTrack(String name, Artist artist) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getTrack: " + name + " " + artist); Log log = Logger.getLog();
log.log(new LogEntry("getTrack").addArg(name).addArg(artist.getName()));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("artist", artist); parameters.put("artist", artist.getName());
parameters.put("track", name); parameters.put("track", name);
if (userName != null) if (userName != null)
@ -265,58 +259,55 @@ public class FmNetwork {
JSONObject obj = makeGetRequest("track.getinfo", parameters); JSONObject obj = makeGetRequest("track.getinfo", parameters);
return parseTrack(obj.getJSONObject("track"), artist);
}
protected Track parseTrack(JSONObject trackJson, Artist artist) {
Log log = Logger.getLog();
String nameIn; String nameIn;
String artistIn;
try { try {
JSONObject trackJson = obj.getJSONObject("track"); // JSONObject trackJson = obj.getJSONObject("track");
nameIn = trackJson.getString("name"); nameIn = trackJson.getString("name");
artistIn = trackJson.getJSONObject("artist").getString("name");
TrackBuilder builder = new TrackBuilder(nameIn, getArtist(artistIn)); TrackBuilder builder = new TrackBuilder(nameIn, artist);
try { try {
builder.setMbid(trackJson.getString("mbid")); builder.setMbid(trackJson.getString("mbid"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("parseTrack").addArg("no mbid for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No MBID for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No MBID for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setUrl(trackJson.getString("url")); builder.setUrl(trackJson.getString("url"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("parseTrack").addArg("no url for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No Url for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No Url for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setListeners(trackJson.getInt("listeners")); builder.setListeners(trackJson.getInt("listeners"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(
ConsoleHandler.getConsole().write("ERROR: No listeners for " + nameIn + " , " + e.getMessage()); new InfoEntry("parseTrack").addArg("no listeners for").addArg(nameIn).addArg(e.getMessage()));
else
System.err.println("ERROR: No listeners for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setPlayCount(trackJson.getInt("playcount")); builder.setPlayCount(trackJson.getInt("playcount"));
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(
ConsoleHandler.getConsole().write("ERROR: No play count for " + nameIn + " , " + e.getMessage()); new InfoEntry("parseTrack").addArg("no play count for").addArg(nameIn).addArg(e.getMessage()));
else
System.err.println("ERROR: No play count for " + nameIn + " , " + e.getMessage());
} }
try { try {
builder.setUserPlayCount(trackJson.getInt("userplaycount")); builder.setUserPlayCount(trackJson.getInt("userplaycount"));
} catch (JSONException e) { } catch (JSONException e) {
log.logInfo(new InfoEntry("parseTrack").addArg("no user play count for").addArg(nameIn)
.addArg(e.getMessage()));
} }
try { try {
@ -328,33 +319,74 @@ public class FmNetwork {
builder.setWiki(wiki); builder.setWiki(wiki);
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("parseTrack").addArg("no wiki for").addArg(nameIn).addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: No wiki for " + nameIn + " , " + e.getMessage());
else
System.err.println("ERROR: No wiki for " + nameIn + " , " + e.getMessage());
} }
return builder.build(); return builder.build();
} catch (JSONException e) { } catch (JSONException e) {
if (ConsoleHandler.isVerbose()) log.logInfo(new InfoEntry("parseTrack").addArg("track name not found").addArg(e.getMessage()));
ConsoleHandler.getConsole().write("ERROR: Album Name Not Found, " + e.getMessage());
else
System.err.println("ERROR: Album Name Not Found, " + e.getMessage());
} }
return null; return null;
} }
public FMObjList getArtistTopTracks(Artist artist, int number) throws ApiCallException {
Logger.getLog()
.log(new LogEntry("getArtistTopTracks").addArg(artist.getName()).addArg(Integer.toString(number)));
int limit = 50;
int pages = 0;
System.out.println(number / limit);
if ((double) number % (double) limit != 0) {
pages = (number / limit) + 1;
} else {
pages = number / limit;
}
FMObjList tracks = new FMObjList();
int counter;
for (counter = 0; counter < pages; counter++) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("artist", artist.getName());
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(counter + 1));
JSONObject obj = makeGetRequest("artist.gettoptracks", parameters);
JSONArray tracksJson = obj.getJSONObject("toptracks").getJSONArray("track");
for (int i = 0; i < tracksJson.length(); i++) {
JSONObject json = (JSONObject) tracksJson.get(i);
if (tracks.size() < number) {
tracks.add(parseTrack(json, artist));
}
}
}
return tracks;
}
/** /**
* Exchanges album object for stat-updated album from Last.FM * Exchanges album object for stat-updated album from Last.FM
* *
* @param album Old Album Object * @param album Old Album Object
* @return Refreshed Album * @return Refreshed Album
* @throws ApiCallException
* @throws JSONException
*/ */
public Album refresh(Album album) { public Album refresh(Album album) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>refreshAlbum: " + album.getName() + " " + album.getArtist().getName()); Logger.getLog().log(new LogEntry("refreshAlbum").addArg(album.getName()).addArg(album.getArtist().getName()));
return getAlbum(album.getName(), album.getArtist().getName()); return getAlbum(album.getName(), album.getArtist().getName());
} }
@ -364,10 +396,12 @@ public class FmNetwork {
* *
* @param artist Old Artist Object * @param artist Old Artist Object
* @return Refreshed Artist * @return Refreshed Artist
* @throws ApiCallException
* @throws JSONException
*/ */
public Artist refresh(Artist artist) { public Artist refresh(Artist artist) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>refreshArtist: " + artist.getName()); Logger.getLog().log(new LogEntry("refreshArtist").addArg(artist.getName()));
return getArtist(artist.getName()); return getArtist(artist.getName());
} }
@ -377,14 +411,19 @@ public class FmNetwork {
* *
* @param track Old Track Object * @param track Old Track Object
* @return Refreshed Track * @return Refreshed Track
* @throws ApiCallException
* @throws JSONException
*/ */
public Track refresh(Track track) { public Track refresh(Track track) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>refreshTrack: " + track.getName() + " " + track.getArtist().getName());
Track refreshedTrack = getTrack(track.getName(), track.getArtist().getName()); Logger.getLog().log(new LogEntry("refreshTrack").addArg(track.getName()).addArg(track.getArtist().getName()));
refreshedTrack.setAlbum(refresh(track.getAlbum())); Artist refreshedArtist = getArtist(track.getArtist().getName());
Track refreshedTrack = getTrack(track.getName(), refreshedArtist);
if (track.getAlbum() != null) {
refreshedTrack.setAlbum(getAlbum(track.getAlbum().getName(), refreshedArtist));
}
return refreshedTrack; return refreshedTrack;
} }
@ -394,8 +433,10 @@ public class FmNetwork {
* *
* @param obj FMObj for refreshing * @param obj FMObj for refreshing
* @return Updated FMObj * @return Updated FMObj
* @throws ApiCallException
* @throws JSONException
*/ */
public FMObj refresh(FMObj obj) { public FMObj refresh(FMObj obj) throws ApiCallException {
if (obj.getClass() == Track.class) if (obj.getClass() == Track.class)
return refresh((Track) obj); return refresh((Track) obj);
if (obj.getClass() == Album.class) if (obj.getClass() == Album.class)
@ -405,19 +446,23 @@ public class FmNetwork {
return null; return null;
} }
protected JSONObject makeGetRequest(String method, HashMap<String, String> parameters) { protected JSONObject makeGetRequest(String method, HashMap<String, String> parameters) throws ApiCallException {
return makeGetRequest(method, parameters, null); return makeGetRequest(method, parameters, null);
} }
protected JSONObject makeGetRequest(String method, HashMap<String, String> parameters, protected JSONObject makeGetRequest(String method, HashMap<String, String> parameters,
HashMap<String, String> headers) { HashMap<String, String> headers) throws ApiCallException {
HttpRequest request; HttpRequest request;
try { try {
request = Unirest.get("https://ws.audioscrobbler.com/2.0/").header("Accept", "application/json") request = Unirest.get("https://ws.audioscrobbler.com/2.0/").header("Accept", "application/json")
.header("User-Agent", "fmframework").queryString("method", method); .header("User-Agent", "fmframework");
parameters.put("method", method);
parameters.put("api_key", key);
parameters.put("format", "json");
if (headers != null) { if (headers != null) {
for (String key : headers.keySet()) { for (String key : headers.keySet()) {
@ -431,21 +476,16 @@ public class FmNetwork {
} }
} }
request = request.queryString("api_key", key).queryString("format", "json");
HttpResponse<JsonNode> response = request.asJson(); HttpResponse<JsonNode> response = request.asJson();
if (response.getStatus() == 200) { if (response.getStatus() >= 200 && response.getStatus() < 300) {
return new JSONObject(response.getBody().toString()); return new JSONObject(response.getBody().toString());
} else { } else {
System.out.println(response.getBody()); JSONObject obj = new JSONObject(response.getBody().toString());
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write("ERROR : HTTP Request Error " + response.getStatus()); throw new ApiCallException(method, obj.getInt("error"), obj.getString("message"));
else
System.err.println("ERROR : HTTP Request Error " + response.getStatus());
return null;
} }
} catch (UnirestException e) { } catch (UnirestException e) {
e.printStackTrace(); e.printStackTrace();
@ -453,15 +493,4 @@ public class FmNetwork {
return null; return null;
} }
protected class RequestParam {
int intparam;
String strparam;
public RequestParam(int param) {
}
}
} }

View File

@ -1,22 +1,29 @@
package sarsoo.fmframework.fm; package sarsoo.fmframework.fm;
import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import com.mashape.unirest.http.HttpResponse; import sarsoo.fmframework.error.ApiCallException;
import com.mashape.unirest.http.JsonNode; import sarsoo.fmframework.log.Logger;
import com.mashape.unirest.http.Unirest; import sarsoo.fmframework.log.entry.ErrorEntry;
import com.mashape.unirest.http.exceptions.UnirestException; import sarsoo.fmframework.log.entry.InfoEntry;
import sarsoo.fmframework.log.entry.LogEntry;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Album.AlbumBuilder;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Artist.ArtistBuilder;
import sarsoo.fmframework.music.Scrobble;
import sarsoo.fmframework.music.Tag; import sarsoo.fmframework.music.Tag;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.util.ConsoleHandler; import sarsoo.fmframework.music.Track.TrackBuilder;
import sarsoo.fmframework.util.FMObjList; import sarsoo.fmframework.util.FMObjList;
public class FmUserNetwork extends FmNetwork { public class FmUserNetwork extends FmNetwork {
@ -66,10 +73,12 @@ public class FmUserNetwork extends FmNetwork {
* Return user object from Last.FM * Return user object from Last.FM
* *
* @return User * @return User
* @throws ApiCallException
* @throws JSONException
*/ */
public User getUser() { public User getUser() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getUser"); Logger.getLog().log(new LogEntry("getUser"));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
@ -87,10 +96,12 @@ public class FmUserNetwork extends FmNetwork {
* Return user real name * Return user real name
* *
* @return User real name * @return User real name
* @throws ApiCallException
* @throws JSONException
*/ */
public String getUserRealName() { public String getUserRealName() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getUserRealname"); Logger.getLog().log(new LogEntry("getUserRealName"));
return getUser().getRealName(); return getUser().getRealName();
} }
@ -99,10 +110,12 @@ public class FmUserNetwork extends FmNetwork {
* Return user's total scrobble count * Return user's total scrobble count
* *
* @return Total scrobble count * @return Total scrobble count
* @throws ApiCallException
* @throws JSONException
*/ */
public int getUserScrobbleCount() { public int getUserScrobbleCount() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getUserScrobbleCount"); Logger.getLog().log(new LogEntry("getUserScrobbleCount"));
return getUser().getScrobbleCount(); return getUser().getScrobbleCount();
} }
@ -111,10 +124,12 @@ public class FmUserNetwork extends FmNetwork {
* Returns last or currently listening track * Returns last or currently listening track
* *
* @return Last track * @return Last track
* @throws ApiCallException
* @throws JSONException
*/ */
public Track getLastTrack() { public Track getLastTrack() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getLastTrack"); Logger.getLog().log(new LogEntry("getLastTrack"));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
@ -126,9 +141,10 @@ public class FmUserNetwork extends FmNetwork {
JSONObject track = (JSONObject) obj.get(0); JSONObject track = (JSONObject) obj.get(0);
Track trackObj = getTrack(track.getString("name"), track.getJSONObject("artist").getString("#text")); Artist artistObj = getArtist(track.getJSONObject("artist").getString("#text"));
trackObj.setAlbum(getAlbum(track.getJSONObject("album").getString("#text"),
track.getJSONObject("artist").getString("#text"))); Track trackObj = getTrack(track.getString("name"), artistObj);
trackObj.setAlbum(getAlbum(track.getJSONObject("album").getString("#text"), artistObj));
return trackObj; return trackObj;
@ -138,10 +154,12 @@ public class FmUserNetwork extends FmNetwork {
* Return scrobble count from today * Return scrobble count from today
* *
* @return Scrobble count today * @return Scrobble count today
* @throws ApiCallException
* @throws JSONException
*/ */
public int getScrobblesToday() { public int getScrobblesToday() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getScrobblesToday"); Logger.getLog().log(new LogEntry("getScrobblesToday"));
LocalDate local = LocalDate.now(); LocalDate local = LocalDate.now();
@ -169,10 +187,13 @@ public class FmUserNetwork extends FmNetwork {
* @param month Month int * @param month Month int
* @param year Year int * @param year Year int
* @return Scrobble count * @return Scrobble count
* @throws ApiCallException
* @throws JSONException
*/ */
public int getScrobbleCountByDate(int day, int month, int year) { public int getScrobbleCountByDate(int day, int month, int year) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getScrobblesByDate " + day + "." + month + "." + year); Logger.getLog().log(new LogEntry("getScrobblesByDate").addArg(Integer.toString(day))
.addArg(Integer.toString(month)).addArg(Integer.toString(year)));
LocalDate startDate = LocalDate.of(year, month, day); LocalDate startDate = LocalDate.of(year, month, day);
@ -200,10 +221,12 @@ public class FmUserNetwork extends FmNetwork {
* *
* @param day Negative day offset * @param day Negative day offset
* @return Scrobble count * @return Scrobble count
* @throws ApiCallException
* @throws JSONException
*/ */
public int getScrobbleCountByDeltaDay(int day) { public int getScrobbleCountByDeltaDay(int day) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getScrobblesByDeltaDay " + day); Logger.getLog().log(new LogEntry("getScrobblesByDeltaDay").addArg(Integer.toString(day)));
LocalDate local = LocalDate.now(); LocalDate local = LocalDate.now();
@ -226,15 +249,327 @@ public class FmUserNetwork extends FmNetwork {
return total; return total;
} }
public LocalDateTime getFirstScrobbleDateTime() throws ApiCallException {
Logger.getLog().log(new LogEntry("getFirstScrobbleDates"));
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("limit", Integer.toString(1));
JSONObject obj = makeGetRequest("user.getrecenttracks", parameters);
int page = obj.getJSONObject("recenttracks").getJSONObject("@attr").getInt("totalPages");
parameters.put("page", Integer.toString(page));
JSONObject dateJson = makeGetRequest("user.getrecenttracks", parameters);
JSONArray trackArray = dateJson.getJSONObject("recenttracks").getJSONArray("track");
long uts;
if(trackArray.length() == 1) {
uts = ((JSONObject) trackArray.get(0)).getJSONObject("date").getLong("uts");
}else {
uts = ((JSONObject) trackArray.get(1)).getJSONObject("date").getLong("uts");
}
return LocalDateTime.ofInstant(Instant.ofEpochSecond(uts), ZoneId.systemDefault());
}
private String getPeriod(TimePeriod period) {
switch(period){
case OVERALL:
return "overall";
case SEVENDAY:
return "7day";
case ONEMONTH:
return "1month";
case THREEMONTH:
return "3month";
case SIXMONTH:
return "6month";
case TWELVEMONTH:
return "12month";
default:
throw new IllegalArgumentException("invalid period provided");
}
}
public FMObjList getTopTracks(TimePeriod period, int number) throws ApiCallException {
Logger.getLog().log(new LogEntry("getTopTracks").addArg(getPeriod(period)).addArg(Integer.toString(number)));
int limit = 50;
int pages = 0;
System.out.println(number / limit);
if ((double) number % (double) limit != 0) {
pages = (number / limit) + 1;
} else {
pages = number / limit;
}
FMObjList tracks = new FMObjList();
int counter;
for (counter = 0; counter < pages; counter++) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("period", getPeriod(period));
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(counter + 1));
JSONObject obj = makeGetRequest("user.gettoptracks", parameters);
JSONArray tracksJson = obj.getJSONObject("toptracks").getJSONArray("track");
for (int i = 0; i < tracksJson.length(); i++) {
JSONObject json = (JSONObject) tracksJson.get(i);
if (tracks.size() < number) {
Artist artist = new ArtistBuilder(json.getJSONObject("artist").getString("name")).build();
Track track = parseTrack(json, artist);
tracks.add(track);
}
}
}
return tracks;
}
public FMObjList getTopAlbums(TimePeriod period, int number) throws ApiCallException {
Logger.getLog().log(new LogEntry("getTopAlbums").addArg(getPeriod(period)).addArg(Integer.toString(number)));
int limit = 50;
int pages = 0;
System.out.println(number / limit);
if ((double) number % (double) limit != 0) {
pages = (number / limit) + 1;
} else {
pages = number / limit;
}
FMObjList albums = new FMObjList();
int counter;
for (counter = 0; counter < pages; counter++) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("period", getPeriod(period));
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(counter + 1));
JSONObject obj = makeGetRequest("user.gettopalbums", parameters);
JSONArray albumsJson = obj.getJSONObject("topalbums").getJSONArray("album");
for (int i = 0; i < albumsJson.length(); i++) {
JSONObject json = (JSONObject) albumsJson.get(i);
if (albums.size() < number) {
Artist artist = new ArtistBuilder(json.getJSONObject("artist").getString("name")).build();
AlbumBuilder albumBuilder = new AlbumBuilder(json.getString("name"), artist)
.setUserPlayCount(json.getInt("playcount"));
JSONArray imageArray = json.getJSONArray("image");
JSONObject imageObj = (JSONObject) imageArray.get(imageArray.length() - 1);
albumBuilder.setImageUrl(imageObj.getString("#text"));
Album album = albumBuilder.build();
albums.add(album);
}
}
}
return albums;
}
public FMObjList getTopArtists(TimePeriod period, int number) throws ApiCallException {
Logger.getLog().log(new LogEntry("getTopArtists").addArg(getPeriod(period)).addArg(Integer.toString(number)));
int limit = 50;
int pages = 0;
System.out.println(number / limit);
if ((double) number % (double) limit != 0) {
pages = (number / limit) + 1;
} else {
pages = number / limit;
}
FMObjList artists = new FMObjList();
int counter;
for (counter = 0; counter < pages; counter++) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("period", getPeriod(period));
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(counter + 1));
JSONObject obj = makeGetRequest("user.gettopartists", parameters);
JSONArray artistsJson = obj.getJSONObject("topartists").getJSONArray("artist");
for (int i = 0; i < artistsJson.length(); i++) {
JSONObject json = (JSONObject) artistsJson.get(i);
if (artists.size() < number) {
Artist artist = new ArtistBuilder(json.getString("name")).setUserPlayCount(json.getInt("playcount"))
.build();
artists.add(artist);
}
}
}
return artists;
}
public ArrayList<Scrobble> getTrackScrobbles(Track track) throws ApiCallException {
Logger.getLog()
.log(new LogEntry("getTrackScrobbles").addArg(track.getName()).addArg(track.getArtist().getName()));
return getRecursiveTrackScrobbles(track, 1);
}
private ArrayList<Scrobble> getRecursiveTrackScrobbles(Track track, int page) throws ApiCallException {
int limit = 50;
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("track", track.getName());
parameters.put("artist", track.getArtist().getName());
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(page));
ArrayList<Scrobble> scrobbles = new ArrayList<Scrobble>();
JSONObject obj = makeGetRequest("user.gettrackscrobbles", parameters);
JSONArray returnedScrobbles = obj.getJSONObject("trackscrobbles").getJSONArray("track");
System.out.println(returnedScrobbles.length() + " length");
if (returnedScrobbles.length() > 0) {
for (int i = 0; i < returnedScrobbles.length(); i++) {
JSONObject scrob = returnedScrobbles.getJSONObject(i);
Album album = null;
try {
album = new AlbumBuilder(scrob.getJSONObject("album").getString("#text"), track.getArtist())
.build();
} catch (JSONException e) {
Logger.getLog()
.logError(new ErrorEntry("getTrackScrobbles").addArg("no album found").addArg(track.getName()).addArg(track.getArtist().getName()));
}
Scrobble scrobble = new Scrobble(scrob.getJSONObject("date").getLong("uts"), track, album);
scrobbles.add(scrobble);
}
int totalPages = obj.getJSONObject("trackscrobbles").getJSONObject("@attr").getInt("totalPages");
if (totalPages > page) {
scrobbles.addAll(getRecursiveTrackScrobbles(track, page + 1));
}
}
return scrobbles;
}
public ArrayList<Scrobble> getRecentScrobbles(int number) throws ApiCallException {
Logger.getLog().log(new LogEntry("getRecentTracks").addArg(Integer.toString(number)));
int limit = 50;
int pages = 0;
System.out.println(number / limit);
if ((double) number % (double) limit != 0) {
pages = (number / limit) + 1;
} else {
pages = number / limit;
}
ArrayList<Scrobble> scrobbles = new ArrayList<Scrobble>();
int counter;
for (counter = 0; counter < pages; counter++) {
HashMap<String, String> parameters = new HashMap<String, String>();
parameters.put("user", userName);
parameters.put("limit", Integer.toString(limit));
parameters.put("page", Integer.toString(counter + 1));
JSONObject obj = makeGetRequest("user.getrecenttracks", parameters);
JSONArray tracks = obj.getJSONObject("recenttracks").getJSONArray("track");
for (int i = 0; i < tracks.length(); i++) {
JSONObject json = (JSONObject) tracks.get(i);
if (scrobbles.size() < number) {
Artist artist = new ArtistBuilder(json.getJSONObject("artist").getString("#text")).build();
Album album = new AlbumBuilder(json.getJSONObject("album").getString("#text"), artist).build();
Track track = new TrackBuilder(json.getString("name"), artist).build();
track.setAlbum(album);
try {
Scrobble scrobble = new Scrobble(json.getJSONObject("date").getLong("uts"), track);
scrobbles.add(scrobble);
} catch (JSONException e) {
Logger.getLog().logInfo(new InfoEntry("getRecentTracks").addArg("first track"));
}
}
}
}
return scrobbles;
}
/** /**
* Returns list of user tags * Returns list of user tags
* *
* @return List of tags * @return List of tags
* @throws ApiCallException
* @throws JSONException
*/ */
public ArrayList<Tag> getTags() { public ArrayList<Tag> getTags() throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getTags"); Logger.getLog().log(new LogEntry("getTags"));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
@ -262,16 +597,18 @@ public class FmUserNetwork extends FmNetwork {
return tags; return tags;
} }
/** /**
* Returns FMObjList of tagged artists * Returns FMObjList of tagged artists
* *
* @param tagName Tag to explore * @param tagName Tag to explore
* @return FMObjList of artists * @return FMObjList of artists
* @throws ApiCallException
* @throws JSONException
*/ */
public FMObjList getTag(String tagName) { public FMObjList getArtistTag(String tagName) throws ApiCallException {
if (ConsoleHandler.isVerbose())
ConsoleHandler.getConsole().write(">>getTag: " + tagName); Logger.getLog().log(new LogEntry("getArtistTag").addArg(tagName));
HashMap<String, String> parameters = new HashMap<String, String>(); HashMap<String, String> parameters = new HashMap<String, String>();
@ -282,8 +619,7 @@ public class FmUserNetwork extends FmNetwork {
JSONObject obj = makeGetRequest("user.getpersonaltags", parameters); JSONObject obj = makeGetRequest("user.getpersonaltags", parameters);
JSONArray tagJsonArray = obj.getJSONObject("taggings") JSONArray tagJsonArray = obj.getJSONObject("taggings").getJSONObject("artists").getJSONArray("artist");
.getJSONObject("artists").getJSONArray("artist");
JSONObject artistJson; JSONObject artistJson;
@ -296,10 +632,9 @@ public class FmUserNetwork extends FmNetwork {
artistJson = (JSONObject) tagJsonArray.get(counter); artistJson = (JSONObject) tagJsonArray.get(counter);
Artist artist = getArtist(artistJson.getString("name")); Artist artist = new ArtistBuilder(artistJson.getString("name")).build();
if (ConsoleHandler.isVerbose()) Logger.getLog().logInfo(new InfoEntry("Tag").addArg(tagName).addArg(artist.getName()));
ConsoleHandler.getConsole().write(">Tag: " + tagName + ", " + artist.getName());
list.add(artist); list.add(artist);
@ -309,4 +644,38 @@ public class FmUserNetwork extends FmNetwork {
} }
/**
* Returns FMObjList of tagged artists
*
* @param tagName Tag to explore
* @return FMObjList of artists
* @throws ApiCallException
* @throws JSONException
*/
public FMObjList getPopulatedArtistTag(String tagName) throws ApiCallException {
Logger.getLog().log(new LogEntry("getPopulatedArtistTag").addArg(tagName));
FMObjList inputList = getArtistTag(tagName);
FMObjList returnedList = new FMObjList();
returnedList.setGroupName(tagName);
int counter;
for (counter = 0; counter < inputList.size(); counter++) {
Artist count = (Artist) inputList.get(counter);
Artist artist = getArtist(count.getName());
Logger.getLog().logInfo(new InfoEntry("Tag").addArg(tagName).addArg(artist.getName()));
returnedList.add(artist);
}
return returnedList;
}
} }

View File

@ -0,0 +1,12 @@
package sarsoo.fmframework.fm;
public enum TimePeriod {
OVERALL,
SEVENDAY,
ONEMONTH,
THREEMONTH,
SIXMONTH,
TWELVEMONTH
}

View File

@ -1,37 +1,65 @@
package sarsoo.fmframework.fx; package sarsoo.fmframework.fx;
import java.io.File;
import javafx.application.Application; import javafx.application.Application;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import sarsoo.fmframework.cache.AlbumCache;
import sarsoo.fmframework.cache.StaticCache;
import sarsoo.fmframework.cache.TrackCache;
import sarsoo.fmframework.cache.puller.AlbumPuller;
import sarsoo.fmframework.cache.puller.ArtistPuller;
import sarsoo.fmframework.cache.puller.ArtistTagPuller;
import sarsoo.fmframework.cache.puller.CachedArtistTagPuller;
import sarsoo.fmframework.cache.puller.TrackPuller;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.config.ConfigPersister;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.controller.RootController; import sarsoo.fmframework.fx.controller.RootController;
import sarsoo.fmframework.util.Reference; import sarsoo.fmframework.fx.service.SaveConfigService;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.LogEntry;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.util.FMObjList;
public class FmFramework extends Application { public class FmFramework extends Application {
private static Stage stage; private static Stage stage;
private Scene rootScene; private Scene rootScene;
private static Config config;
private static StaticCache<FMObjList, String> tagPool = null;
private static StaticCache<Track, Track> trackPool = null;
private static StaticCache<Album, Album> albumPool = null;
private static StaticCache<Artist, Artist> artistPool = null;
private static RootController control; private static RootController control;
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
FmFramework.stage = stage; FmFramework.stage = stage;
Reference.setUserName("sarsoo");
initConfig();
initCaches();
FXMLLoader loader = new FXMLLoader(getClass().getResource("ui/RootPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("ui/RootPane.fxml"));
// Parent root = FXMLLoader.load(getClass().getResource("ui/main.fxml")); // Parent root = FXMLLoader.load(getClass().getResource("ui/main.fxml"));
Parent root = (Parent)loader.load(); Parent root = (Parent) loader.load();
Scene scene = new Scene(root, 1000, 800); Scene scene = new Scene(root, 1000, 800);
rootScene = scene; rootScene = scene;
// scene.getStylesheets().add("styles/style.css"); // scene.getStylesheets().add("styles/style.css");
control = (RootController) loader.getController();
control = (RootController)loader.getController();
// (new Thread(new TagCaller())).start(); // (new Thread(new TagCaller())).start();
stage.setMinHeight(800); stage.setMinHeight(800);
stage.setMinWidth(960); stage.setMinWidth(960);
@ -41,15 +69,67 @@ public class FmFramework extends Application {
} }
private void initConfig() {
ConfigPersister persist = new ConfigPersister();
config = persist.readConfig(".fm/");
if (config != null) {
if (!(new File(".fm/").isFile())) {
new File(".fm/").mkdir();
}
SaveConfigService saveConfig = new SaveConfigService(".fm/", config);
saveConfig.start();
} else {
Logger.getLog().log(new LogEntry("load config").addArg("null config returned"));
}
}
private void initCaches() {
artistPool = new StaticCache<>(
new ArtistPuller(new FmUserNetwork(config.getValue("api_key"), config.getValue("username"))));
albumPool = new AlbumCache<>(
new AlbumPuller(new FmUserNetwork(config.getValue("api_key"), config.getValue("username"))),
artistPool);
trackPool = new TrackCache<>(
new TrackPuller(new FmUserNetwork(config.getValue("api_key"), config.getValue("username"))),
albumPool,
artistPool);
tagPool = new StaticCache<>(
new CachedArtistTagPuller(new FmUserNetwork(config.getValue("api_key"), config.getValue("username")), artistPool));
}
public static StaticCache<FMObjList, String> getTagPool() {
return tagPool;
}
public static StaticCache<Track, Track> getTrackPool() {
return trackPool;
}
public static StaticCache<Album, Album> getAlbumPool() {
return albumPool;
}
public static StaticCache<Artist, Artist> getArtistPool() {
return artistPool;
}
public static Config getSessionConfig() {
return config;
}
public static void main(String[] args) { public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> (new ConfigPersister()).saveConfig(".fm/", config)));
launch(args); launch(args);
} }
// public void changeScene() throws IOException {
// Parent root = FXMLLoader.load(getClass().getResource("ui/changed.fxml"));
//
// }
public static RootController getController() { public static RootController getController() {
return control; return control;
} }

View File

@ -2,7 +2,7 @@ package sarsoo.fmframework.fx;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import sarsoo.fmframework.util.Console; import sarsoo.fmframework.log.console.Console;
public class TextAreaConsole implements Console{ public class TextAreaConsole implements Console{
@ -12,6 +12,7 @@ public class TextAreaConsole implements Console{
private TextAreaConsole() { private TextAreaConsole() {
output = new TextArea(); output = new TextArea();
output.setEditable(false);
} }
public static TextAreaConsole getInstance(){ public static TextAreaConsole getInstance(){

View File

@ -0,0 +1,18 @@
package sarsoo.fmframework.fx;
import javafx.scene.image.Image;
public class TiledImage extends Image {
private int index;
public TiledImage(String url, int index) {
super(url);
this.index = index;
}
public int getIndex() {
return index;
}
}

View File

@ -7,8 +7,9 @@ import java.util.Comparator;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.chart.PieChart; import javafx.scene.chart.PieChart;
import sarsoo.fmframework.cache.StaticCache;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.util.FMObjList; import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.tagpool.TagPool;
public class GenrePieChart extends PieChart{ public class GenrePieChart extends PieChart{
@ -17,18 +18,21 @@ public class GenrePieChart extends PieChart{
public GenrePieChart(String name, ArrayList<String> tagNames) { public GenrePieChart(String name, ArrayList<String> tagNames) {
// getStylesheets().add("../styles/mainPane.css");
getStyleClass().add("backGround");
setStartAngle(90); setStartAngle(90);
setTitle(name); setTitle(name);
pieChartData = FXCollections.observableArrayList(); pieChartData = FXCollections.observableArrayList();
TagPool tagPool = TagPool.getPool(); StaticCache<FMObjList, String> tagPool = FmFramework.getTagPool();
ArrayList<FMObjList> tagObjs = new ArrayList<FMObjList>(); ArrayList<FMObjList> tagObjs = new ArrayList<FMObjList>();
int i; int i;
for(i = 0; i < tagNames.size(); i++){ for(i = 0; i < tagNames.size(); i++){
tagObjs.add(tagPool.getTag(tagNames.get(i))); tagObjs.add(tagPool.get(tagNames.get(i)));
} }
for(i = 0; i < tagObjs.size(); i++) { for(i = 0; i < tagObjs.size(); i++) {
@ -37,7 +41,6 @@ public class GenrePieChart extends PieChart{
for(i = 0; i < tagNames.size(); i++) { for(i = 0; i < tagNames.size(); i++) {
FMObjList list = tagObjs.get(i); FMObjList list = tagObjs.get(i);
System.out.println(list.getGroupName());
pieChartData.add(new PieChart.Data( pieChartData.add(new PieChart.Data(
String.format("%s %d%%", list.getGroupName(),(int) list.getTotalUserScrobbles() * 100 / genreTotal), list.getTotalUserScrobbles())); String.format("%s %d%%", list.getGroupName(),(int) list.getTotalUserScrobbles() * 100 / genreTotal), list.getTotalUserScrobbles()));
} }

View File

@ -3,20 +3,30 @@ package sarsoo.fmframework.fx.chart;
import java.util.ArrayList; import java.util.ArrayList;
import javafx.scene.chart.PieChart; import javafx.scene.chart.PieChart;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork; import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.net.Key; import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.util.Reference;
public class GenreTotalPieChart extends GenrePieChart{ public class GenreTotalPieChart extends GenrePieChart{
public GenreTotalPieChart(String name, ArrayList<String> tagNames) { public GenreTotalPieChart(String name, ArrayList<String> tagNames) {
super(name, tagNames); super(name, tagNames);
getStyleClass().add("backGround");
setTitle(name + " total"); setTitle(name + " total");
FmUserNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName()); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
int totalScrobbles = net.getUserScrobbleCount(); int totalScrobbles;
try {
totalScrobbles = net.getUserScrobbleCount();
} catch (ApiCallException e) {
totalScrobbles = 0;
}
int other = totalScrobbles - genreTotal; int other = totalScrobbles - genreTotal;
pieChartData.add(new PieChart.Data(String.format("other %d%%", (int) other * 100 / totalScrobbles), other)); pieChartData.add(new PieChart.Data(String.format("other %d%%", (int) other * 100 / totalScrobbles), other));

View File

@ -1,135 +0,0 @@
package sarsoo.fmframework.fx.controller;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
import javafx.scene.control.*;
public class AlbumPaneController {
@FXML
private Label labelAlbumName;
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
public void initialize() {
labelAlbumName.setText("Hello World");
}
Album album;
public void populate(Album album) {
this.album = album;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelAlbumName.setText(album.getName());
labelArtistName.setText(album.getArtist().getName());
labelUserScrobbles.setText(numberFormat.format(album.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(album, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(album.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(album.getPlayCount()) + " Total Scrobbles");
double ratio = album.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = album.getWiki();
if(wiki != null) {
textAreaWiki.setText(wiki.getContent()+ "\n\n" + wiki.getDate());
}
}
@FXML
protected void handleRefresh(ActionEvent event) {
refresh();
}
@FXML
protected void viewOnline(ActionEvent event) {
Network.openURL(album.getUrl());
}
@FXML
protected void viewArtist(ActionEvent event) throws IOException {
FmFramework.getController().addTab(new ArtistTab(album.getArtist()));
}
@FXML
protected void viewRYM(ActionEvent event) {
Network.openURL(album.getRymURL());
}
public void refresh() {
album = new FmUserNetwork(Key.getKey(), Reference.getUserName()).refresh(album);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelUserScrobbles.setText(numberFormat.format(album.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(album, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(album.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(album.getPlayCount()) + " Total Scrobbles");
double ratio = album.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = album.getWiki();
if(wiki != null) {
textAreaWiki.setText(wiki.getContent()+ "\n\n" + wiki.getDate());
}
}
}

View File

@ -1,138 +0,0 @@
package sarsoo.fmframework.fx.controller;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.tab.FMObjListTab;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Getter;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
import javafx.scene.control.*;
public class ArtistPaneController {
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
public void initialize() {
}
Artist artist;
public void populate(Artist artist) {
this.artist = artist;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelArtistName.setText(artist.getName());
labelUserScrobbles.setText(numberFormat.format(artist.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(artist, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(artist.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(artist.getPlayCount()) + " Total Scrobbles");
double ratio = artist.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = artist.getWiki();
if(wiki != null) {
textAreaWiki.setText(wiki.getContent()+ "\n\n" + wiki.getDate());
}
}
@FXML
protected void handleRefresh(ActionEvent event) {
refresh();
}
@FXML
protected void viewOnline(ActionEvent event) {
Network.openURL(artist.getUrl());
}
@FXML
protected void viewRYM(ActionEvent event) {
Network.openURL(artist.getRymURL());
}
@FXML
protected void handleViewTracks(ActionEvent event) {
try {
FmFramework.getController().addTab(new FMObjListTab(Getter.getArtistTracks(artist.getName(), Reference.getUserName())));
} catch (IOException e) {
e.printStackTrace();
}
}
public void refresh() {
artist = new FmUserNetwork(Key.getKey(), Reference.getUserName()).refresh(artist);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelUserScrobbles.setText(numberFormat.format(artist.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(artist, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(artist.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(artist.getPlayCount()) + " Total Scrobbles");
double ratio = artist.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = artist.getWiki();
if(wiki != null) {
textAreaWiki.setText(wiki.getContent()+ "\n\n" + wiki.getDate());
}
}
}

View File

@ -14,15 +14,15 @@ import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork; import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework; import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.tab.ArtistTab; import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.FMObj; import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.util.FMObjList; import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.Maths; import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.chart.*; import javafx.scene.chart.*;
import javafx.scene.chart.PieChart.Data; import javafx.scene.chart.PieChart.Data;
@ -37,22 +37,24 @@ public class FMObjListPaneController {
@FXML @FXML
private GridPane gridPaneFMObjs; private GridPane gridPaneFMObjs;
@FXML @FXML
private PieChart pieChart; private PieChart pieChart;
@FXML @FXML
private PieChart pieChartArtists; private PieChart pieChartArtists;
private FMObjList list; private FMObjList list;
public void populate(FMObjList list) { public void populate(FMObjList list) {
this.list = list; this.list = list;
double percent = Maths.getPercentListening(list, Reference.getUserName()); String username = FmFramework.getSessionConfig().getValue("username");
double percent = Maths.getPercentListening(list, username);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US); NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelTotalScrobbles.setText("" + list.getTotalUserScrobbles()); labelTotalScrobbles.setText(numberFormat.format(list.getTotalUserScrobbles()));
labelPercent.setText(String.format("%.2f%%", percent)); labelPercent.setText(String.format("%.2f%%", percent));
Collections.sort(list); Collections.sort(list);
@ -64,20 +66,15 @@ public class FMObjListPaneController {
FMObj obj = list.get(counter); FMObj obj = list.get(counter);
Label name = new Label(obj.getName().toLowerCase()); Label name = new Label(obj.getName().toLowerCase());
name.getStyleClass().add("nameLabel"); name.getStyleClass().add("nameLabel");
name.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() { name.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
@Override @Override
public void handle(Event event) { public void handle(Event event) {
try { FmFramework.getController().addTab(new ArtistTab((Artist) obj));
FmFramework.getController().addTab(new ArtistTab((Artist) obj));
} catch (IOException e) {
e.printStackTrace();
}
} }
@ -91,50 +88,62 @@ public class FMObjListPaneController {
gridPaneFMObjs.add(totalScrobbles, 2, counter); gridPaneFMObjs.add(totalScrobbles, 2, counter);
} }
ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
new PieChart.Data(list.getGroupName(), list.getTotalUserScrobbles()),
new PieChart.Data("other", new FmUserNetwork(Key.getKey(), Reference.getUserName()).getUserScrobbleCount() - list.getTotalUserScrobbles()));
ObservableList<PieChart.Data> pieChartArtistsData = FXCollections.observableArrayList();
int counter2;
for(counter2 = 0; counter2 < list.size(); counter2++) {
PieChart.Data data = new PieChart.Data(list.get(counter2).getName(), list.get(counter2).getUserPlayCount());
pieChartArtistsData.add(data);
}
Collections.sort(pieChartArtistsData, new Comparator<PieChart.Data>() {
@Override ObservableList<PieChart.Data> pieChartData;
public int compare(Data arg0, Data arg1) { try {
return (int) (arg1.getPieValue() - arg0.getPieValue()); pieChartData = FXCollections.observableArrayList(
new PieChart.Data(list.getGroupName(), list.getTotalUserScrobbles()),
new PieChart.Data("other",
new FmUserNetwork(FmFramework.getSessionConfig().getValue("api_key"), username)
.getUserScrobbleCount() - list.getTotalUserScrobbles()));
ObservableList<PieChart.Data> pieChartArtistsData = FXCollections.observableArrayList();
int counter2;
for (counter2 = 0; counter2 < list.size(); counter2++) {
PieChart.Data data = new PieChart.Data(list.get(counter2).getName(), list.get(counter2).getUserPlayCount());
pieChartArtistsData.add(data);
} }
});
pieChart.setData(pieChartData);
pieChartArtists.setData(pieChartArtistsData);
Collections.sort(pieChartArtistsData, new Comparator<PieChart.Data>() {
@Override
public int compare(Data arg0, Data arg1) {
return (int) (arg1.getPieValue() - arg0.getPieValue());
}
});
pieChart.setData(pieChartData);
pieChartArtists.setData(pieChartArtistsData);
} catch (ApiCallException e) {}
} }
@FXML @FXML
protected void handleRefresh(ActionEvent event) { protected void handleRefresh(ActionEvent event) {
list = new FmUserNetwork(Key.getKey(), Reference.getUserName()).getTag(list.getGroupName()); Config config = FmFramework.getSessionConfig();
double percent = Maths.getPercentListening(list, Reference.getUserName());
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelTotalScrobbles.setText("Σ " + list.getTotalUserScrobbles()); String username = config.getValue("username");
String api_key = config.getValue("api_key");
try {
list = new FmUserNetwork(api_key, username).getPopulatedArtistTag(list.getGroupName());
} catch (ApiCallException e1) {
e1.printStackTrace();
}
double percent = Maths.getPercentListening(list, username);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.UK);
labelTotalScrobbles.setText(numberFormat.format(list.getTotalUserScrobbles()));
labelPercent.setText(String.format("%.2f%%", percent)); labelPercent.setText(String.format("%.2f%%", percent));
Collections.sort(list); Collections.sort(list);
Collections.reverse(list); Collections.reverse(list);
gridPaneFMObjs.getChildren().clear(); gridPaneFMObjs.getChildren().clear();
int counter; int counter;
@ -143,20 +152,15 @@ public class FMObjListPaneController {
FMObj obj = list.get(counter); FMObj obj = list.get(counter);
Label name = new Label(obj.getName().toLowerCase()); Label name = new Label(obj.getName().toLowerCase());
name.getStyleClass().add("nameLabel"); name.getStyleClass().add("nameLabel");
name.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() { name.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
@Override @Override
public void handle(Event event) { public void handle(Event event) {
try { FmFramework.getController().addTab(new ArtistTab((Artist) obj));
FmFramework.getController().addTab(new ArtistTab((Artist) obj));
} catch (IOException e) {
e.printStackTrace();
}
} }
@ -170,14 +174,19 @@ public class FMObjListPaneController {
gridPaneFMObjs.add(totalScrobbles, 2, counter); gridPaneFMObjs.add(totalScrobbles, 2, counter);
} }
ObservableList<PieChart.Data> pieChartData;
try {
pieChartData = FXCollections.observableArrayList(
new PieChart.Data(list.getGroupName(), list.getTotalUserScrobbles()),
new PieChart.Data("other",
new FmUserNetwork(FmFramework.getSessionConfig().getValue("api_key"), username)
.getUserScrobbleCount() - list.getTotalUserScrobbles()));
pieChart.setData(pieChartData);
} catch (ApiCallException e) {}
ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
new PieChart.Data(list.getGroupName(), list.getTotalUserScrobbles()),
new PieChart.Data("other", new FmUserNetwork(Key.getKey(), Reference.getUserName()).getUserScrobbleCount() - list.getTotalUserScrobbles()));
pieChart.setData(pieChartData);
} }
} }

View File

@ -14,6 +14,8 @@ import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.file.ListPersister; import sarsoo.fmframework.file.ListPersister;
import sarsoo.fmframework.fm.FmNetwork; import sarsoo.fmframework.fm.FmNetwork;
import sarsoo.fmframework.fm.FmUserNetwork; import sarsoo.fmframework.fm.FmUserNetwork;
@ -25,13 +27,12 @@ import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.FMObj; import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.util.FMObjList; import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.Maths; import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.chart.*; import javafx.scene.chart.*;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
public class FMObjListPaneEditController { public class FMObjListPaneEditController {
@FXML @FXML
@ -55,84 +56,6 @@ public class FMObjListPaneEditController {
this.list = list; this.list = list;
} }
// public void populate(FMObjList list) {
// this.list = list;
//
// double percent = Maths.getPercentListening(list, Reference.getUserName());
// NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
//
// labelTotalScrobbles.setText("Σ " + list.getTotalUserScrobbles());
// labelPercent.setText(String.format("%.2f%%", percent));
//
// Collections.sort(list);
// Collections.reverse(list);
//
// int counter;
// for (counter = 0; counter < list.size(); counter++) {
//
// FMObj obj = list.get(counter);
//
// Label name = new Label(obj.getName().toLowerCase());
//
// name.getStyleClass().add("nameLabel");
//
// name.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
//
// @Override
// public void handle(Event event) {
//
// try {
// FmFramework.getController().addTab(new ArtistTab((Artist) obj));
// } catch (IOException e) {
//
// e.printStackTrace();
// }
//
// }
//
// });
//
// Label userScrobbles = new Label(numberFormat.format(obj.getUserPlayCount()));
// Label totalScrobbles = new Label(numberFormat.format(obj.getPlayCount()));
//
// gridPaneFMObjs.add(name, 0, counter);
// gridPaneFMObjs.add(userScrobbles, 1, counter);
// gridPaneFMObjs.add(totalScrobbles, 2, counter);
//
// }
//
//
// ObservableList<PieChart.Data> pieChartData =
// FXCollections.observableArrayList(
// new PieChart.Data(list.getGroupName(), list.getTotalUserScrobbles()),
// new PieChart.Data("other", Getter.getScrobbles(Reference.getUserName()) -
// list.getTotalUserScrobbles()));
//
// ObservableList<PieChart.Data> pieChartArtistsData =
// FXCollections.observableArrayList();
// int counter2;
// for(counter2 = 0; counter2 < list.size(); counter2++) {
//
// PieChart.Data data = new PieChart.Data(list.get(counter2).getName(),
// list.get(counter2).getUserPlayCount());
//
// pieChartArtistsData.add(data);
//
// }
//
// Collections.sort(pieChartArtistsData, new Comparator<PieChart.Data>() {
//
// @Override
// public int compare(Data arg0, Data arg1) {
// return (int) (arg1.getPieValue() - arg0.getPieValue());
// }
// });
//
// pieChart.setData(pieChartData);
// pieChartArtists.setData(pieChartArtistsData);
//
// }
@FXML @FXML
protected void handleRefresh(ActionEvent event) { protected void handleRefresh(ActionEvent event) {
updateList(); updateList();
@ -140,28 +63,31 @@ public class FMObjListPaneEditController {
} }
public void updateList() { public void updateList() {
FmNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName()); FmNetwork net = new FmUserNetwork(FmFramework.getSessionConfig().getValue("api_key"),
FmFramework.getSessionConfig().getValue("username"));
FMObjList newList = new FMObjList(); FMObjList newList = new FMObjList();
int counter; int counter;
for (counter = 0; counter < list.size(); counter++) { for (counter = 0; counter < list.size(); counter++) {
newList.add(net.refresh(list.get(counter))); try {
newList.add(net.refresh(list.get(counter)));
} catch (ApiCallException e) {}
} }
setList(newList); setList(newList);
} }
public void refresh() { public void refresh() {
double percent = Maths.getPercentListening(list, Reference.getUserName()); double percent = Maths.getPercentListening(list, FmFramework.getSessionConfig().getValue("username"));
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US); NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.UK);
labelTotalScrobbles.setText("" + list.getTotalUserScrobbles()); labelTotalScrobbles.setText(numberFormat.format(list.getTotalUserScrobbles()));
labelPercent.setText(String.format("%.2f%%", percent)); labelPercent.setText(String.format("%.2f%%", percent));
Collections.sort(list); Collections.sort(list);
Collections.reverse(list); Collections.reverse(list);
gridPaneFMObjs.getChildren().clear(); gridPaneFMObjs.getChildren().clear();
@ -180,18 +106,12 @@ public class FMObjListPaneEditController {
@Override @Override
public void handle(Event event) { public void handle(Event event) {
try { if (obj.getClass() == Artist.class) {
FmFramework.getController().addTab(new ArtistTab((Artist) obj));
if (obj.getClass() == Artist.class) { } else if (obj.getClass() == Album.class) {
FmFramework.getController().addTab(new ArtistTab((Artist) obj)); FmFramework.getController().addTab(new AlbumTab((Album) obj));
} else if (obj.getClass() == Album.class) { } else if (obj.getClass() == Track.class) {
FmFramework.getController().addTab(new AlbumTab((Album) obj)); FmFramework.getController().addTab(new TrackTab((Track) obj));
} else if (obj.getClass() == Track.class) {
FmFramework.getController().addTab(new TrackTab((Track) obj));
}
} catch (IOException e) {
e.printStackTrace();
} }
} }
@ -221,7 +141,15 @@ public class FMObjListPaneEditController {
} }
int other = new FmUserNetwork(Key.getKey(), Reference.getUserName()).getUserScrobbleCount() - list.getTotalUserScrobbles(); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
int other;
try {
other = net.getUserScrobbleCount() - list.getTotalUserScrobbles();
} catch (ApiCallException e) {
other = 0;
}
ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList( ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(
new PieChart.Data(String.format("%d%%", (int) list.getTotalUserScrobbles() * 100 / other), new PieChart.Data(String.format("%d%%", (int) list.getTotalUserScrobbles() * 100 / other),
list.getTotalUserScrobbles()), list.getTotalUserScrobbles()),
@ -229,13 +157,13 @@ public class FMObjListPaneEditController {
pieChart.setData(pieChartData); pieChart.setData(pieChartData);
ObservableList<PieChart.Data> pieChartArtistsData = FXCollections.observableArrayList(); ObservableList<PieChart.Data> pieChartArtistsData = FXCollections.observableArrayList();
for (counter = 0; counter < list.size(); counter++) { for (counter = 0; counter < list.size(); counter++) {
PieChart.Data data = new PieChart.Data(list.get(counter).getName(), list.get(counter).getUserPlayCount()); PieChart.Data data = new PieChart.Data(list.get(counter).getName(), list.get(counter).getUserPlayCount());
pieChartArtistsData.add(data); pieChartArtistsData.add(data);
} }
pieChartArtists.setData(pieChartArtistsData); pieChartArtists.setData(pieChartArtistsData);
} }
@ -248,26 +176,32 @@ public class FMObjListPaneEditController {
@FXML @FXML
protected void handleAddTrack(ActionEvent event) { protected void handleAddTrack(ActionEvent event) {
FmNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName()); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String name = textTrack.getText(); String name = textTrack.getText();
String album = textAlbum.getText(); String album = textAlbum.getText();
String artist = textArtist.getText(); String artist = textArtist.getText();
if ((name != null) && (artist != null)) { if ((name != null) && (artist != null)) {
Track track = net.getTrack(name, artist); Track track;
if (album != null) { try {
Album albumObj = net.getAlbum(album, artist); track = net.getTrack(name, artist);
track.setAlbum(albumObj);
textAlbum.setText(null); if (album != null) {
} Album albumObj = net.getAlbum(album, artist);
track.setAlbum(albumObj);
textTrack.setText(null);
textArtist.setText(null);
list.add(track); textAlbum.setText(null);
}
textTrack.setText(null);
textArtist.setText(null);
list.add(track);
} catch (ApiCallException e) {}
} }
refresh(); refresh();
@ -276,15 +210,22 @@ public class FMObjListPaneEditController {
@FXML @FXML
protected void handleAddAlbum(ActionEvent event) { protected void handleAddAlbum(ActionEvent event) {
FmNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName());
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String album = textAlbum.getText(); String album = textAlbum.getText();
String artist = textArtist.getText(); String artist = textArtist.getText();
if ((album != null) && (artist != null)) { if ((album != null) && (artist != null)) {
Album albumObj = net.getAlbum(album, artist); Album albumObj;
try {
list.add(albumObj); albumObj = net.getAlbum(album, artist);
list.add(albumObj);
} catch (ApiCallException e) {}
textAlbum.setText(null); textAlbum.setText(null);
textArtist.setText(null); textArtist.setText(null);
} }
@ -295,36 +236,41 @@ public class FMObjListPaneEditController {
@FXML @FXML
protected void handleAddArtist(ActionEvent event) { protected void handleAddArtist(ActionEvent event) {
FmNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName()); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String artist = textArtist.getText(); String artist = textArtist.getText();
if (artist != null) { if (artist != null) {
Artist artistObj = net.getArtist(artist); Artist artistObj;
try {
artistObj = net.getArtist(artist);
list.add(artistObj);
} catch (ApiCallException e) {}
list.add(artistObj);
textArtist.setText(null); textArtist.setText(null);
} }
refresh(); refresh();
} }
@FXML @FXML
protected void handleSave(ActionEvent event) { protected void handleSave(ActionEvent event) {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("save fm list"); fileChooser.setTitle("save fm list");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("FMObjList", "*.fmlist")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("FMObjList", "*.fmlist"));
File file = fileChooser.showSaveDialog(FmFramework.getStage()); File file = fileChooser.showSaveDialog(FmFramework.getStage());
if(file != null) { if (file != null) {
ListPersister persist = new ListPersister(); ListPersister persist = new ListPersister();
persist.saveListToFile(file, list); persist.saveListToFile(file, list);
} }
} }
} }

View File

@ -0,0 +1,245 @@
package sarsoo.fmframework.fx.controller;
import java.io.File;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONObject;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.file.JSONPersister;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.chart.GenrePieChartTitledPane;
import sarsoo.fmframework.fx.chart.PieChartTitledPane;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.InfoEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class GenrePieChartPaneController {
protected String defaultPath = "./piechart.json";
@FXML
BorderPane borderPane;
@FXML
Accordion accordionCharts;
@FXML
ToolBar toolbar;
@FXML
Button buttonLoadAll;
@FXML
Button buttonLoad;
@FXML
ChoiceBox choiceBox;
ArrayList<GenreHierarchy> genreHierarchies = new ArrayList<GenreHierarchy>();
@FXML
public void initialize() {
Config config = FmFramework.getSessionConfig();
JSONPersister persist = new JSONPersister();
JSONObject rootParsedJsonObj = persist.readJSONFromFile(".fm/piechart.json");
if (rootParsedJsonObj != null) {
JSONArray hierarchiesJsonArray = rootParsedJsonObj.getJSONObject("genrehierarchy").getJSONArray("genres");
if (hierarchiesJsonArray.length() > 0) {
// menuPieChart.setVisible(true);
}
int counter;
for (counter = 0; counter < hierarchiesJsonArray.length(); counter++) {
JSONObject hierarchyJsonObj = (JSONObject) hierarchiesJsonArray.get(counter);
// JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
// ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
String hierarchyName = hierarchyJsonObj.getString("name");
JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
int i;
for (i = 0; i < hierarchyTagsJsonArray.length(); i++) {
hierarchyTagNameList.add(hierarchyTagsJsonArray.getString(i));
// allTags.add(hierarchyTagsJsonArray.getString(i));
}
choiceBox.getItems().add(new GenreHierarchy(hierarchyName, hierarchyTagNameList));
// paneList.add(new GenrePieChartTitledPane(hierarchyName, hierarchyTagNameList));
}
}
}
@FXML
protected void handleLoad(ActionEvent event) {
GenreHierarchy hier = (GenreHierarchy) choiceBox.getValue();
if (hier != null) {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
GenrePieChartTitledPane pane = new GenrePieChartTitledPane(hier.getName(),
hier.getTagNames());
Platform.runLater(new Runnable() {
@Override
public void run() {
accordionCharts.getPanes().add(pane);
}
});
return null;
}
};
}
};
service.start();
}
}
@FXML
protected void handleLoadAll(ActionEvent event) {
Config config = FmFramework.getSessionConfig();
File file = null;
String path = null;
if (new File(".fm/piechart.json").isFile()) {
file = new File(".fm/piechart.json");
} else {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("open pie chart json");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON", "*.json"));
file = fileChooser.showOpenDialog(FmFramework.getStage());
}
if (file != null) {
JSONPersister persist = new JSONPersister();
JSONObject rootParsedJsonObj = persist.readJSONFromFile(file);
refreshPieCharts(rootParsedJsonObj);
}
}
public void refreshPieCharts(JSONObject object) {
Logger.getLog().log(new LogEntry("refreshPieCharts"));
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
JSONObject rootParsedJsonObj = object;
JSONArray hierarchiesJsonArray = rootParsedJsonObj.getJSONObject("genrehierarchy")
.getJSONArray("genres");
JSONObject pieJson = rootParsedJsonObj.getJSONObject("pie");
Logger.getLog().logInfo(new InfoEntry("refreshPieCharts").addArg("arrays parsed"));
int counter;
ArrayList<TitledPane> paneList = new ArrayList<TitledPane>();
ArrayList<String> allTags = new ArrayList<String>();
for (counter = 0; counter < hierarchiesJsonArray.length(); counter++) {
JSONObject hierarchyJsonObj = (JSONObject) hierarchiesJsonArray.get(counter);
JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
String hierarchyName = hierarchyJsonObj.getString("name");
int i;
for (i = 0; i < hierarchyTagsJsonArray.length(); i++) {
hierarchyTagNameList.add(hierarchyTagsJsonArray.getString(i));
allTags.add(hierarchyTagsJsonArray.getString(i));
}
paneList.add(new GenrePieChartTitledPane(hierarchyName, hierarchyTagNameList));
}
JSONArray totalPieTags = pieJson.getJSONArray("tags");
int i;
for (i = 0; i < totalPieTags.length(); i++) {
allTags.add((totalPieTags).getString(i));
}
paneList.add(new PieChartTitledPane("total", allTags));
// final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
accordionCharts.getPanes().clear();
int i;
for (i = 0; i < paneList.size(); i++) {
accordionCharts.getPanes().add(paneList.get(i));
}
} finally {
// latch.countDown();
}
}
});
// latch.await();
return null;
}
};
}
};
service.start();
}
}
class GenreHierarchy {
private String name;
private ArrayList<String> tagNames;
public GenreHierarchy(String name, ArrayList<String> tagNames) {
this.name = name;
this.tagNames = tagNames;
}
public String getName() {
return name;
}
public ArrayList<String> getTagNames() {
return tagNames;
}
@Override
public String toString() {
return name;
}
}

View File

@ -1,372 +1,192 @@
package sarsoo.fmframework.fx.controller; package sarsoo.fmframework.fx.controller;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.config.ConfigPersister;
import sarsoo.fmframework.config.ConfigVariable;
import sarsoo.fmframework.config.VariableEvent;
import sarsoo.fmframework.config.VariableListener;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.file.ListPersister; import sarsoo.fmframework.file.ListPersister;
import sarsoo.fmframework.fm.FmUserNetwork; import sarsoo.fmframework.fm.FmAuthNetwork;
import sarsoo.fmframework.fx.TextAreaConsole; import sarsoo.fmframework.fx.TextAreaConsole;
import sarsoo.fmframework.fx.chart.GenrePieChartTitledPane; import sarsoo.fmframework.fx.service.GetLastTrackService;
import sarsoo.fmframework.fx.chart.PieChartTitledPane; import sarsoo.fmframework.fx.service.GetScrobbleCountService;
import sarsoo.fmframework.fx.service.GetTagMenuItemsService;
import sarsoo.fmframework.fx.service.GetTagsService;
import sarsoo.fmframework.fx.service.ScrobbleCount;
import sarsoo.fmframework.fx.tab.AlbumTab; import sarsoo.fmframework.fx.tab.AlbumTab;
import sarsoo.fmframework.fx.tab.ArtistTab; import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.fx.tab.ConsoleTab; import sarsoo.fmframework.fx.tab.ConsoleTab;
import sarsoo.fmframework.fx.tab.FMObjListEditTab; import sarsoo.fmframework.fx.tab.FMObjListEditTab;
import sarsoo.fmframework.fx.tab.FMObjListTab; import sarsoo.fmframework.fx.tab.GenrePieChartTab;
import sarsoo.fmframework.fx.tab.ScrobbleChartTab; import sarsoo.fmframework.fx.tab.ScrobbleChartTab;
import sarsoo.fmframework.fx.tab.ScrobbleTab;
import sarsoo.fmframework.fx.tab.TopAlbumTab;
import sarsoo.fmframework.fx.tab.TrackTab; import sarsoo.fmframework.fx.tab.TrackTab;
import sarsoo.fmframework.fx.tab.WebViewTab;
import sarsoo.fmframework.log.Log;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.fx.FmFramework; import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Album; import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Tag; import sarsoo.fmframework.music.Tag;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.util.ConsoleHandler;
import sarsoo.fmframework.util.FMObjList; import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.Reference;
import sarsoo.fmframework.util.tagpool.TagPool;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.concurrent.*; import javafx.concurrent.*;
import javafx.application.Platform; import javafx.application.Platform;
import org.json.*;
public class RootController { public class RootController {
@FXML @FXML
public void initialize() { public void initialize() {
// Reference.setUserName("sarsoo"); Logger.setLog(new Log(TextAreaConsole.getInstance()));
ConsoleHandler.setVerbose(TextAreaConsole.getInstance()); Config config = FmFramework.getSessionConfig();
if (config.getVariable("api_key") == null) {
while (config.getVariable("api_key") == null) {
setApiKey();
}
}
if (config.getVariable("username") == null) {
while (config.getVariable("username") == null) {
changeUsername();
}
}
new ConfigPersister().saveConfig(".fm/", config);
FmFramework.getSessionConfig().getVariable("username").addListener(new VariableListener() {
@Override
public void listen(VariableEvent event) {
refresh();
}
});
refresh(); refresh();
} }
public void refresh() { public void refresh() {
labelStatsUsername.setText(FmFramework.getSessionConfig().getValue("username"));
refreshScrobbleCounts();
addLastTrackTab();
refreshTagMenu();
}
public void refreshScrobbleCounts() {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.UK);
GetScrobbleCountService getScrobbles = new GetScrobbleCountService();
getScrobbles.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
Service<Void> service = new Service<Void>() {
@Override @Override
protected Task<Void> createTask() { public void handle(WorkerStateEvent t) {
return new Task<Void>() { Platform.runLater(new Runnable() {
@Override @Override
protected Void call() throws Exception { public void run() {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US); labelStatsScrobblesToday.setText(
numberFormat.format(((ScrobbleCount) t.getSource().getValue()).getDailyCount()));
FmUserNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName()); labelStatsScrobblesTotal.setText(
numberFormat.format(((ScrobbleCount) t.getSource().getValue()).getTotalCount()));
String scrobblesToday = numberFormat.format(net.getScrobblesToday());
String scrobbles = numberFormat.format(net.getUserScrobbleCount());
TrackTab tab = new TrackTab(net.getLastTrack());
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
labelStatsScrobblesToday.setText(scrobblesToday);
labelStatsUsername.setText(Reference.getUserName());
labelStatsScrobblesTotal.setText(scrobbles);
addTab(tab);
// refreshPieCharts();
refreshTagMenu();
refreshPieChartMenu();
} finally {
latch.countDown();
}
}
});
latch.await();
// Keep with the background work
return null;
} }
};
});
} }
}; });
service.start(); getScrobbles.start();
}
public void addLastTrackTab() {
GetLastTrackService getLastTrack = new GetLastTrackService();
getLastTrack.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
TrackTab tab = new TrackTab(((Track) t.getSource().getValue()));
Platform.runLater(new Runnable() {
@Override
public void run() {
addTab(tab, false);
}
});
}
});
getLastTrack.start();
} }
public void refreshTagMenu() { public void refreshTagMenu() {
FmUserNetwork net = new FmUserNetwork(Key.getKey(), Reference.getUserName());
tags = net.getTags(); GetTagsService getTags = new GetTagsService();
getTags.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
Collections.sort(tags);
int counter;
for (counter = 0; counter < tags.size(); counter++) {
String name = tags.get(counter).getName().toLowerCase();
// System.out.println(name);
MenuItem item = new MenuItem(name);
item.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
// TAG ITEM HANDLER SERVICE
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
FMObjListTab tab = new FMObjListTab(TagPool.getPool().getTag(name));
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
tabPane.getTabs().add(tab);
} finally {
latch.countDown();
}
}
});
latch.await();
// Keep with the background work
return null;
}
};
}
};
service.start();
}
});
menuTag.getItems().add(item);
}
}
public void refreshPieChartMenu() {
try {
if (new File("./piechart.json").isFile()) {
File file = new File("./piechart.json");
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String jsonLine = br.readLine();
while (jsonLine != null) {
sb.append(jsonLine);
jsonLine = br.readLine();
}
br.close();
String jsonString = sb.toString();
JSONObject rootParsedJsonObj = new JSONObject(jsonString);
JSONArray hierarchiesJsonArray = rootParsedJsonObj.getJSONObject("genrehierarchy")
.getJSONArray("genres");
if(hierarchiesJsonArray.length() > 0) {
menuPieChart.setVisible(true);
}
int counter;
for (counter = 0; counter < hierarchiesJsonArray.length(); counter++) {
JSONObject hierarchyJsonObj = (JSONObject) hierarchiesJsonArray.get(counter);
// JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
// ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
String hierarchyName = hierarchyJsonObj.getString("name");
JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
int i;
for (i = 0; i < hierarchyTagsJsonArray.length(); i++) {
hierarchyTagNameList.add(hierarchyTagsJsonArray.getString(i));
// allTags.add(hierarchyTagsJsonArray.getString(i));
System.out.println(hierarchyTagsJsonArray.getString(i));
}
System.out.println("hierarchy: " + hierarchyName);
System.out.println(hierarchyTagNameList);
// paneList.add(new GenrePieChartTitledPane(hierarchyName, hierarchyTagNameList));
MenuItem item = new MenuItem(hierarchyName);
item.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
// TAG ITEM HANDLER SERVICE
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
GenrePieChartTitledPane pane = new GenrePieChartTitledPane(hierarchyName,
hierarchyTagNameList);
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
accordionCharts.getPanes().add(pane);
} finally {
latch.countDown();
}
}
});
latch.await();
// Keep with the background work
return null;
}
};
}
};
service.start();
}
});
menuPieChart.getItems().add(item);
}
}
} catch (IOException e) {
}
}
public void refreshPieCharts(File file) {
// File file = null;
// String path = null;
// if (new File("./piechart.json").isFile()) {
// file = new File("./piechart.json");
// } else {
// FileChooser fileChooser = new FileChooser();
// fileChooser.setTitle("open pie chart json");
// fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON", "*.json"));
// file = fileChooser.showOpenDialog(FmFramework.getStage());
// }
Service<Void> service = new Service<Void>() {
@Override @Override
protected Task<Void> createTask() { public void handle(WorkerStateEvent t) {
return new Task<Void>() {
tags = (ArrayList<Tag>) t.getSource().getValue();
Collections.sort(tags);
GetTagMenuItemsService getTagMenuItems = new GetTagMenuItemsService(tags);
getTagMenuItems.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override @Override
protected Void call() throws Exception { public void handle(WorkerStateEvent t) {
String jsonString = null;
// System.out.println(file.getPath());
if (file != null) {
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String jsonLine = br.readLine();
while (jsonLine != null) {
sb.append(jsonLine);
jsonLine = br.readLine();
}
br.close();
jsonString = sb.toString();
System.out.println("json read");
}
JSONObject rootParsedJsonObj = new JSONObject(jsonString);
JSONArray hierarchiesJsonArray = rootParsedJsonObj.getJSONObject("genrehierarchy")
.getJSONArray("genres");
JSONObject pieJson = rootParsedJsonObj.getJSONObject("pie");
System.out.println("arrays parsed");
int counter;
ArrayList<TitledPane> paneList = new ArrayList<TitledPane>();
ArrayList<String> allTags = new ArrayList<String>();
for (counter = 0; counter < hierarchiesJsonArray.length(); counter++) {
JSONObject hierarchyJsonObj = (JSONObject) hierarchiesJsonArray.get(counter);
JSONArray hierarchyTagsJsonArray = hierarchyJsonObj.getJSONArray("tags");
ArrayList<String> hierarchyTagNameList = new ArrayList<String>();
String hierarchyName = hierarchyJsonObj.getString("name");
int i;
for (i = 0; i < hierarchyTagsJsonArray.length(); i++) {
hierarchyTagNameList.add(hierarchyTagsJsonArray.getString(i));
allTags.add(hierarchyTagsJsonArray.getString(i));
System.out.println(hierarchyTagsJsonArray.getString(i));
}
System.out.println("hierarchy: " + hierarchyName);
System.out.println(hierarchyTagNameList);
paneList.add(new GenrePieChartTitledPane(hierarchyName, hierarchyTagNameList));
}
JSONArray totalPieTags = pieJson.getJSONArray("tags");
int i;
for (i = 0; i < totalPieTags.length(); i++) {
allTags.add((totalPieTags).getString(i));
}
System.out.println(allTags);
paneList.add(new PieChartTitledPane("total", allTags));
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { public void run() {
try { menuTag.getItems().setAll((ArrayList<MenuItem>) t.getSource().getValue());
accordionCharts.getPanes().clear(); menuTag.setDisable(false);
int i;
for (i = 0; i < paneList.size(); i++) {
accordionCharts.getPanes().add(paneList.get(i));
}
} finally {
latch.countDown();
}
} }
}); });
latch.await();
return null;
} }
}; });
getTagMenuItems.start();
} }
}; });
service.start();
getTags.start();
}
public void addTab(Tab tab) {
addTab(tab, true);
} }
public void addTab(Tab tab) { public void addTab(Tab tab, Boolean select) {
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);
SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel(); SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel();
selectionModel.select(tab); if(select)
selectionModel.select(tab);
} }
@FXML @FXML
@ -375,49 +195,98 @@ public class RootController {
if (event.getCode() == KeyCode.F5) { if (event.getCode() == KeyCode.F5) {
refresh(); refresh();
} }
if (event.getCode() == KeyCode.W && event.isControlDown()) {
closeCurrentTab();
}
if (event.getCode() == KeyCode.TAB && event.isControlDown()) {
if (event.isShiftDown()) {
tabPane.getSelectionModel().selectPrevious();
} else {
tabPane.getSelectionModel().selectNext();
}
}
} }
@FXML @FXML
protected void handleChangeUsername(ActionEvent event) throws IOException { protected void handleChangeUsername(ActionEvent event) {
// System.out.println("USERNAME"); changeUsername();
// String username = JOptionPane.showInputDialog("enter username:"); }
// if(username != null) {
// Reference.setUserName(username); @FXML
// } protected void handleAuth(ActionEvent event) {
// refresh(); authenticate();
}
public void authenticate() {
try {
Config config = FmFramework.getSessionConfig();
if (config.getVariable("api_secret") != null) {
FmAuthNetwork net = new FmAuthNetwork(config.getValue("api_key"), config.getValue("api_secret"),
config.getValue("username"));
String token = net.getToken();
String url = String.format("http://www.last.fm/api/auth/?api_key=%s&token=%s",
config.getValue("api_key"), token);
Tab tab = new WebViewTab(url);
tab.setOnClosed(new EventHandler<Event>() {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override @Override
protected Void call() throws Exception { public void handle(Event arg0) {
completeAuth(net, token);
System.out.println("USERNAME");
String username = JOptionPane.showInputDialog("enter username:");
if (username != null) {
Reference.setUserName(username);
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
refresh();
} finally {
latch.countDown();
}
}
});
latch.await();
}
// Keep with the background work
return null;
} }
}; });
addTab(tab, true);
} }
};
service.start(); } catch (IOException e) {
e.printStackTrace();
} catch (ApiCallException e) {
}
}
protected void completeAuth(FmAuthNetwork net, String token) {
String sk;
try {
sk = net.getSession(token);
if (sk != null) {
FmFramework.getSessionConfig().addVariable(new ConfigVariable("session_key", sk));
}
} catch (ApiCallException e) {
}
}
public void changeUsername() {
String username = JOptionPane.showInputDialog("enter username:");
if (username != null) {
FmFramework.getSessionConfig().addVariable(new ConfigVariable("username", username));
}
}
public void setApiKey() {
String apiKey = JOptionPane.showInputDialog("enter api key:");
if (apiKey != null) {
FmFramework.getSessionConfig().addVariable(new ConfigVariable("api_key", apiKey));
}
} }
@FXML @FXML
@ -434,18 +303,18 @@ public class RootController {
if (album != null) { if (album != null) {
AlbumTab tab = new AlbumTab(album); AlbumTab tab = new AlbumTab(album);
final CountDownLatch latch = new CountDownLatch(1); // final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);
} finally { } finally {
latch.countDown(); // latch.countDown();
} }
} }
}); });
latch.await(); // latch.await();
} }
// Keep with the background work // Keep with the background work
return null; return null;
@ -471,20 +340,19 @@ public class RootController {
if (artist != null) { if (artist != null) {
ArtistTab tab = new ArtistTab(artist); ArtistTab tab = new ArtistTab(artist);
final CountDownLatch latch = new CountDownLatch(1); // final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
tabPane.getTabs().add(tab); tabPane.getTabs().add(tab);
} finally { } finally {
latch.countDown(); // latch.countDown();
} }
} }
}); });
latch.await(); // latch.await();
} }
// Keep with the background work
return null; return null;
} }
}; };
@ -508,20 +376,13 @@ public class RootController {
if (track != null) { if (track != null) {
TrackTab tab = new TrackTab(track); TrackTab tab = new TrackTab(track);
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() { Platform.runLater(new Runnable() {
@Override @Override
public void run() { public void run() {
try { tabPane.getTabs().add(tab);
tabPane.getTabs().add(tab);
} finally {
latch.countDown();
}
} }
}); });
latch.await();
} }
// Keep with the background work
return null; return null;
} }
}; };
@ -532,93 +393,50 @@ public class RootController {
@FXML @FXML
protected void handleCurrentTrack(ActionEvent event) throws IOException { protected void handleCurrentTrack(ActionEvent event) throws IOException {
Service<Void> service = new Service<Void>() { addLastTrackTab();
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
Track track = new FmUserNetwork(Key.getKey(), Reference.getUserName()).getLastTrack();
if (track != null) {
TrackTab tab = new TrackTab(track);
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
tabPane.getTabs().add(tab);
} finally {
latch.countDown();
}
}
});
latch.await();
}
// Keep with the background work
return null;
}
};
}
};
service.start();
}
@FXML
protected void handleRefreshPieChart(ActionEvent event) throws IOException {
File file = null;
String path = null;
if (new File("./piechart.json").isFile()) {
file = new File("./piechart.json");
} else {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("open pie chart json");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON", "*.json"));
file = fileChooser.showOpenDialog(FmFramework.getStage());
}
refreshPieCharts(file);
} }
@FXML @FXML
protected void handleCreateList(ActionEvent event) { protected void handleCreateList(ActionEvent event) {
try { Tab tab = new FMObjListEditTab();
Tab tab = new FMObjListEditTab(); addTab(tab, true);
addTab(tab);
} catch (IOException e) {
e.printStackTrace();
}
} }
@FXML
protected void handlePrintConfig(ActionEvent event) {
System.out.println(FmFramework.getSessionConfig());
}
@FXML
protected void handleDumpCache(ActionEvent event) {
Log log = Logger.getLog();
FmFramework.getTrackPool().dumpToLog(log);
FmFramework.getAlbumPool().dumpToLog(log);
FmFramework.getArtistPool().dumpToLog(log);
FmFramework.getTagPool().dumpToLog(log);
}
@FXML @FXML
protected void handleScrobble(ActionEvent event) throws IOException { protected void handleScrobble(ActionEvent event) throws IOException {
// Album album = sarsoo.fmframework.jframe.Getter.getAlbum(); addTab(new ScrobbleTab(), true);
// if (album != null) {
// Track track = sarsoo.fmframework.jframe.Getter.getTrack(album);
//
// }
} }
@FXML @FXML
protected void handleOpenConsole(ActionEvent event) { protected void handleOpenConsole(ActionEvent event) {
addTab(new ConsoleTab()); addTab(new ConsoleTab(), true);
} }
@FXML
protected void handleTopAlbum(ActionEvent event) {
addTab(new TopAlbumTab(), true);
}
@FXML @FXML
protected void handleScrobbleChart(ActionEvent event) { protected void handleScrobbleChart(ActionEvent event) {
try { addTab(new ScrobbleChartTab(), true);
addTab(new ScrobbleChartTab());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
@ -636,17 +454,34 @@ public class RootController {
FMObjList list = persist.readListFromFile(file); FMObjList list = persist.readListFromFile(file);
list.setGroupName(file.getName()); list.setGroupName(file.getName());
list.refresh(); list.refresh();
try { addTab(new FMObjListEditTab(list), true);
addTab(new FMObjListEditTab(list));
} catch (IOException e) {
e.printStackTrace();
}
} }
} }
@FXML @FXML
protected void handleOpenEdit(ActionEvent event) { protected void handleOpenEdit(ActionEvent event) {
addTab(new ConsoleTab()); addTab(new ConsoleTab(), true);
}
public void closeCurrentTab() {
SingleSelectionModel<Tab> selectionModel = tabPane.getSelectionModel();
Tab tab = selectionModel.getSelectedItem();
if (tab.isClosable()) {
EventHandler<Event> handler = tab.getOnClosed();
if (handler != null) {
handler.handle(null);
} else {
tabPane.getTabs().remove(tab);
}
}
}
@FXML
protected void handleGenrePieTab(ActionEvent event) {
addTab(new GenrePieChartTab(), true);
} }
private ArrayList<Tag> tags; private ArrayList<Tag> tags;
@ -659,9 +494,6 @@ public class RootController {
@FXML @FXML
private Label labelStatsScrobblesTotal; private Label labelStatsScrobblesTotal;
//
// @FXML
// private PieChart pieChartGenres;
@FXML @FXML
private TabPane tabPane; private TabPane tabPane;
@ -671,32 +503,11 @@ public class RootController {
@FXML @FXML
private Menu menuPieChart; private Menu menuPieChart;
@FXML @FXML
private Menu menuChart; private Menu menuChart;
//
// @FXML
// private PieChart pieChartRap;
//
// @FXML
// private PieChart pieChartRapTotal;
//
// @FXML
// private PieChart pieChartRock;
//
// @FXML
// private PieChart pieChartRockTotal;
@FXML @FXML
private Accordion accordionCharts; private Accordion accordionCharts;
@FXML
private TitledPane titledPaneGenres;
@FXML
private TitledPane titledPaneRap;
@FXML
private StackPane stackViewGenres;
} }

View File

@ -8,9 +8,10 @@ import javafx.concurrent.Service;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork; import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Album; import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.net.Key;
import javafx.scene.chart.BarChart; import javafx.scene.chart.BarChart;
import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart;
import javafx.scene.control.*; import javafx.scene.control.*;
@ -38,6 +39,8 @@ public class ScrobbleChartPaneController {
// dropDownTimeRange.setItems(FXCollections.observableArrayList("week", "month", // dropDownTimeRange.setItems(FXCollections.observableArrayList("week", "month",
// "3 month", "6 month", "year")); // "3 month", "6 month", "year"));
dropDownTimeRange.getItems().addAll("week", "30 day", "90 day", "180 day", "year"); dropDownTimeRange.getItems().addAll("week", "30 day", "90 day", "180 day", "year");
dropDownTimeRange.getSelectionModel().select(0);
} }
@FXML @FXML
@ -57,7 +60,9 @@ public class ScrobbleChartPaneController {
@Override @Override
protected Void call() throws Exception { protected Void call() throws Exception {
FmUserNetwork net = new FmUserNetwork(Key.getKey(), "sarsoo"); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String value = (String) dropDownTimeRange.getValue(); String value = (String) dropDownTimeRange.getValue();
int dayLength = 0; int dayLength = 0;

View File

@ -0,0 +1,187 @@
package sarsoo.fmframework.fx.controller;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import org.json.JSONObject;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmAuthNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Artist.ArtistBuilder;
import sarsoo.fmframework.music.Scrobble;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.music.Track.TrackBuilder;
import sarsoo.fmframework.music.Album.AlbumBuilder;
public class ScrobblePaneController {
@FXML
private TextField textTrack;
@FXML
private TextField textAlbum;
@FXML
private TextField textArtist;
@FXML
private TextField textAlbumArtist;
@FXML
private Slider sliderHour;
@FXML
private Slider sliderMinute;
@FXML
private Slider sliderSecond;
@FXML
private Label labelStatus;
@FXML
private DatePicker datePicker;
@FXML
private Button buttonScrobble;
@FXML
public void initialize() {
Config config = FmFramework.getSessionConfig();
if (config.getValue("session_key") == null) {
FmFramework.getController().authenticate();
}
}
@FXML
private void handleClear() {
textTrack.setText("");
textAlbum.setText("");
textArtist.setText("");
textAlbumArtist.setText("");
sliderHour.setValue(0);
sliderMinute.setValue(0);
sliderSecond.setValue(0);
datePicker.setValue(null);
}
@FXML
private void handleScrobble() {
if (validateText()) {
if (validateDate()) {
Config config = FmFramework.getSessionConfig();
if (config.getValue("session_key") != null) {
FmAuthNetwork net = new FmAuthNetwork(config.getValue("api_key"),
config.getValue("api_secret"),
config.getValue("username"));
Artist artist = new ArtistBuilder(textArtist.getText()).build();
Track track = new TrackBuilder(textTrack.getText(), artist).build();
Scrobble scrobble = new Scrobble(getEpochDate(), track);
if(textAlbum.getText().length() > 0) {
Artist albumArtist = new ArtistBuilder(textAlbumArtist.getText()).build();
scrobble.setAlbum(new AlbumBuilder(textAlbum.getText(), albumArtist).build());
}
JSONObject obj;
try {
obj = net.scrobble(scrobble, config.getValue("session_key"));
if(obj.getJSONObject("scrobbles").getJSONObject("@attr").getInt("accepted") == 1) {
labelStatus.setText("sent!");
}else {
labelStatus.setText("failed");
}
} catch (ApiCallException e) {}
}else {
labelStatus.setText("unauthorized");
}
} else {
labelStatus.setText("wrong date");
}
} else {
labelStatus.setText("wrong text");
}
}
@FXML
public void handleNow() {
LocalDateTime date = LocalDateTime.now();
datePicker.setValue(date.toLocalDate());
sliderHour.setValue(date.getHour());
sliderMinute.setValue(date.getMinute());
sliderSecond.setValue(date.getSecond());
}
private boolean validateText() {
String track = textTrack.getText();
String album = textAlbum.getText();
String artist = textArtist.getText();
String albumArtist = textAlbumArtist.getText();
if (track.length() > 0 && artist.length() > 0) {
if (album.length() > 0 ^ albumArtist.length() > 0) {
return false;
} else {
return true;
}
}
return false;
}
private boolean validateDate() {
if (datePicker.getValue() != null) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime selected = getLocalDateTime();
if (selected.isAfter(now.minusWeeks(2))) {
if (selected.isBefore(now)) {
return true;
}
return false;
}
return false;
}
return false;
}
public LocalDateTime getLocalDateTime() {
LocalDate date = datePicker.getValue();
LocalTime time = LocalTime.of((int) sliderHour.getValue(), (int) sliderMinute.getValue(),
(int) sliderSecond.getValue());
return LocalDateTime.of(date, time);
}
public long getEpochDate() {
ZoneId zone = ZoneId.systemDefault();
return getLocalDateTime().atZone(zone).toEpochSecond();
}
}

View File

@ -0,0 +1,324 @@
package sarsoo.fmframework.fx.controller;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import javafx.fxml.FXML;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.GridPane;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.music.Scrobble;
import sarsoo.fmframework.util.FMObjCalendarWrapper;
import sarsoo.fmframework.util.MonthScrobbles;
import sarsoo.fmframework.util.ScrobbleCountCalendar;
public class ScrobblesViewPaneController {
@FXML
private SplitPane splitPane;
@FXML
private GridPane gridPane;
@FXML
private AreaChart<String, Integer> areaChart;
@FXML
private Button buttonTracks;
@FXML
private Button buttonAlbums;
@FXML
private Button buttonTracksAlbums;
@FXML
private CheckBox checkBoxCumulative;
@FXML
private CheckBox checkBoxTotal;
private FMObj obj;
private List<Scrobble> scrobbles;
private LocalDate firstDate;
@FXML
public void initialize() {
buttonTracks.setDisable(true);
buttonAlbums.setDisable(true);
buttonTracksAlbums.setDisable(true);
}
public void populate(FMObj obj) {
this.obj = obj;
this.scrobbles = obj.getScrobbles();
populate();
}
public void populate(ArrayList<Scrobble> scrobbles) {
this.scrobbles = scrobbles;
populate();
}
private void populate() {
scrobbles.sort(Comparator.comparing(Scrobble::getDateTime).reversed());
if (scrobbles != null) {
if (scrobbles.size() > 0) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.UK);
gridPane.getChildren().clear();
int counter;
for (counter = 0; counter < scrobbles.size(); counter++) {
Scrobble scrobble = scrobbles.get(counter);
Label trackName = new Label(scrobble.getTrack().getName().toLowerCase());
Label artistName = new Label(scrobble.getTrack().getArtist().getName().toLowerCase());
Label date = new Label(scrobble.getDateTime().toString().toLowerCase());
gridPane.add(trackName, 0, counter);
gridPane.add(artistName, 2, counter);
gridPane.add(date, 3, counter);
if (scrobble.getAlbum() != null) {
Label albumName = new Label(scrobble.getAlbum().getName().toLowerCase());
gridPane.add(albumName, 1, counter);
}
}
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
try {
firstDate = net.getFirstScrobbleDateTime().toLocalDate();
} catch (ApiCallException e) {
firstDate = LocalDate.now();
}
buttonAlbums.setDisable(false);
buttonTracksAlbums.setDisable(false);
graphShowTracks();
}
}
}
public void graphShowTracks() {
ArrayList<FMObjCalendarWrapper> list = new ArrayList<>();
ScrobbleCountCalendar totalCalendar = new ScrobbleCountCalendar(firstDate, "total");
for (Scrobble scrobble : scrobbles) {
Boolean needNew = true;
LocalDateTime scrobbleDate = scrobble.getDateTime();
for (FMObjCalendarWrapper wrapper : list) {
if (scrobble.getTrack().equals(wrapper.getScrobble().getTrack())) {
needNew = false;
wrapper.getCalendar().addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
}
if (needNew) {
ScrobbleCountCalendar calendar = new ScrobbleCountCalendar(firstDate, scrobble.getTrack().getName());
calendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
list.add(new FMObjCalendarWrapper(scrobble, calendar));
}
totalCalendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
List<ScrobbleCountCalendar> toShow = list.stream().map(FMObjCalendarWrapper::getCalendar)
.collect(Collectors.toList());
if (list.size() > 1 && checkBoxTotal.isSelected()) {
toShow.add(totalCalendar);
}
refreshGraph(toShow);
}
public void graphShowAlbums() {
ArrayList<FMObjCalendarWrapper> list = new ArrayList<>();
ScrobbleCountCalendar totalCalendar = new ScrobbleCountCalendar(firstDate, "total");
for (Scrobble scrobble : scrobbles) {
Boolean needNew = true;
LocalDateTime scrobbleDate = scrobble.getDateTime();
for (FMObjCalendarWrapper wrapper : list) {
if (scrobble.getAlbum().equals(wrapper.getScrobble().getAlbum())) {
needNew = false;
wrapper.getCalendar().addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
}
if (needNew) {
ScrobbleCountCalendar calendar = new ScrobbleCountCalendar(firstDate, scrobble.getAlbum().getName());
calendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
list.add(new FMObjCalendarWrapper(scrobble, calendar));
}
totalCalendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
List<ScrobbleCountCalendar> toShow = list.stream().map(FMObjCalendarWrapper::getCalendar)
.collect(Collectors.toList());
if (list.size() > 1 && checkBoxTotal.isSelected()) {
toShow.add(totalCalendar);
}
refreshGraph(toShow);
}
public void graphShowTracksByAlbum() {
ArrayList<FMObjCalendarWrapper> list = new ArrayList<>();
ScrobbleCountCalendar totalCalendar = new ScrobbleCountCalendar(firstDate, "total");
for (Scrobble scrobble : scrobbles) {
Boolean needNew = true;
LocalDateTime scrobbleDate = scrobble.getDateTime();
for (FMObjCalendarWrapper wrapper : list) {
if (scrobble.getTrack().equals(wrapper.getScrobble().getTrack())
&& scrobble.getAlbum().equals(wrapper.getScrobble().getAlbum())) {
needNew = false;
wrapper.getCalendar().addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
}
if (needNew) {
ScrobbleCountCalendar calendar = new ScrobbleCountCalendar(firstDate, scrobble.getTrack().getName() + " / " + scrobble.getAlbum().getName());
calendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
list.add(new FMObjCalendarWrapper(scrobble, calendar));
}
totalCalendar.addCount(scrobbleDate.getMonth(), scrobbleDate.getYear());
}
List<ScrobbleCountCalendar> toShow = list.stream().map(FMObjCalendarWrapper::getCalendar)
.collect(Collectors.toList());
if (list.size() > 1 && checkBoxTotal.isSelected()) {
toShow.add(totalCalendar);
}
refreshGraph(toShow);
}
public void refreshGraph(List<ScrobbleCountCalendar> calendars) {
areaChart.getData().clear();
for (ScrobbleCountCalendar calendar : calendars) {
XYChart.Series<String, Integer> series = new XYChart.Series<>();
series.setName(calendar.getName());
int cumulative = 0;
for (MonthScrobbles month : calendar.getMonthScrobbles()) {
cumulative += month.getCount();
if (checkBoxCumulative.isSelected()) {
series.getData().add(new Data<String, Integer>(month.toString(), cumulative));
}else {
series.getData().add(new Data<String, Integer>(month.toString(), month.getCount()));
}
}
areaChart.getData().add(series);
}
}
@FXML
private void handleShowTracks() {
buttonTracks.setDisable(true);
buttonAlbums.setDisable(false);
buttonTracksAlbums.setDisable(false);
graphShowTracks();
}
@FXML
private void handleShowAlbums() {
buttonTracks.setDisable(false);
buttonAlbums.setDisable(true);
buttonTracksAlbums.setDisable(false);
graphShowAlbums();
}
@FXML
private void handleShowTracksByAlbums() {
buttonTracks.setDisable(false);
buttonAlbums.setDisable(false);
buttonTracksAlbums.setDisable(true);
graphShowTracksByAlbum();
}
}

View File

@ -0,0 +1,216 @@
package sarsoo.fmframework.fx.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.ToolBar;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.TilePane;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fm.TimePeriod;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.TiledImage;
import sarsoo.fmframework.fx.service.GetFXImageService;
import sarsoo.fmframework.fx.service.GetTopAlbumsService;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.util.FMObjList;
public class TopAlbumController {
@FXML
protected BorderPane borderPane;
@FXML
protected ToolBar toolBar;
@FXML
protected ChoiceBox<String> dropDownTimeRange;
@FXML
protected ChoiceBox<Integer> dropDownLimit;
@FXML
protected Button buttonLoad;
@FXML
protected Button buttonGenerate;
@FXML
protected GridPane gridPane;
@FXML
protected TilePane tilePane;
FMObjList albums;
ArrayList<TiledImage> images = new ArrayList<>();
@FXML
public void initialize() {
dropDownTimeRange.getItems().addAll("week", "30 day", "90 day", "180 day", "year", "overall");
for (int i = 1; i < 16; i++) {
dropDownLimit.getItems().add(i);
}
for (int i = 20; i < 110; i += 10) {
dropDownLimit.getItems().add(i);
}
dropDownTimeRange.getSelectionModel().select(0);
dropDownLimit.getSelectionModel().select(0);
}
@FXML
private void handleLoad(ActionEvent event) {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String value = (String) dropDownTimeRange.getValue();
TimePeriod timePeriod = null;
switch (value) {
case "week":
timePeriod = TimePeriod.SEVENDAY;
break;
case "30 day":
timePeriod = TimePeriod.ONEMONTH;
break;
case "90 day":
timePeriod = TimePeriod.THREEMONTH;
break;
case "180 day":
timePeriod = TimePeriod.SIXMONTH;
break;
case "year":
timePeriod = TimePeriod.TWELVEMONTH;
break;
case "overall":
timePeriod = TimePeriod.OVERALL;
break;
}
GetTopAlbumsService service = new GetTopAlbumsService(timePeriod, dropDownLimit.getValue(), net);
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
Platform.runLater(new Runnable() {
@Override
public void run() {
gridPane.getChildren().clear();
if (albums != null)
albums.clear();
albums = (FMObjList) t.getSource().getValue();
if (albums.size() > 0) {
buttonGenerate.setDisable(false);
} else {
buttonGenerate.setDisable(true);
}
int counter = 0;
for (FMObj fmObj : albums) {
Album album = (Album) fmObj;
Label albumName = new Label(album.getName().toLowerCase());
Label artistName = new Label(album.getArtist().getName().toLowerCase());
Label userPlays = new Label(Integer.toString(album.getUserPlayCount()));
gridPane.add(new Label(Integer.toString(counter + 1)), 0, counter);
gridPane.add(albumName, 1, counter);
gridPane.add(artistName, 2, counter);
gridPane.add(userPlays, 3, counter);
counter++;
}
}
});
}
});
service.start();
}
@FXML
private void handleGenerate(ActionEvent event) {
if (albums != null) {
if (albums.size() > 0) {
tilePane.getChildren().clear();
images.clear();
int counter = 0;
for (FMObj obj : albums) {
Album album = (Album) obj;
if (album.getImageURL() != null) {
GetFXImageService service = new GetFXImageService(album.getImageURL(), counter);
service.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
TiledImage image = (TiledImage) t.getSource().getValue();
images.add(image);
refreshImages();
}
});
service.start();
counter++;
}
}
}
}
}
private void refreshImages() {
ObservableList<Node> list = tilePane.getChildren();
list.clear();
Collections.sort(images, new Comparator<TiledImage>() {
@Override
public int compare(TiledImage arg0, TiledImage arg1) {
return arg0.getIndex() - arg1.getIndex();
}
});
for (TiledImage image : images) {
list.add(new ImageView(image));
}
}
}

View File

@ -1,148 +0,0 @@
package sarsoo.fmframework.fx.controller;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.tab.AlbumTab;
import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.net.Key;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
import javafx.scene.control.*;
public class TrackPaneController {
@FXML
private Label labelTrackName;
@FXML
private Label labelAlbumName;
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
private Button buttonViewAlbum;
@FXML
public void initialize() {
}
Track track;
public void populate(Track track) {
this.track = track;
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelTrackName.setText(track.getName());
if (track.getAlbum() == null)
labelAlbumName.setVisible(false);
else
labelAlbumName.setText(track.getAlbum().getName());
labelArtistName.setText(track.getArtist().getName());
labelUserScrobbles.setText(numberFormat.format(track.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(track, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(track.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(track.getPlayCount()) + " Total Scrobbles");
double ratio = track.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = track.getWiki();
if (wiki != null) {
textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
}
if (track.getAlbum() == null) {
buttonViewAlbum.setVisible(false);
}
}
@FXML
protected void handleRefresh(ActionEvent event) {
refresh();
}
@FXML
protected void viewOnline(ActionEvent event) {
Network.openURL(track.getUrl());
}
@FXML
protected void viewArtist(ActionEvent event) throws IOException {
FmFramework.getController().addTab(new ArtistTab(track.getArtist()));
}
@FXML
protected void viewAlbum(ActionEvent event) throws IOException {
FmFramework.getController().addTab(new AlbumTab(track.getAlbum()));
}
public void refresh() {
track = new FmUserNetwork(Key.getKey(), Reference.getUserName()).refresh(track);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelUserScrobbles.setText(numberFormat.format(track.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(track, Reference.getUserName())));
labelTotalListeners.setText(numberFormat.format(track.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(track.getPlayCount()) + " Total Scrobbles");
double ratio = track.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = track.getWiki();
if (wiki != null) {
textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
}
}
}

View File

@ -0,0 +1,141 @@
package sarsoo.fmframework.fx.controller.borderpane;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.controller.info.AlbumPaneController;
import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.net.Network;
public class AlbumBorderPaneController extends FMObjBorderPaneController {
AlbumPaneController infoPaneController;
Album album;
@FXML
public void initialize() {
borderPane.setTop(null);
}
public void populate(Album album) {
this.album = album;
try {
loadInfoPane();
loadScrobblePane();
} catch (IOException e) {
e.printStackTrace();
}
setInfoView();
Button openRym = new Button("view rym");
Button viewArtist = new Button("view artist");
openRym.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
Network.openURL(album.getRymURL());
}
});
if (album.getArtist() != null) {
viewArtist.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
FmFramework.getController().addTab(new ArtistTab(album.getArtist()));
}
});
} else {
viewArtist.setDisable(true);
}
toolBar.getItems().add(openRym);
toolBar.getItems().add(viewArtist);
// if(album.getUrl() == null) {
buttonViewOnline.setDisable(true);
// }
}
@Override
public void loadInfoPane() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../../ui/AlbumPane.fxml"));
this.infoAnchorPane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(infoAnchorPane, 0.0);
AnchorPane.setLeftAnchor(infoAnchorPane, 0.0);
AnchorPane.setRightAnchor(infoAnchorPane, 0.0);
AnchorPane.setBottomAnchor(infoAnchorPane, 0.0);
infoPaneController = (AlbumPaneController) loader.getController();
infoPaneController.refresh(album);
}
@Override
@FXML
protected void handleViewOnline(ActionEvent event) {
System.out.println(album.getUrl());
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(album.getUrl()));
} catch (Exception e) {
Logger.getLog().logError(new ErrorEntry("Can't Open"));
}
}
// Network.openURL(album.getUrl());
}
@Override
@FXML
protected void handleRefresh(ActionEvent event) {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
album = FmFramework.getAlbumPool().getNew(album);
Platform.runLater(new Runnable() {
@Override
public void run() {
infoPaneController.refresh(album);
}
});
return null;
}
};
}
};
service.start();
}
}

View File

@ -0,0 +1,132 @@
package sarsoo.fmframework.fx.controller.borderpane;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.controller.info.ArtistPaneController;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Scrobble;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.util.FMObjList;
public class ArtistBorderPaneController extends FMObjBorderPaneController{
ArtistPaneController infoPaneController;
Artist artist;
@FXML
public void initialize() {
borderPane.setTop(null);
}
public void populate(Artist artist) {
this.artist = artist;
try {
loadInfoPane();
loadScrobblePane();
} catch (IOException e) {
e.printStackTrace();
}
setInfoView();
// if(artist.getUrl() == null) {
buttonViewOnline.setDisable(true);
// }
}
@Override
public void loadInfoPane() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../../ui/ArtistPane.fxml"));
this.infoAnchorPane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(infoAnchorPane, 0.0);
AnchorPane.setLeftAnchor(infoAnchorPane, 0.0);
AnchorPane.setRightAnchor(infoAnchorPane, 0.0);
AnchorPane.setBottomAnchor(infoAnchorPane, 0.0);
infoPaneController = (ArtistPaneController) loader.getController();
infoPaneController.refresh(artist);
}
@Override
@FXML
protected void handleViewOnline(ActionEvent event) {
System.out.println(artist.getUrl());
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(artist.getUrl()));
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
}
// Network.openURL(artist.getUrl());
}
@Override
@FXML
protected void handleRefresh(ActionEvent event) {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
artist = FmFramework.getArtistPool().getNew(artist);
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
FMObjList topTracks = net.getArtistTopTracks(artist, 10);
ArrayList<Scrobble> scrobbles = new ArrayList<>();
topTracks.stream().forEach(t -> {
try {
scrobbles.addAll(net.getTrackScrobbles((Track) t));
} catch (ApiCallException e) {}
});
Platform.runLater(new Runnable() {
@Override
public void run() {
infoPaneController.refresh(artist);
scrobblePaneController.populate(scrobbles);
}
});
return null;
}
};
}
};
service.start();
}
}

View File

@ -0,0 +1,88 @@
package sarsoo.fmframework.fx.controller.borderpane;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import sarsoo.fmframework.fx.controller.ScrobblesViewPaneController;
import sarsoo.fmframework.fx.tab.FMObjTab;
import sarsoo.fmframework.net.Network;
public abstract class FMObjBorderPaneController {
@FXML
protected ToolBar toolBar;
@FXML
protected ProgressBar progressBar;
@FXML
protected AnchorPane progressBarAnchorPane;
@FXML
protected Button buttonViewScrobbles;
@FXML
protected Button buttonViewInfo;
@FXML
protected Button buttonViewOnline;
@FXML
protected BorderPane borderPane;
protected AnchorPane scrobbleAnchorPane;
protected ScrobblesViewPaneController scrobblePaneController;
protected AnchorPane infoAnchorPane;
@FXML
protected abstract void handleRefresh(ActionEvent event);
@FXML
protected void handleViewScrobbles(ActionEvent event) {
setScrobblesView();
}
@FXML
protected void handleViewInfo(ActionEvent event) {
setInfoView();
}
@FXML
protected abstract void handleViewOnline(ActionEvent event);
public void setScrobblesView() {
buttonViewInfo.setDisable(false);
buttonViewScrobbles.setDisable(true);
borderPane.setCenter(scrobbleAnchorPane);
}
public void setInfoView() {
buttonViewInfo.setDisable(true);
buttonViewScrobbles.setDisable(false);
borderPane.setCenter(infoAnchorPane);
}
public abstract void loadInfoPane()throws IOException;
public void loadScrobblePane() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../../ui/FMObjScrobblePane.fxml"));
this.scrobbleAnchorPane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(scrobbleAnchorPane, 0.0);
AnchorPane.setLeftAnchor(scrobbleAnchorPane, 0.0);
AnchorPane.setRightAnchor(scrobbleAnchorPane, 0.0);
AnchorPane.setBottomAnchor(scrobbleAnchorPane, 0.0);
this.scrobblePaneController = (ScrobblesViewPaneController) loader.getController();
}
}

View File

@ -0,0 +1,149 @@
package sarsoo.fmframework.fx.controller.borderpane;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.controller.info.TrackPaneController;
import sarsoo.fmframework.fx.tab.AlbumTab;
import sarsoo.fmframework.fx.tab.ArtistTab;
import sarsoo.fmframework.music.Track;
public class TrackBorderPaneController extends FMObjBorderPaneController {
TrackPaneController infoPaneController;
Track track;
@FXML
public void initialize() {
borderPane.setTop(null);
}
public void populate(Track track) {
this.track = track;
try {
loadInfoPane();
loadScrobblePane();
} catch (IOException e) {
e.printStackTrace();
}
setInfoView();
Button viewAlbum = new Button("view album");
Button viewArtist = new Button("view artist");
if (track.getAlbum() != null) {
viewAlbum.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
FmFramework.getController().addTab(new AlbumTab(track.getAlbum()));
}
});
}else {
viewAlbum.setDisable(true);
}
if (track.getArtist() != null) {
viewArtist.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
FmFramework.getController().addTab(new ArtistTab(track.getArtist()));
}
});
}else {
viewArtist.setDisable(true);
}
toolBar.getItems().add(viewAlbum);
toolBar.getItems().add(viewArtist);
// if(track.getUrl() == null) {
buttonViewOnline.setDisable(true);
// }
}
@Override
public void loadInfoPane() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../../ui/TrackPane.fxml"));
this.infoAnchorPane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(infoAnchorPane, 0.0);
AnchorPane.setLeftAnchor(infoAnchorPane, 0.0);
AnchorPane.setRightAnchor(infoAnchorPane, 0.0);
AnchorPane.setBottomAnchor(infoAnchorPane, 0.0);
infoPaneController = (TrackPaneController) loader.getController();
infoPaneController.refresh(track);
}
@Override
@FXML
protected void handleViewOnline(ActionEvent event) {
System.out.println(track.getUrl());
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(new URI(track.getUrl()));
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
}
// Network.openURL(track.getUrl());
}
@Override
@FXML
protected void handleRefresh(ActionEvent event) {
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
track = FmFramework.getTrackPool().getNew(track);
track.setScrobbles(net.getTrackScrobbles(track));
Platform.runLater(new Runnable() {
@Override
public void run() {
infoPaneController.refresh(track);
scrobblePaneController.populate(track);
}
});
return null;
}
};
}
};
service.start();
}
}

View File

@ -0,0 +1,87 @@
package sarsoo.fmframework.fx.controller.info;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.fxml.FXML;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.util.Maths;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
public class AlbumPaneController {
@FXML
private Label labelAlbumName;
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
private AnchorPane infoAnchorPane;
@FXML
private AnchorPane anchorPane;
@FXML
private GridPane gridPane;
@FXML
public void initialize() {
labelAlbumName.setText("Hello World");
}
public void refresh(Album album) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.UK);
labelAlbumName.setText(album.getName());
labelArtistName.setText(album.getArtist().getName());
labelUserScrobbles.setText(numberFormat.format(album.getUserPlayCount()) + String.format(" Scrobbles (%.2f%%)",
Maths.getPercentListening(album, FmFramework.getSessionConfig().getValue("username"))));
labelTotalListeners.setText(numberFormat.format(album.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(album.getPlayCount()) + " Total Scrobbles");
double ratio = album.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = album.getWiki();
if (wiki != null) {
textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
} else {
anchorPane.getChildren().set(0, gridPane);
}
}
}

View File

@ -0,0 +1,80 @@
package sarsoo.fmframework.fx.controller.info;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.fxml.FXML;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.util.Maths;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
public class ArtistPaneController {
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
private AnchorPane infoAnchorPane;
@FXML
private AnchorPane anchorPane;
@FXML
private GridPane gridPane;
@FXML
public void initialize() {
}
public void refresh(Artist artist) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelArtistName.setText(artist.getName());
labelUserScrobbles.setText(numberFormat.format(artist.getUserPlayCount()) + String.format(" Scrobbles (%.2f%%)",
Maths.getPercentListening(artist, FmFramework.getSessionConfig().getValue("username"))));
labelTotalListeners.setText(numberFormat.format(artist.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(artist.getPlayCount()) + " Total Scrobbles");
double ratio = artist.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = artist.getWiki();
if (wiki != null) {
textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
} else {
anchorPane.getChildren().set(0, gridPane);
}
}
}

View File

@ -0,0 +1,151 @@
package sarsoo.fmframework.fx.controller.info;
import java.text.NumberFormat;
import java.util.Locale;
import javafx.fxml.FXML;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.music.Wiki;
import sarsoo.fmframework.util.Maths;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
public class TrackPaneController {
@FXML
private Label labelTrackName;
@FXML
private Label labelAlbumName;
@FXML
private Label labelArtistName;
@FXML
private Label labelUserScrobbles;
@FXML
private Label labelRatio;
@FXML
private Label labelTotalListeners;
@FXML
private Label labelTotalScrobbles;
@FXML
private TextArea textAreaWiki;
@FXML
private Button buttonViewAlbum;
@FXML
private AnchorPane infoAnchorPane;
@FXML
private AnchorPane anchorPane;
@FXML
private GridPane gridPane;
@FXML
public void initialize() {
}
Track track;
public void refresh(Track track) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
labelTrackName.setText(track.getName());
if (track.getAlbum() == null)
labelAlbumName.setVisible(false);
else
labelAlbumName.setText(track.getAlbum().getName());
labelArtistName.setText(track.getArtist().getName());
labelUserScrobbles.setText(numberFormat.format(track.getUserPlayCount()) + String.format(" Scrobbles (%.2f%%)",
Maths.getPercentListening(track, FmFramework.getSessionConfig().getValue("username"))));
labelTotalListeners.setText(numberFormat.format(track.getListeners()) + " Listeners");
labelTotalScrobbles.setText(numberFormat.format(track.getPlayCount()) + " Total Scrobbles");
double ratio = track.getTimeListenRatio();
if (ratio > 1) {
labelRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
labelRatio.setText("listen every day");
} else {
labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
Wiki wiki = track.getWiki();
if (wiki != null) {
textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
} else {
anchorPane.getChildren().set(0, gridPane);
}
if (track.getAlbum() == null) {
// buttonViewAlbum.setVisible(false);
}
}
// @FXML
// protected void handleRefresh(ActionEvent event) {
// refresh();
// }
//
// @FXML
// protected void viewOnline(ActionEvent event) {
// Network.openURL(track.getUrl());
// }
//
// @FXML
// protected void viewArtist(ActionEvent event) throws IOException {
// FmFramework.getController().addTab(new ArtistTab(track.getArtist()));
// }
//
// @FXML
// protected void viewAlbum(ActionEvent event) throws IOException {
// FmFramework.getController().addTab(new AlbumTab(track.getAlbum()));
// }
// public void refresh() {
// track = new FmUserNetwork(Key.getKey(), Reference.getUserName()).refresh(track);
//
// NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
//
// labelUserScrobbles.setText(numberFormat.format(track.getUserPlayCount())
// + String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(track, Reference.getUserName())));
//
// labelTotalListeners.setText(numberFormat.format(track.getListeners()) + " Listeners");
// labelTotalScrobbles.setText(numberFormat.format(track.getPlayCount()) + " Total Scrobbles");
//
// double ratio = track.getTimeListenRatio();
//
// if (ratio > 1) {
// labelRatio.setText(String.format("listen every %.2f days", ratio));
// } else if (ratio == 1) {
// labelRatio.setText("listen every day");
// } else {
// labelRatio.setText(String.format("%.2f times a day", 1 / ratio));
// }
//
// Wiki wiki = track.getWiki();
//
// if (wiki != null) {
//
// textAreaWiki.setText(wiki.getContent() + "\n\n" + wiki.getDate());
// }
// }
}

View File

@ -0,0 +1,42 @@
package sarsoo.fmframework.fx.service;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.image.Image;
import sarsoo.fmframework.fx.TiledImage;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
public class GetFXImageService extends Service<TiledImage> {
private String url;
private int index;
public GetFXImageService(String url, int index) {
super();
this.url = url;
this.index = index;
}
@Override
protected Task<TiledImage> createTask() {
return new Task<TiledImage>() {
@Override
protected TiledImage call() throws Exception {
return new TiledImage(url, index);
}
};
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get image " + url));
}
}

View File

@ -0,0 +1,48 @@
package sarsoo.fmframework.fx.service;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.music.Track;
public class GetLastTrackService extends Service<Track> {
@Override
protected Task<Track> createTask() {
return new Task<Track>() {
@Override
protected Track call() throws Exception {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
Track lastTrack = net.getLastTrack();
FmFramework.getTrackPool().add(lastTrack);
FmFramework.getArtistPool().add(lastTrack.getArtist());
if(lastTrack.getAlbum() != null) {
FmFramework.getAlbumPool().add(lastTrack.getAlbum());
}
return lastTrack;
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get last track"));
}
};
}
}

View File

@ -0,0 +1,38 @@
package sarsoo.fmframework.fx.service;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
public class GetScrobbleCountService extends Service<ScrobbleCount> {
@Override
protected Task<ScrobbleCount> createTask() {
return new Task<ScrobbleCount>() {
@Override
protected ScrobbleCount call() throws Exception {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
return new ScrobbleCount(net.getScrobblesToday(), net.getUserScrobbleCount());
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get scrobble count"));
}
};
}
}

View File

@ -0,0 +1,90 @@
package sarsoo.fmframework.fx.service;
import java.util.ArrayList;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.MenuItem;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.fx.tab.FMObjListTab;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.music.Tag;
public class GetTagMenuItemsService extends Service<ArrayList<MenuItem>> {
private ArrayList<Tag> tags;
public GetTagMenuItemsService(ArrayList<Tag> tags) {
super();
this.tags = tags;
}
@Override
protected Task<ArrayList<MenuItem>> createTask() {
return new Task<ArrayList<MenuItem>>() {
@Override
protected ArrayList<MenuItem> call() throws Exception {
ArrayList<MenuItem> items = new ArrayList<MenuItem>();
int counter;
for (counter = 0; counter < tags.size(); counter++) {
String name = tags.get(counter).getName().toLowerCase();
// System.out.println(name);
MenuItem item = new MenuItem(name);
item.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
// TAG ITEM HANDLER SERVICE
Service<Void> service = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
FMObjListTab tab = new FMObjListTab(FmFramework.getTagPool().get(name));
Platform.runLater(new Runnable() {
@Override
public void run() {
FmFramework.getController().addTab(tab);
}
});
return null;
}
};
}
};
service.start();
}
});
items.add(item);
}
return items;
}
};
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get tag menu items"));
}
}

View File

@ -0,0 +1,41 @@
package sarsoo.fmframework.fx.service;
import java.util.ArrayList;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.music.Tag;
public class GetTagsService extends Service<ArrayList<Tag>> {
@Override
protected Task<ArrayList<Tag>> createTask() {
return new Task<ArrayList<Tag>>() {
@Override
protected ArrayList<Tag> call() throws Exception {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
return net.getTags();
}
};
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get tags"));
}
}

View File

@ -0,0 +1,45 @@
package sarsoo.fmframework.fx.service;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fm.TimePeriod;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.util.FMObjList;
public class GetTopAlbumsService extends Service<FMObjList> {
private int limit;
private TimePeriod period;
private FmUserNetwork net;
public GetTopAlbumsService(TimePeriod period, int limit, FmUserNetwork net) {
super();
this.limit = limit;
this.period = period;
this.net = net;
}
@Override
protected Task<FMObjList> createTask() {
return new Task<FMObjList>() {
@Override
protected FMObjList call() throws Exception {
return net.getTopAlbums(period, limit);
}
};
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to get top albums"));
}
}

View File

@ -0,0 +1,52 @@
package sarsoo.fmframework.fx.service;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.config.ConfigPersister;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.log.Logger;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class SaveConfigService extends Service<Integer> {
protected Config config;
protected String path;
public SaveConfigService(String path, Config config) {
this.path = path;
this.config = config;
}
@Override
protected Task<Integer> createTask() {
return new Task<Integer>() {
@Override
protected Integer call() throws Exception {
ConfigPersister persister = new ConfigPersister();
while(!this.isCancelled()) {
persister.saveConfig(path, config);
Logger.getLog().log(new LogEntry("save config").addArg("config saved"));
Thread.sleep(60000);
}
return 0;
}
@Override
protected void failed() {
super.failed();
Logger.getLog().logError(new ErrorEntry("failed to save config"));
}
};
}
}

View File

@ -0,0 +1,20 @@
package sarsoo.fmframework.fx.service;
public class ScrobbleCount {
private int dailyCount;
private int totalCount;
public ScrobbleCount(int dailyCount, int totalCount) {
this.dailyCount = dailyCount;
this.totalCount = totalCount;
}
public int getDailyCount() {
return dailyCount;
}
public int getTotalCount() {
return totalCount;
}
}

View File

@ -4,7 +4,9 @@ import java.io.IOException;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import sarsoo.fmframework.fx.controller.AlbumPaneController; import sarsoo.fmframework.fx.controller.borderpane.AlbumBorderPaneController;
import sarsoo.fmframework.fx.controller.borderpane.ArtistBorderPaneController;
import sarsoo.fmframework.fx.controller.info.AlbumPaneController;
import sarsoo.fmframework.music.Album; import sarsoo.fmframework.music.Album;
@ -12,27 +14,33 @@ import javafx.fxml.FXMLLoader;
public class AlbumTab extends Tab { public class AlbumTab extends Tab {
public AlbumTab(Album album) throws IOException { public AlbumTab(Album album) {
setText(album.getName()); setText(album.getName().toLowerCase());
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/AlbumPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjBorderPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); AlbumBorderPaneController controller = new AlbumBorderPaneController();
AnchorPane.setTopAnchor(pane, 0.0); loader.setController(controller);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
AlbumPaneController control = (AlbumPaneController) loader.getController();
control.populate(album);
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
controller.populate(album);
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View File

@ -4,33 +4,39 @@ import java.io.IOException;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import sarsoo.fmframework.fx.controller.ArtistPaneController; import sarsoo.fmframework.fx.controller.borderpane.ArtistBorderPaneController;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
public class ArtistTab extends Tab { public class ArtistTab extends Tab{
public ArtistTab(Artist artist) throws IOException { public ArtistTab(Artist artist) {
setText(artist.getName());
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/ArtistPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
ArtistPaneController control = (ArtistPaneController) loader.getController();
control.populate(artist);
setText(artist.getName().toLowerCase());
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjBorderPane.fxml"));
ArtistBorderPaneController controller = new ArtistBorderPaneController();
loader.setController(controller);
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
controller.populate(artist);
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View File

@ -9,30 +9,37 @@ import javafx.fxml.FXMLLoader;
public class FMObjListEditTab extends Tab { public class FMObjListEditTab extends Tab {
public FMObjListEditTab() throws IOException { public FMObjListEditTab() {
setText("List"); setText("List");
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListEditPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListEditPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
AnchorPane.setTopAnchor(pane, 0.0); // BorderPane
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
// BorderPane setText("list");
setText("list"); setContent(pane);
setContent(pane);
FMObjListPaneEditController control = (FMObjListPaneEditController) loader.getController();
FMObjListPaneEditController control = (FMObjListPaneEditController) loader.getController();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
public FMObjListEditTab(FMObjList list) throws IOException { public FMObjListEditTab(FMObjList list) {
if (list.getGroupName() != null) { if (list.getGroupName() != null) {
setText(list.getGroupName()); setText(list.getGroupName());
@ -42,20 +49,27 @@ public class FMObjListEditTab extends Tab {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListEditPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListEditPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); AnchorPane pane;
AnchorPane.setTopAnchor(pane, 0.0); try {
AnchorPane.setLeftAnchor(pane, 0.0); pane = (AnchorPane) loader.load();
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0); AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
// BorderPane // BorderPane
setContent(pane); setContent(pane);
FMObjListPaneEditController control = (FMObjListPaneEditController) loader.getController(); FMObjListPaneEditController control = (FMObjListPaneEditController) loader.getController();
control.setList(list); control.setList(list);
control.refresh(); control.refresh();
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View File

@ -9,51 +9,31 @@ import javafx.fxml.FXMLLoader;
public class FMObjListTab extends Tab { public class FMObjListTab extends Tab {
public FMObjListTab(FMObjList list) throws IOException { public FMObjListTab(FMObjList list) {
setText(list.getGroupName()); setText(list.getGroupName());
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjListPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
AnchorPane.setTopAnchor(pane, 0.0); setContent(pane);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0); setText(list.getGroupName());
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane); FMObjListPaneController control = (FMObjListPaneController) loader.getController();
setText(list.getGroupName());
FMObjListPaneController control = (FMObjListPaneController) loader.getController();
control.populate(list);
control.populate(list);
} catch (IOException e) {
e.printStackTrace();
}
} }
// public FMObjListTab() throws IOException {
//
// setText("List");
//
// FXMLLoader loader = new FXMLLoader(getClass().getResource("ui/FMObjListPaneEdit.fxml"));
//
// AnchorPane pane = (AnchorPane) loader.load();
//
// AnchorPane.setTopAnchor(pane, 0.0);
// AnchorPane.setLeftAnchor(pane, 0.0);
// AnchorPane.setRightAnchor(pane, 0.0);
// AnchorPane.setBottomAnchor(pane, 0.0);
//
//// BorderPane
//
// setContent(pane);
//
// FMObjListPaneEditController control = (FMObjListPaneEditController) loader.getController();
//
//
// }
} }

View File

@ -0,0 +1,46 @@
package sarsoo.fmframework.fx.tab;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.Tab;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import sarsoo.fmframework.fx.controller.ScrobblesViewPaneController;
import sarsoo.fmframework.fx.controller.borderpane.FMObjBorderPaneController;
public abstract class FMObjTab extends Tab {
protected AnchorPane infoAnchorPane;
protected FMObjBorderPaneController controller;
protected FMObjTab() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjBorderPane.fxml"));
AnchorPane anchor;
try {
anchor = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(anchor, 0.0);
AnchorPane.setLeftAnchor(anchor, 0.0);
AnchorPane.setRightAnchor(anchor, 0.0);
AnchorPane.setBottomAnchor(anchor, 0.0);
this.controller = (FMObjBorderPaneController) loader.getController();
setContent(anchor);
} catch (IOException e) {
e.printStackTrace();
}
}
public AnchorPane getInfoAnchorPane() {
return infoAnchorPane;
}
public abstract AnchorPane loadInfoAnchorPane() throws IOException;
}

View File

@ -0,0 +1,39 @@
package sarsoo.fmframework.fx.tab;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Tab;
import javafx.scene.layout.AnchorPane;
import sarsoo.fmframework.fx.controller.GenrePieChartPaneController;
public class GenrePieChartTab extends Tab{
public GenrePieChartTab() {
setText("genre pie");
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/GenrePieChartPane.fxml"));
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
GenrePieChartPaneController control = (GenrePieChartPaneController) loader.getController();
//control.populate();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -9,26 +9,30 @@ import javafx.fxml.FXMLLoader;
public class ScrobbleChartTab extends Tab { public class ScrobbleChartTab extends Tab {
public ScrobbleChartTab() throws IOException { public ScrobbleChartTab() {
setText("scrobbles"); setText("scrobbles");
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/ScrobbleChartPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/ScrobbleChartPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); AnchorPane pane;
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
ScrobbleChartPaneController control = (ScrobbleChartPaneController) loader.getController();
//control.populate();
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
ScrobbleChartPaneController control = (ScrobbleChartPaneController) loader.getController();
//control.populate();
} catch (IOException e) {
e.printStackTrace();
}
} }

View File

@ -0,0 +1,37 @@
package sarsoo.fmframework.fx.tab;
import java.io.IOException;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import sarsoo.fmframework.fx.controller.ScrobblePaneController;
import javafx.fxml.FXMLLoader;
public class ScrobbleTab extends Tab {
public ScrobbleTab() {
setText("scrobble");
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/ScrobblePane.fxml"));
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
ScrobblePaneController control = (ScrobblePaneController) loader.getController();
//control.populate();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,37 @@
package sarsoo.fmframework.fx.tab;
import java.io.IOException;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import sarsoo.fmframework.fx.controller.TopAlbumController;
import javafx.fxml.FXMLLoader;
public class TopAlbumTab extends Tab {
public TopAlbumTab() {
setText("top albums");
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/TopAlbumPane.fxml"));
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
TopAlbumController control = (TopAlbumController) loader.getController();
//control.populate();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -4,33 +4,41 @@ import java.io.IOException;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import sarsoo.fmframework.fx.controller.TrackPaneController; import sarsoo.fmframework.fx.controller.borderpane.ArtistBorderPaneController;
import sarsoo.fmframework.fx.controller.borderpane.TrackBorderPaneController;
import sarsoo.fmframework.fx.controller.info.TrackPaneController;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
public class TrackTab extends Tab { public class TrackTab extends Tab {
public TrackTab(Track track) throws IOException { public TrackTab(Track track) {
setText(track.getName()); setText(track.getName().toLowerCase());
FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/TrackPane.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("../ui/FMObjBorderPane.fxml"));
AnchorPane pane = (AnchorPane) loader.load(); TrackBorderPaneController controller = new TrackBorderPaneController();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
TrackPaneController control = (TrackPaneController) loader.getController();
control.populate(track);
loader.setController(controller);
AnchorPane pane;
try {
pane = (AnchorPane) loader.load();
AnchorPane.setTopAnchor(pane, 0.0);
AnchorPane.setLeftAnchor(pane, 0.0);
AnchorPane.setRightAnchor(pane, 0.0);
AnchorPane.setBottomAnchor(pane, 0.0);
setContent(pane);
controller.populate(track);
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View File

@ -0,0 +1,28 @@
package sarsoo.fmframework.fx.tab;
import java.io.IOException;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class WebViewTab extends Tab {
public WebViewTab(String path) throws IOException {
setText("web view");
StackPane pane = new StackPane();
WebView web = new WebView();
pane.getChildren().add(web);
WebEngine webEngine = web.getEngine();
webEngine.load(path);
setContent(pane);
}
}

View File

@ -1,188 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
public class AlbumView extends JFrame {
JPanel buttons = new JPanel();
JPanel buttons2 = new JPanel();
JPanel trackListPanel = new JPanel();
JLabel name = new JLabel();
JLabel artist = new JLabel();
JLabel listeners = new JLabel();
JLabel playCount = new JLabel();
JLabel userPlayCount = new JLabel();
JLabel timePlayRatio = new JLabel();
JButton open = new JButton("View Online");
JButton viewArtist = new JButton("View Artist");
JButton viewWiki = new JButton("View Wiki");
JButton musicBrainz = new JButton("Open MusicBrainz");
JButton rym = new JButton("Open RYM");
public AlbumView(Album album) {
super(album.getName());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new GridLayout(7, 1));
setSize(300, 300);
setResizable(false);
buttons.setLayout(new FlowLayout());
buttons2.setLayout(new FlowLayout());
// System.out.println(album.getName());
// if (album.getTrackList() != null)
// buttons2.setLayout(new GridLayout(album.getTrackList().size(), 1));
buttons.add(open);
// buttons2.add(viewArtist);
if (album.getWiki() != null)
buttons.add(viewWiki);
if (album.getMbid() != null)
buttons.add(musicBrainz);
buttons.add(rym);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
Font title = new Font("Arial", Font.BOLD, 24);
Font sub = new Font("Arial", Font.PLAIN, 20);
name.setText(album.getName());
name.setHorizontalAlignment(SwingConstants.CENTER);
name.setFont(title);
artist.setText(album.getArtist().getName());
artist.setHorizontalAlignment(SwingConstants.CENTER);
artist.setFont(sub);
listeners.setText(numberFormat.format(album.getListeners()) + " Listeners");
listeners.setHorizontalAlignment(SwingConstants.CENTER);
playCount.setText(numberFormat.format(album.getPlayCount()) + " Total Scrobbles");
playCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setText(numberFormat.format(album.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(album, Reference.getUserName())));
userPlayCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setFont(sub);
double ratio = album.getTimeListenRatio();
// int ratioRound = (int) Math.round(ratio);
// int oneOverRatioRound = (int) Math.round(1/ratio);
if (ratio > 1) {
timePlayRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
timePlayRatio.setText("listen every day");
} else {
timePlayRatio.setText(String.format("%.2f times a day", 1/ratio));
}
timePlayRatio.setHorizontalAlignment(SwingConstants.CENTER);
timePlayRatio.setFont(sub);
artist.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
album.getArtist().view();
}
});
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(album.getUrl());
}
});
viewArtist.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
album.getArtist().view();
}
});
viewWiki.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
album.getWiki().view(album.getName());
}
});
musicBrainz.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(album.getMusicBrainzURL());
;
}
});
rym.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(album.getRymURL());
;
}
});
// if (album.getTrackList() != null) {
// int counter;
// ArrayList<Track> trackList = album.getTrackList();
// for (counter = 0; counter < trackList.size(); counter++) {
// Track track = trackList.get(counter);
// JLabel name = new JLabel(track.getName());
//
// int playCountString = track.getUserPlayCount();
//
// JLabel userPlays;
// if (playCountString == 0)
// userPlays = new JLabel("0");
// else
// userPlays = new JLabel(Integer.toString(track.getUserPlayCount()));
//
// JLabel plays = new JLabel(numberFormat.format(track.getPlayCount()));
// JButton openExternal = new JButton("Open Online");
// openExternal.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// Network.openURL(track.getUrl());
// }
// });
// JButton openInternal = new JButton("Open " +
// track.getClass().getSimpleName());
// openInternal.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// track.view();
// }
// });
// JPanel panel = new JPanel();
// panel.setLayout(new GridLayout(1, 5));
// panel.add(name);
// panel.add(userPlays);
// panel.add(plays);
// panel.add(openInternal);
// panel.add(openExternal);
//
// trackListPanel.add(panel);
// }
// }
add(name);
add(artist);
add(userPlayCount);
add(timePlayRatio);
add(listeners);
add(playCount);
// add(trackListPanel);
add(buttons);
// add(buttons2);
pack();
}
}

View File

@ -1,21 +0,0 @@
package sarsoo.fmframework.jframe;
import sarsoo.fmframework.util.Reference;
public class Driver {
public static void main(String[] args) {
// String username = JOptionPane.showInputDialog(null, "Enter User-Name");
// System.out.println(username);
// if (username != null) {
Reference.setUserName("sarsoo");
// Reference.setUserName(username);
// System.out.println(Getter.getScrobbles(Reference.getUserName()));
MainMenu main = new MainMenu();
main.setVisible(true);
// }
}
}

View File

@ -1,188 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;
import java.util.Collections;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
public class FMObjListView extends JFrame {
public FMObjListView(FMObjList objects, String title) {
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// setLayout(new GridLayout(objects.size() + 2, 0));
// setResizable(false);
// createMenu();
int limit = 20;
if(objects.size() > limit) {
setSize(600, 800);
}
JPanel container = new JPanel();
container.setLayout(new GridLayout(objects.size() + 2, 0));
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
Font font = new Font("Arial", Font.PLAIN, 20);
Font header = new Font("Arial", Font.BOLD, 16);
JPanel headerLabels = new JPanel();
// headerLabels.setFont(header);
headerLabels.setLayout(new GridLayout(1, 4));
JLabel headerName = new JLabel("name");
headerName.setHorizontalAlignment(SwingConstants.CENTER);
headerName.setFont(header);
JLabel headerUser = new JLabel("user");
headerUser.setHorizontalAlignment(SwingConstants.CENTER);
headerUser.setFont(header);
JLabel headerTotal = new JLabel("total");
headerTotal.setHorizontalAlignment(SwingConstants.CENTER);
headerTotal.setFont(header);
headerLabels.add(headerName);
headerLabels.add(headerUser);
headerLabels.add(headerTotal);
headerLabels.add(new JLabel(""));
// headerLabels.add(new JLabel(""));
container.add(headerLabels);
Collections.sort(objects);
Collections.reverse(objects);
int counter;
for (counter = 0; counter < objects.size(); counter++) {
FMObj fmObj = objects.get(counter);
JLabel artistName = new JLabel(fmObj.getName());
artistName.setHorizontalAlignment(SwingConstants.CENTER);
artistName.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
fmObj.view();
}
});
int playCountString = fmObj.getUserPlayCount();
JLabel userPlays;
if (playCountString == 0)
userPlays = new JLabel("0");
else
userPlays = new JLabel(Integer.toString(fmObj.getUserPlayCount()));
userPlays.setHorizontalAlignment(SwingConstants.CENTER);
JLabel plays = new JLabel(numberFormat.format(fmObj.getPlayCount()));
plays.setHorizontalAlignment(SwingConstants.CENTER);
JButton openExternal = new JButton("Open Online");
openExternal.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(fmObj.getUrl());
}
});
// JButton openInternal = new JButton("Open " + fmObj.getClass().getSimpleName());
// openInternal.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// fmObj.view();
// }
// });
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 4));
panel.add(artistName);
panel.add(userPlays);
panel.add(plays);
// panel.add(openInternal);
panel.add(openExternal);
container.add(panel);
}
JPanel info = new JPanel();
info.setLayout(new GridLayout(1, 2));
JLabel totalScrobbles = new JLabel(numberFormat.format(objects.getTotalUserScrobbles()) + " total plays");
totalScrobbles.setHorizontalAlignment(SwingConstants.CENTER);
totalScrobbles.setFont(font);
info.add(totalScrobbles);
double percent = Maths.getPercentListening(objects, Reference.getUserName());
// if (percent > 1) {
JLabel percentLabel = new JLabel();
percentLabel.setHorizontalAlignment(SwingConstants.CENTER);
percentLabel.setText(String.format("%.2f%%", percent));
percentLabel.setFont(font);
info.add(percentLabel);
// }
container.add(info);
JScrollPane scroll = new JScrollPane(container);
add(scroll);
if(objects.size() <= limit) {
pack();
}
}
private void createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu editMenu = new JMenu("Edit");
JMenu addMenu = new JMenu("Add");
// create menu items
JMenuItem addAlbum = new JMenuItem("Album");
addAlbum.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Album album = sarsoo.fmframework.jframe.Getter.getAlbum();
if (album != null) {
}
}
});
JMenuItem addTrack = new JMenuItem("Track");
JMenuItem addArtist = new JMenuItem("Artist");
addMenu.add(addAlbum);
addMenu.add(addTrack);
addMenu.add(addArtist);
editMenu.add(addMenu);
menuBar.add(editMenu);
setJMenuBar(menuBar);
}
}

View File

@ -1,108 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import sarsoo.fmframework.music.FMObj;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
public class FMObjView extends JFrame {
JPanel buttons = new JPanel();
JLabel name = new JLabel();
JLabel listeners = new JLabel();
JLabel playCount = new JLabel();
JLabel userPlayCount = new JLabel();
JLabel timePlayRatio = new JLabel();
JButton viewWiki = new JButton("View Wiki");
JButton open = new JButton("View Online");
JButton musicBrainz = new JButton("Open MusicBrainz");
public FMObjView(FMObj obj) {
super(obj.toString());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new GridLayout(6, 1));
setSize(300, 300);
// setResizable(false);
buttons.setLayout(new FlowLayout());
buttons.add(open);
if (obj.getWiki() != null)
buttons.add(viewWiki);
if (obj.getMbid() != null)
buttons.add(musicBrainz);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
Font title = new Font("Arial", Font.BOLD, 24);
Font sub = new Font("Arial", Font.PLAIN, 20);
name.setText(obj.getName());
name.setHorizontalAlignment(SwingConstants.CENTER);
name.setFont(title);
listeners.setText(numberFormat.format(obj.getListeners()) + " Listeners");
listeners.setHorizontalAlignment(SwingConstants.CENTER);
playCount.setText(numberFormat.format(obj.getPlayCount()) + " Total Scrobbles");
playCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setText(numberFormat.format(obj.getUserPlayCount())
+ String.format(" Scrobbles (%.2f%%)", Maths.getPercentListening(obj, Reference.getUserName())));
userPlayCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setFont(sub);
double ratio = obj.getTimeListenRatio();
// int ratioRound = (int) Math.round(ratio);
// int oneOverRatioRound = (int) Math.round(1/ratio);
if (ratio > 1) {
timePlayRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
timePlayRatio.setText("listen every day");
} else {
timePlayRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
timePlayRatio.setHorizontalAlignment(SwingConstants.CENTER);
timePlayRatio.setFont(sub);
viewWiki.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
obj.getWiki().view(obj.getName());
}
});
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(obj.getUrl());
}
});
musicBrainz.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(obj.getMusicBrainzURL());
;
}
});
add(name);
add(userPlayCount);
add(timePlayRatio);
add(listeners);
add(playCount);
// add(info);
add(buttons);
pack();
}
}

View File

@ -2,51 +2,70 @@ package sarsoo.fmframework.jframe;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import sarsoo.fmframework.cache.StaticCache;
import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.music.Album; import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist; import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Track; import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.util.Reference; import sarsoo.fmframework.music.Album.AlbumBuilder;
import sarsoo.fmframework.music.Artist.ArtistBuilder;
import sarsoo.fmframework.music.Track.TrackBuilder;
public class Getter { public class Getter {
public static Album getAlbum() { public static Album getAlbum() {
Config config = FmFramework.getSessionConfig();
// FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String albumName = JOptionPane.showInputDialog(null, "Enter Album Name"); String albumName = JOptionPane.showInputDialog(null, "Enter Album Name");
if (albumName != null) { if (albumName != null) {
String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name"); String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name");
if (artistName != null) { if (artistName != null) {
return Album.getAlbum(albumName, artistName, Reference.getUserName()); StaticCache<Album, Album> albumCache = FmFramework.getAlbumPool();
StaticCache<Artist, Artist> artistCache = FmFramework.getArtistPool();
Artist artist = artistCache.get(new ArtistBuilder(artistName).build());
Album album = albumCache.get(new AlbumBuilder(albumName, artist).build());
return album;
} }
} }
return null; return null;
} }
public static Artist getArtist() { public static Artist getArtist() {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name"); String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name");
if (artistName != null) { if (artistName != null) {
return Artist.getArtist(artistName, Reference.getUserName()); StaticCache<Artist, Artist> artistCache = FmFramework.getArtistPool();
return artistCache.get(new ArtistBuilder(artistName).build());
} }
return null; return null;
} }
public static Track getTrack() { public static Track getTrack() {
Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
String trackName = JOptionPane.showInputDialog(null, "Enter Track Name"); String trackName = JOptionPane.showInputDialog(null, "Enter Track Name");
if (trackName != null) { if (trackName != null) {
String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name"); String artistName = JOptionPane.showInputDialog(null, "Enter Artist Name");
if (artistName != null) { if (artistName != null) {
return Track.getTrack(artistName, trackName, Reference.getUserName());
StaticCache<Artist, Artist> artistCache = FmFramework.getArtistPool();
StaticCache<Track, Track> trackCache = FmFramework.getTrackPool();
Artist artist = artistCache.get(new ArtistBuilder(artistName).build());
return trackCache.get(new TrackBuilder(trackName, artist).build());
} }
} }
return null; return null;
} }
public static Track getTrack(Album album) {
String trackName = JOptionPane.showInputDialog(null, "Enter Track Name");
if (trackName != null) {
Track track = Track.getTrack(album.getArtist().getName(), trackName, Reference.getUserName());
track.setAlbum(album);
return track;
}
return null;
}
} }

View File

@ -1,91 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import sarsoo.fmframework.music.Album;
import sarsoo.fmframework.music.Artist;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Getter;
import sarsoo.fmframework.util.Reference;
public class MainMenu extends JFrame {
JButton getAlbum = new JButton("Get Album");
JButton getArtist = new JButton("Get Artist");
JButton viewLastTrack = new JButton("View Last Track");
JButton viewList = new JButton("View List");
JButton viewTag = new JButton("View Tags");
JButton today = new JButton();
public MainMenu() {
super("fmframework - " + Reference.getUserName());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(3, 2));
setSize(300, 300);
setResizable(false);
getAlbum.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Album album = sarsoo.fmframework.jframe.Getter.getAlbum();
if (album != null) {
album.view();
} else {
JOptionPane.showMessageDialog(null, "No Album Found", "Album Error", JOptionPane.ERROR_MESSAGE);
}
}
});
getArtist.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Artist artist = sarsoo.fmframework.jframe.Getter.getArtist();
if (artist != null) {
artist.view();
} else {
JOptionPane.showMessageDialog(null, "No Artist Found", "Artist Error", JOptionPane.ERROR_MESSAGE);
}
}
});
viewLastTrack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Track track = Getter.getLastTrack();
if (track != null) {
track.view();
} else {
JOptionPane.showMessageDialog(null, "No Track Found", "Track Error", JOptionPane.ERROR_MESSAGE);
}
}
});
viewList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
RefListsView view = new RefListsView();
view.setVisible(true);
}
});
viewTag.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
TagMenuView view = new TagMenuView();
view.setVisible(true);
}
});
today.setText("Today: " + Integer.toString(Getter.getScrobblesToday(Reference.getUserName())));
today.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(String.format("https://www.last.fm/user/%s/library?date_preset=LAST_30_DAYS", Reference.getUserName()));
today.setText("Today: " + Integer.toString(Getter.getScrobblesToday(Reference.getUserName())));
}
});
add(viewLastTrack);
add(today);
add(viewTag);
add(viewList);
add(getArtist);
add(getAlbum);
}
}

View File

@ -1,105 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import sarsoo.fmframework.util.Reference;
public class RefListsView extends JFrame {
public RefListsView() {
super("fmframework");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new GridLayout(3, 2));
setSize(300, 300);
setResizable(false);
// Reference.initGroupsList();
// ArrayList<FMObjList> groups = Reference.getGroups();
// int counter;
// for (counter = 0; counter < groups.size(); counter++) {
// FMObjList group = groups.get(counter);
// JButton view = new JButton("View " + group.getGroupName());
// view.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// group.view();
// }
// });
// add(view);
// }
// JButton viewTDE = new JButton("TDE");
// viewTDE.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// Reference.getTDE().view();
// }
// });
// add(viewTDE);
JButton viewBPHQ = new JButton("BPHQ");
viewBPHQ.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getBB().view();
}
});
add(viewBPHQ);
JButton viewDre = new JButton("Dre");
viewDre.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getDre().view();
}
});
add(viewDre);
JButton viewWu = new JButton("Wu");
viewWu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getWu().view();
}
});
add(viewWu);
JButton viewHopeless = new JButton("Hopeless");
viewHopeless.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getHopeless().view();
}
});
add(viewHopeless);
JButton viewSaturation = new JButton("Saturation");
viewSaturation.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getSaturation().view();
}
});
add(viewSaturation);
JButton viewEmoTrio = new JButton("Emo Trio");
viewEmoTrio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Reference.getEmoTrio().view();
}
});
// add(viewEmoTrio);
//
// JButton viewRockTag = new JButton("Rock Tag");
// viewRockTag.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// FMObjList list = Getter.getUserTag(Reference.getUserName(), "rock");
// list.view();
// }
// });
// add(viewRockTag);
//
// JButton viewRapTag = new JButton("Rap Tag");
// viewRapTag.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent arg0) {
// FMObjList list = Getter.getUserTag(Reference.getUserName(), "rap");
// list.view();
// }
// });
// add(viewRapTag);
}
}

View File

@ -1,43 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import sarsoo.fmframework.music.Tag;
import sarsoo.fmframework.util.FMObjList;
import sarsoo.fmframework.util.Getter;
import sarsoo.fmframework.util.Reference;
public class TagMenuView extends JFrame {
public TagMenuView() {
super("View Tags");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ArrayList<Tag> tags = Getter.getUserTags(Reference.getUserName());
setLayout(new GridLayout(4, 4));
setSize(700, 700);
setResizable(false);
int counter;
for(counter = 0; counter < tags.size(); counter++) {
Tag tag = tags.get(counter);
JButton view = new JButton(tag.getName());
view.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
FMObjList list = Getter.getUserTag(Reference.getUserName(), tag.getName());
list.view();
}
});
add(view);
}
}
}

View File

@ -1,192 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import sarsoo.fmframework.music.Track;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
public class TrackView extends JFrame {
// JPanel info = new JPanel();
// JPanel nameInfo = new JPanel();
// JPanel scrobbleInfo = new JPanel();
JPanel buttons = new JPanel();
JPanel buttons2 = new JPanel();
JLabel name = new JLabel();
JLabel album = new JLabel();
JLabel artist = new JLabel();
JLabel listeners = new JLabel();
JLabel playCount = new JLabel();
JLabel userPlayCount = new JLabel();
JLabel timePlayRatio = new JLabel();
JButton open = new JButton("View Online");
JButton viewArtist = new JButton("View Artist");
JButton viewAlbum = new JButton("View Album");
JButton viewWiki = new JButton("View Wiki");
JButton musicBrainz = new JButton("Open MusicBrainz");
JButton genius = new JButton("Open Genius");
public TrackView(Track track) {
super(track.getName());
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
if (track.getAlbum() != null) {
setLayout(new GridLayout(8, 1));
} else {
setLayout(new GridLayout(7, 1));
}
// setSize(300, 300);
setResizable(false);
// info.setLayout(new GridLayout(6,1));
// nameInfo.setLayout(new GridLayout(3,1));
// scrobbleInfo.setLayout(new GridLayout(3,1));
buttons.setLayout(new FlowLayout());
buttons2.setLayout(new FlowLayout());
buttons.add(open);
if (track.getMbid() != null)
buttons.add(musicBrainz);
buttons2.add(viewArtist);
if (track.getAlbum() != null)
buttons2.add(viewAlbum);
if (track.getWiki() != null)
buttons2.add(viewWiki);
// if (track.getArtist() != null)
buttons.add(genius);
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
Font title = new Font("Arial", Font.BOLD, 24);
Font sub = new Font("Arial", Font.PLAIN, 20);
Font subSub = new Font("Arial", Font.PLAIN, 16);
name.setText(track.getName());
name.setHorizontalAlignment(SwingConstants.CENTER);
name.setFont(title);
if (track.getAlbum() != null) {
album.setText(track.getAlbum().getName());
album.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
track.getAlbum().view();
}
});
}
album.setHorizontalAlignment(SwingConstants.CENTER);
album.setFont(sub);
artist.setText(track.getArtist().getName());
artist.setHorizontalAlignment(SwingConstants.CENTER);
artist.setFont(sub);
double ratio = track.getTimeListenRatio();
// int ratioRound = (int) Math.round(ratio);
// int oneOverRatioRound = (int) Math.round(1/ratio);
if (ratio > 1) {
timePlayRatio.setText(String.format("listen every %.2f days", ratio));
} else if (ratio == 1) {
timePlayRatio.setText("listen every day");
} else {
timePlayRatio.setText(String.format("%.2f times a day", 1 / ratio));
}
timePlayRatio.setHorizontalAlignment(SwingConstants.CENTER);
timePlayRatio.setFont(subSub);
listeners.setText(numberFormat.format(track.getListeners()) + " Listeners");
listeners.setHorizontalAlignment(SwingConstants.CENTER);
playCount.setText(numberFormat.format(track.getPlayCount()) + " Total Scrobbles");
playCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setText(numberFormat.format(track.getUserPlayCount())
+ String.format(" Scrobbles (%.3f%%)", Maths.getPercentListening(track, Reference.getUserName())));
userPlayCount.setHorizontalAlignment(SwingConstants.CENTER);
userPlayCount.setFont(sub);
open.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(track.getUrl());
}
});
viewWiki.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
track.getWiki().view(track.getName());
}
});
if (track.getUserPlayCount() > 0) {
userPlayCount.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String namePlus = track.getName().replaceAll(" ", "+");
String artistPlus = track.getArtist().getName().replaceAll(" ", "+");
String url = String.format("https://www.last.fm/user/%s/library/music/%s/_/%s",
Reference.getUserName(), artistPlus, namePlus);
Network.openURL(url);
}
});
}
artist.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
track.getArtist().view();
}
});
viewArtist.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
track.getArtist().view();
}
});
musicBrainz.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(track.getMusicBrainzURL());
}
});
viewAlbum.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
track.getAlbum().view();
}
});
genius.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Network.openURL(track.getLyricsURL());
}
});
add(name);
if (track.getAlbum() != null)
add(album);
add(artist);
add(userPlayCount);
add(timePlayRatio);
add(listeners);
add(playCount);
// info.add(nameInfo);
// info.add(scrobbleInfo);
// add(info);
add(buttons);
// add(buttons2);
pack();
}
}

View File

@ -1,29 +0,0 @@
package sarsoo.fmframework.jframe;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import sarsoo.fmframework.music.Wiki;
public class WikiView extends JFrame {
JTextArea contentLabel = new JTextArea();
public WikiView(Wiki wiki, String name) {
super(name);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new GridLayout(1,1));
setSize(500, 700);
contentLabel.setText(wiki.getContent()+ "\n\n" + wiki.getDate());
contentLabel.setLineWrap(true);
// contentLabel.setText("<html>" + wiki.getContent() + "<br><br>" + wiki.getDate() + "</html>");
JScrollPane scroll = new JScrollPane(contentLabel);
add(scroll);
// add(contentLabel);
// pack();
}
}

View File

@ -0,0 +1,118 @@
package sarsoo.fmframework.log;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import sarsoo.fmframework.log.console.Console;
import sarsoo.fmframework.log.console.STDOutConsole;
import sarsoo.fmframework.log.entry.ErrorEntry;
import sarsoo.fmframework.log.entry.InfoEntry;
import sarsoo.fmframework.log.entry.LogEntry;
public class Log {
private ArrayList<Console> consoles = new ArrayList<Console>();
private ArrayList<LogEntry> logList = new ArrayList<LogEntry>();
private ArrayList<InfoEntry> infoList = new ArrayList<InfoEntry>();
private ArrayList<ErrorEntry> errorList = new ArrayList<ErrorEntry>();
private LocalDateTime createdTime = LocalDateTime.now();
public Log() {
consoles.add(new STDOutConsole());
}
public Log(Console... consoles) {
for(Console console: consoles) {
this.consoles.add(console);
}
}
public void clearConsoles() {
consoles.clear();
}
public void log(LogEntry entry) {
logList.add(entry);
writeLog(entry.toString());
}
public void logInfo(InfoEntry entry) {
infoList.add(entry);
writeLog(entry.toString());
}
public void logError(ErrorEntry entry) {
errorList.add(entry);
writeLog(entry.toString());
}
protected void writeLog(String logString) {
if (consoles.size() > 0) {
for (Console i : consoles) {
i.write(logString);
}
}
}
public void dumpLog() {
Logger.getLog().log(new LogEntry("dumpLog"));
try {
FileWriter writer = new FileWriter(String.format("%s_Log.txt", createdTime));
for(LogEntry i: logList) {
writer.write(i.toString());
}
writer.close();
Logger.getLog().log(new InfoEntry("dumpLog").addArg("log written"));
} catch (IOException e) {
Logger.getLog().log(new ErrorEntry("dumpLog").addArg("io exception"));
e.printStackTrace();
}
}
public void dumpInfoLog() {
Logger.getLog().log(new LogEntry("dumpInfoLog"));
try {
FileWriter writer = new FileWriter(String.format("%s_InfoLog.txt", createdTime));
for(LogEntry i: infoList) {
writer.write(i.toString());
}
writer.close();
Logger.getLog().log(new InfoEntry("dumpInfoLog").addArg("log written"));
} catch (IOException e) {
Logger.getLog().log(new ErrorEntry("dumpInfoLog").addArg("io exception"));
e.printStackTrace();
}
}
public void dumpErrorLog() {
Logger.getLog().log(new LogEntry("dumpErrorLog"));
try {
FileWriter writer = new FileWriter(String.format("%s_ErrorLog.txt", createdTime));
for(LogEntry i: errorList) {
writer.write(i.toString());
}
writer.close();
Logger.getLog().log(new InfoEntry("dumpErrorLog").addArg("log written"));
} catch (IOException e) {
Logger.getLog().log(new ErrorEntry("dumpErrorLog").addArg("io exception"));
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,15 @@
package sarsoo.fmframework.log;
public class Logger {
private static Log log = new Log();
public static Log getLog() {
return log;
}
public static void setLog(Log logIn) {
log = logIn;
}
}

View File

@ -1,4 +1,4 @@
package sarsoo.fmframework.util; package sarsoo.fmframework.log.console;
public interface Console { public interface Console {

View File

@ -1,4 +1,4 @@
package sarsoo.fmframework.util; package sarsoo.fmframework.log.console;
public class ConsoleHandler { public class ConsoleHandler {

View File

@ -0,0 +1,10 @@
package sarsoo.fmframework.log.console;
public class STDOutConsole implements Console {
@Override
public void write(String string) {
System.out.println(string);
}
}

View File

@ -0,0 +1,49 @@
package sarsoo.fmframework.log.entry;
import java.util.ArrayList;
public class ErrorEntry extends LogEntry {
protected int errorCode = 0;
public ErrorEntry(String methodIn) {
super(methodIn);
}
public ErrorEntry setErrorCode(int error) {
errorCode = error;
return this;
}
@Override
public ErrorEntry addArg(String arg) {
if (args == null) {
args = new ArrayList<String>();
}
args.add(arg);
return this;
}
public String toString() {
String logString = String.format("%s !!%s", timestamp, method);
if (errorCode != 0) {
logString += String.format(" (%d)", errorCode);
}
if (args != null) {
if (args.size() > 0) {
logString += ":";
for (String i : args) {
logString += " " + i;
}
}
}
return logString;
}
}

View File

@ -0,0 +1,38 @@
package sarsoo.fmframework.log.entry;
import java.util.ArrayList;
public class InfoEntry extends LogEntry {
public InfoEntry(String methodIn) {
super(methodIn);
}
@Override
public InfoEntry addArg(String arg) {
if (args == null) {
args = new ArrayList<String>();
}
args.add(arg);
return this;
}
public String toString() {
String logString = String.format("%s \t>%s", timestamp, method);
if (args != null) {
if (args.size() > 0) {
logString += ":";
for (String i : args) {
logString += " " + i;
}
}
}
return logString;
}
}

View File

@ -0,0 +1,55 @@
package sarsoo.fmframework.log.entry;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class LogEntry {
protected String method;
protected ArrayList<String> args;
protected LocalDateTime timestamp;
public LogEntry(String methodIn) {
method = methodIn;
timestamp = LocalDateTime.now();
}
public String getMethod() {
return method;
}
public ArrayList<String> getArgs() {
return args;
}
public LocalDateTime getTimeStamp() {
return timestamp;
}
public LogEntry addArg(String arg) {
if (args == null) {
args = new ArrayList<String>();
}
args.add(arg);
return this;
}
public String toString() {
String logString = String.format("%s >>%s", timestamp, method);
if (args != null) {
if (args.size() > 0) {
logString += ":";
for (String i : args) {
logString += " " + i;
}
}
}
return logString;
}
}

View File

@ -1,83 +1,67 @@
package sarsoo.fmframework.music; package sarsoo.fmframework.music;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import org.w3c.dom.Document; import javax.imageio.ImageIO;
import sarsoo.fmframework.jframe.AlbumView; import sarsoo.fmframework.cache.Cacheable;
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.net.URLBuilder;
import sarsoo.fmframework.parser.Parser;
import sarsoo.fmframework.util.Reference;
public class Album extends FMObj implements Serializable{ public class Album extends FMObj implements Serializable, Cacheable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
protected Artist artist; protected Artist artist;
protected ArrayList<Tag> tagList; protected ArrayList<Tag> tagList;
protected ArrayList<Track> trackList; protected ArrayList<Track> trackList;
@Deprecated protected String imageUrl;
public Album(String name, String artist) { protected BufferedImage image;
super(name, null, null, 0, 0, 0, null);
this.artist = Artist.getArtist(artist, Reference.getUserName());
}
@Deprecated
public Album(String name, String url, String mbid, Artist artist, int listeners, int playCount, int userPlayCount,
Wiki wiki) {
super(name, url, mbid, listeners, playCount, userPlayCount, wiki);
this.artist = artist;
}
private Album(AlbumBuilder builder) { private Album(AlbumBuilder builder) {
this.name = builder.name; this.name = builder.name;
this.artist = builder.artist; this.artist = builder.artist;
this.url = builder.url; this.url = builder.url;
this.listeners = builder.listeners; this.listeners = builder.listeners;
this.playCount = builder.playCount; this.playCount = builder.playCount;
this.userPlayCount = builder.userPlayCount; this.userPlayCount = builder.userPlayCount;
this.wiki = builder.wiki; this.wiki = builder.wiki;
this.mbid = builder.mbid; this.mbid = builder.mbid;
this.tagList = builder.tagList; this.tagList = builder.tagList;
this.trackList = builder.trackList; this.trackList = builder.trackList;
this.imageUrl = builder.imageUrl;
} }
public String getImageURL() {
return imageUrl;
}
public void loadImage() {
try {
image = ImageIO.read(new URL(imageUrl));
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getImage() {
return image;
}
public Artist getArtist() { public Artist getArtist() {
return artist; return artist;
} }
@Deprecated
public static Album getAlbum(String name, String artist, String username) {
String url = URLBuilder.getAlbumInfoUrl(name, artist, username);
Document response = Network.getResponse(url);
if (response != null) {
Album album = Parser.parseAlbum(response);
return album;
}
return null;
}
// public Track getTrack(int track) {
// return trackList.get(track);
// }
//
// public ArrayList<Track> getTrackList(){
// return trackList;
// }
//
// public void addTrack(Track track) {
// trackList.add(track);
// }
//
public ArrayList<Tag> getTags() { public ArrayList<Tag> getTags() {
return tagList; return tagList;
} }
@ -93,13 +77,6 @@ public class Album extends FMObj implements Serializable{
} }
@Deprecated
@Override
public void view() {
AlbumView view = new AlbumView(this);
view.setVisible(true);
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj.getClass() != this.getClass()) if (obj.getClass() != this.getClass())
@ -118,86 +95,98 @@ public class Album extends FMObj implements Serializable{
} }
@Deprecated public static class AlbumBuilder {
@Override
public void refresh() {
Album album = Album.getAlbum(name, artist.getName(), Reference.getUserName());
this.listeners = album.listeners;
this.userPlayCount = album.userPlayCount;
this.playCount = album.playCount;
this.wiki = album.wiki;
this.mbid = album.mbid;
}
public static class AlbumBuilder{
protected String name; protected String name;
protected Artist artist; protected Artist artist;
protected String url; protected String url;
protected int listeners; protected int listeners;
protected int playCount; protected int playCount;
protected int userPlayCount; protected int userPlayCount;
protected Wiki wiki; protected Wiki wiki;
protected String mbid; protected String mbid;
protected ArrayList<Tag> tagList; protected ArrayList<Tag> tagList;
protected ArrayList<Track> trackList; protected ArrayList<Track> trackList;
protected String imageUrl;
public AlbumBuilder(String name, Artist artist) { public AlbumBuilder(String name, Artist artist) {
this.name = name; this.name = name;
this.artist = artist; this.artist = artist;
} }
public AlbumBuilder setUrl(String url) { public AlbumBuilder setUrl(String url) {
this.url = url; this.url = url;
return this; return this;
} }
public AlbumBuilder setListeners(int listeners) { public AlbumBuilder setListeners(int listeners) {
this.listeners = listeners; this.listeners = listeners;
return this; return this;
} }
public AlbumBuilder setPlayCount(int playCount) { public AlbumBuilder setPlayCount(int playCount) {
this.playCount = playCount; this.playCount = playCount;
return this; return this;
} }
public AlbumBuilder setUserPlayCount(int userPlayCount) { public AlbumBuilder setUserPlayCount(int userPlayCount) {
this.userPlayCount = userPlayCount; this.userPlayCount = userPlayCount;
return this; return this;
} }
public AlbumBuilder setWiki(Wiki wiki) { public AlbumBuilder setWiki(Wiki wiki) {
this.wiki = wiki; this.wiki = wiki;
return this; return this;
} }
public AlbumBuilder setMbid(String Mbid) { public AlbumBuilder setMbid(String Mbid) {
this.mbid = Mbid; this.mbid = Mbid;
return this; return this;
} }
public AlbumBuilder setTagList(ArrayList<Tag> tagList) { public AlbumBuilder setTagList(ArrayList<Tag> tagList) {
this.tagList = tagList; this.tagList = tagList;
return this; return this;
} }
public AlbumBuilder setTrackList(ArrayList<Track> trackList) { public AlbumBuilder setTrackList(ArrayList<Track> trackList) {
this.trackList = trackList; this.trackList = trackList;
return this; return this;
} }
public AlbumBuilder setImageUrl(String url) {
this.imageUrl = url;
return this;
}
public Album build() { public Album build() {
return new Album(this); return new Album(this);
} }
} }
@Override
public ArrayList<Scrobble> getScrobbles() {
if (trackList != null) {
if (trackList.size() > 0) {
ArrayList<Scrobble> scrobbles = new ArrayList<Scrobble>();
for (Track i : trackList) {
scrobbles.addAll(i.getScrobbles());
}
return scrobbles;
}
}
return null;
}
@Override
public boolean matches(Object o) {
return equals(o);
}
} }

View File

@ -3,16 +3,10 @@ package sarsoo.fmframework.music;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import org.w3c.dom.Document; import sarsoo.fmframework.cache.Cacheable;
import sarsoo.fmframework.net.Network; public class Artist extends FMObj implements Serializable, Cacheable {
import sarsoo.fmframework.net.URLBuilder;
//import sarsoo.fmframework.net.TestCall;
import sarsoo.fmframework.parser.Parser;
import sarsoo.fmframework.util.Reference;
public class Artist extends FMObj implements Serializable{
/** /**
* *
*/ */
@ -23,54 +17,23 @@ public class Artist extends FMObj implements Serializable{
protected ArrayList<Artist> similarArtists; protected ArrayList<Artist> similarArtists;
protected ArrayList<Tag> tagList; protected ArrayList<Tag> tagList;
@Deprecated
public Artist(String name) {
super(name, null, null, 0, 0, 0, null);
}
@Deprecated
public Artist(String name, String url, String mbid, int listeners, int playCount, int userPlayCount, Wiki wiki) {
super(name, url, mbid, listeners, playCount, userPlayCount, wiki);
}
private Artist(ArtistBuilder builder) { private Artist(ArtistBuilder builder) {
this.name = builder.name; this.name = builder.name;
this.url = builder.url; this.url = builder.url;
this.listeners = builder.listeners; this.listeners = builder.listeners;
this.playCount = builder.playCount; this.playCount = builder.playCount;
this.userPlayCount = builder.userPlayCount; this.userPlayCount = builder.userPlayCount;
this.wiki = builder.wiki; this.wiki = builder.wiki;
this.mbid = builder.mbid; this.mbid = builder.mbid;
this.albums = builder.albums; this.albums = builder.albums;
this.similarArtists = builder.similarArtists; this.similarArtists = builder.similarArtists;
this.tagList = builder.tagList; this.tagList = builder.tagList;
}
@Deprecated
public static Artist getArtist(String name, String username) {
String url = URLBuilder.getArtistInfoUrl(name, username);
// TestCall.test(url);
Document response = Network.getResponse(url);
if (response != null) {
Artist artist = Parser.parseArtist(response);
return artist;
}
return null;
}
@Deprecated
public static Artist getArtistByMbid(String mbid, String username) {
String url = URLBuilder.getArtistInfoMbidUrl(mbid, username);
Document response = Network.getResponse(url);
Artist artist = Parser.parseArtist(response);
return artist;
} }
public ArrayList<Album> getAlbum() { public ArrayList<Album> getAlbum() {
@ -105,98 +68,103 @@ public class Artist extends FMObj implements Serializable{
return false; return false;
} }
@Override
public boolean matches(Object o) {
return equals(o);
}
public String toString() { public String toString() {
return "Artist: " + name; return "Artist: " + name;
} }
@Deprecated public static class ArtistBuilder {
@Override
public void refresh() {
Artist artist = Artist.getArtist(name, Reference.getUserName());
this.listeners = artist.listeners;
this.userPlayCount = artist.userPlayCount;
this.playCount = artist.playCount;
this.wiki = artist.wiki;
this.mbid = artist.mbid;
}
public static class ArtistBuilder{
protected String name; protected String name;
protected String url; protected String url;
protected int listeners; protected int listeners;
protected int playCount; protected int playCount;
protected int userPlayCount; protected int userPlayCount;
protected Wiki wiki; protected Wiki wiki;
protected String mbid; protected String mbid;
protected ArrayList<Album> albums; protected ArrayList<Album> albums;
protected ArrayList<Artist> similarArtists; protected ArrayList<Artist> similarArtists;
protected ArrayList<Tag> tagList; protected ArrayList<Tag> tagList;
public ArtistBuilder(String name) { public ArtistBuilder(String name) {
this.name = name; this.name = name;
} }
public ArtistBuilder setUrl(String url) { public ArtistBuilder setUrl(String url) {
this.url = url; this.url = url;
return this; return this;
} }
public ArtistBuilder setListeners(int listeners) { public ArtistBuilder setListeners(int listeners) {
this.listeners = listeners; this.listeners = listeners;
return this; return this;
} }
public ArtistBuilder setPlayCount(int playCount) { public ArtistBuilder setPlayCount(int playCount) {
this.playCount = playCount; this.playCount = playCount;
return this; return this;
} }
public ArtistBuilder setUserPlayCount(int userPlayCount) { public ArtistBuilder setUserPlayCount(int userPlayCount) {
this.userPlayCount = userPlayCount; this.userPlayCount = userPlayCount;
return this; return this;
} }
public ArtistBuilder setWiki(Wiki wiki) { public ArtistBuilder setWiki(Wiki wiki) {
this.wiki = wiki; this.wiki = wiki;
return this; return this;
} }
public ArtistBuilder setMbid(String Mbid) { public ArtistBuilder setMbid(String Mbid) {
this.mbid = Mbid; this.mbid = Mbid;
return this; return this;
} }
public ArtistBuilder setAlbums(ArrayList<Album> albums) { public ArtistBuilder setAlbums(ArrayList<Album> albums) {
this.albums = albums; this.albums = albums;
return this; return this;
} }
public ArtistBuilder setSimilarArtists(ArrayList<Artist> similarArtists) { public ArtistBuilder setSimilarArtists(ArrayList<Artist> similarArtists) {
this.similarArtists = similarArtists; this.similarArtists = similarArtists;
return this; return this;
} }
public ArtistBuilder setTagList(ArrayList<Tag> tagList) { public ArtistBuilder setTagList(ArrayList<Tag> tagList) {
this.tagList = tagList; this.tagList = tagList;
return this; return this;
} }
public Artist build() { public Artist build() {
return new Artist(this); return new Artist(this);
} }
} }
@Override
public ArrayList<Scrobble> getScrobbles() {
if (albums != null) {
if (albums.size() > 0) {
ArrayList<Scrobble> scrobbles = new ArrayList<Scrobble>();
for (Album i : albums) {
scrobbles.addAll(i.getScrobbles());
}
return scrobbles;
}
}
return null;
}
} }

View File

@ -1,11 +1,13 @@
package sarsoo.fmframework.music; package sarsoo.fmframework.music;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import sarsoo.fmframework.jframe.FMObjView; import sarsoo.fmframework.config.Config;
import sarsoo.fmframework.util.Getter; import sarsoo.fmframework.error.ApiCallException;
import sarsoo.fmframework.fm.FmUserNetwork;
import sarsoo.fmframework.fx.FmFramework;
import sarsoo.fmframework.util.Maths; import sarsoo.fmframework.util.Maths;
import sarsoo.fmframework.util.Reference;
public abstract class FMObj implements Comparable<FMObj>, Serializable{ public abstract class FMObj implements Comparable<FMObj>, Serializable{
@ -27,29 +29,6 @@ public abstract class FMObj implements Comparable<FMObj>, Serializable{
} }
@Deprecated
public FMObj(String name, String url, String mbid, int listeners, int playCount, int userPlayCount, Wiki wiki) {
this.name = name;
this.url = url;
this.mbid = mbid;
this.listeners = listeners;
this.playCount = playCount;
this.userPlayCount = userPlayCount;
this.wiki = wiki;
}
@Deprecated
public abstract void refresh();
@Deprecated
public void view() {
FMObjView view = new FMObjView(this);
view.setVisible(true);
}
public String toString() {
return name;
}
@Override @Override
public int compareTo(FMObj obj) { public int compareTo(FMObj obj) {
@ -86,7 +65,14 @@ public abstract class FMObj implements Comparable<FMObj>, Serializable{
} }
public double getPercent() { public double getPercent() {
return ((double)userPlayCount*100)/(double) Getter.getScrobbles(Reference.getUserName()); Config config = FmFramework.getSessionConfig();
FmUserNetwork net = new FmUserNetwork(config.getValue("api_key"), config.getValue("username"));
try {
return ((double)userPlayCount*100)/(double) net.getUser().getScrobbleCount();
} catch (ApiCallException e) {}
return 0;
} }
public Wiki getWiki() { public Wiki getWiki() {
@ -94,5 +80,7 @@ public abstract class FMObj implements Comparable<FMObj>, Serializable{
} }
abstract public String getMusicBrainzURL(); abstract public String getMusicBrainzURL();
public abstract ArrayList<Scrobble> getScrobbles();
} }

View File

@ -0,0 +1,63 @@
package sarsoo.fmframework.music;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class Scrobble {
private LocalDateTime dateTime;
private long uts;
private Track track;
private Album album;
public Scrobble(long uts, Track track) {
this.track = track;
this.uts = uts;
this.dateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(uts), ZoneId.systemDefault());
}
public Scrobble(long uts, Track track, Album album) {
this.track = track;
this.album = album;
this.dateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(uts), ZoneId.systemDefault());
}
public LocalDateTime getDateTime() {
return dateTime;
}
public long getUTS() {
return uts;
}
public Track getTrack() {
return track;
}
public Album getAlbum() {
return album;
}
public void setAlbum(Album album) {
this.album = album;
}
public Artist getArtist() {
return track.getArtist();
}
public String toString() {
String string = "Scrobble: " + dateTime + " " + track.getName();
if(album != null) {
string += " " + album.getName();
}
string += " " + track.getArtist().getName();
return string;
}
}

View File

@ -18,12 +18,6 @@ public class Tag implements Comparable<Tag>, Serializable{
this.setUrl(url); this.setUrl(url);
this.count = count; this.count = count;
} }
@Deprecated
public Tag(String name, String url) {
this.setName(name);
this.setUrl(url);
}
public String getName() { public String getName() {
return name; return name;

View File

@ -3,16 +3,9 @@ package sarsoo.fmframework.music;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import org.w3c.dom.Document; import sarsoo.fmframework.cache.Cacheable;
import sarsoo.fmframework.jframe.TrackView; public class Track extends FMObj implements Serializable, Cacheable {
import sarsoo.fmframework.net.Network;
import sarsoo.fmframework.net.URLBuilder;
//import sarsoo.fmframework.net.TestCall;
import sarsoo.fmframework.parser.Parser;
import sarsoo.fmframework.util.Reference;
public class Track extends FMObj implements Serializable {
/** /**
* *
@ -24,21 +17,9 @@ public class Track extends FMObj implements Serializable {
protected int duration; protected int duration;
protected boolean isLoved; protected boolean isLoved;
protected ArrayList<Tag> tagList; protected ArrayList<Tag> tagList;
protected ArrayList<Scrobble> scrobbles;
private int utsFirstListen; private int utsFirstListen;
@Deprecated
public Track(String name, String artist) {
super(name, null, null, 0, 0, 0, null);
this.artist = new Artist(artist);
}
@Deprecated
public Track(String name, String url, String mbid, Artist artist, int listeners, int playCount, int userPlayCount,
Wiki wiki) {
super(name, url, mbid, listeners, playCount, userPlayCount, wiki);
this.artist = artist;
}
private Track(TrackBuilder builder) { private Track(TrackBuilder builder) {
@ -61,20 +42,8 @@ public class Track extends FMObj implements Serializable {
this.isLoved = builder.isLoved; this.isLoved = builder.isLoved;
this.tagList = builder.tagList; this.tagList = builder.tagList;
} this.scrobbles = new ArrayList<Scrobble>();
@Deprecated
public static Track getTrack(String name, String artist, String username) {
// System.out.println("Artist " + artist);
// System.out.println("track " + name);
String url = URLBuilder.getTrackInfoUrl(name, artist, username);
// TestCall.test(url);
Document response = Network.getResponse(url);
if (response != null) {
Track track = Parser.parseTrack(response);
return track;
}
return null;
} }
public Artist getArtist() { public Artist getArtist() {
@ -95,12 +64,23 @@ public class Track extends FMObj implements Serializable {
} }
public String getLyricsURL() { public String getLyricsURL() {
return URLBuilder.getLyricsUrl(name, artist.getName()); String trackName = name.replaceAll(" ", "-");
String artistName = artist.getName().replaceAll(" ", "-");
String urlString = String.format("http://genius.com/%s-%s-lyrics", artistName, trackName);
return urlString;
} }
public Album getAlbum() { public Album getAlbum() {
return album; return album;
} }
public void addScrobble(Scrobble scrobble) {
scrobbles.add(scrobble);
}
public void setScrobbles(ArrayList<Scrobble> scrobble) {
scrobbles = scrobble;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
@ -114,12 +94,10 @@ public class Track extends FMObj implements Serializable {
return false; return false;
} }
@Deprecated
@Override @Override
public void view() { public boolean matches(Object o) {
TrackView view = new TrackView(this); return equals(o);
view.setVisible(true);
} }
public String toString() { public String toString() {
@ -129,20 +107,6 @@ public class Track extends FMObj implements Serializable {
} }
@Deprecated
@Override
public void refresh() {
Track track = Track.getTrack(name, artist.getName(), Reference.getUserName());
this.listeners = track.listeners;
this.userPlayCount = track.userPlayCount;
this.playCount = track.playCount;
this.wiki = track.wiki;
this.mbid = track.mbid;
this.isLoved = track.isLoved;
}
public int getUtsFirstListen() { public int getUtsFirstListen() {
return utsFirstListen; return utsFirstListen;
} }
@ -250,4 +214,9 @@ public class Track extends FMObj implements Serializable {
return new Track(this); return new Track(this);
} }
} }
@Override
public ArrayList<Scrobble> getScrobbles() {
return scrobbles;
}
} }

View File

@ -2,8 +2,6 @@ package sarsoo.fmframework.music;
import java.io.Serializable; import java.io.Serializable;
import sarsoo.fmframework.jframe.WikiView;
public class Wiki implements Serializable{ public class Wiki implements Serializable{
/** /**
@ -20,11 +18,6 @@ public class Wiki implements Serializable{
this.setContent(content); this.setContent(content);
} }
public void view(String name) {
WikiView view = new WikiView(this, name);
view.setVisible(true);
}
public String getDate() { public String getDate() {
return date; return date;
} }

View File

@ -1,57 +0,0 @@
package sarsoo.fmframework.net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
@Deprecated
public class Authenticator {
public String write() {
URL url;
try {
url = new URL("http://ws.audioscrobbler.com/2.0/");
Map<String, Object> params = new LinkedHashMap<>();
params.put("name", "Freddie the Fish");
params.put("email", "fishie@seamail.example.com");
params.put("reply_to_thread", 10394);
params.put("message",
"Shark attacks in Botany Bay have gotten out of control. We need more defensive dolphins to protect the schools here, but Mayor Porpoise is too busy stuffing his snout with lobsters. He's so shellfish.");
StringBuilder postData = new StringBuilder();
for (Map.Entry<String, Object> param : params.entrySet()) {
if (postData.length() != 0)
postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
String response = sb.toString();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More