Merge pull request #4 from nico202/master

Works with recent beet version, basic http auth support
master
Max Ammann 2018-05-26 08:11:26 +02:00 committed by GitHub
commit c826593be0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 349 additions and 92 deletions

Binary file not shown.

View File

@ -0,0 +1,29 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>

18
.idea/gradle.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

34
.idea/misc.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="5">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

9
.idea/modules.xml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/music-cyclon.iml" filepath="$PROJECT_DIR$/music-cyclon.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="music-cyclon" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
@ -9,13 +9,9 @@
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
@ -26,74 +22,117 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check-manifest" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-apk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-main-apk-res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/prebuild" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/splits-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="appcompat-v7-22.0.0" level="project" />
<orderEntry type="library" exported="" name="commons-io-2.4" level="project" />
<orderEntry type="library" exported="" name="httpclient-android-4.3.5.1" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
<orderEntry type="library" name="Gradle: com.takisoft.fix:preference-v7-23.4.0.4" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.8.0@jar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:preference-v7-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:appcompat-v7-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: commons-io:commons-io:2.4@jar" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.3.1@jar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:design-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:animated-vector-drawable-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:support-v4-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:preference-v14-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:support-annotations:23.4.0@jar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:recyclerview-v7-23.4.0" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:support-vector-drawable-23.4.0" level="project" />
</component>
</module>

View File

@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "max.music_cyclon"
minSdkVersion 14
targetSdkVersion 23
versionCode 2
versionName "0.2"
versionName "0.3"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7

View File

@ -10,8 +10,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import max.music_cyclon.SynchronizeConfig;
import okhttp3.OkHttpClient;
@ -29,45 +31,48 @@ public class BeetsFetcher {
this.resources = resources;
}
public List<Item> fetch(SynchronizeConfig config) throws IOException {
public Set<Item> fetch(SynchronizeConfig config,
String username, String password) throws IOException {
StringBuilder get;
if (config.isAlbum(resources)) {
get = new StringBuilder("/album");
get = new StringBuilder("/album/");
} else {
get = new StringBuilder("/item");
get = new StringBuilder("/item/");
}
String query = config.getQuery(resources);
if (!query.isEmpty()) {
get.append("/query/").append(query);
get.append("query/").append(query);
}
get.append("?expand");
OkHttpClient client = new OkHttpClient();
String auth = okhttp3.Credentials.basic(username != null ? username : "",
password != null ? password : "");
Request request = new Request.Builder()
.url(address + get)
.header("Authorization", auth)
.build();
Response response = client.newCall(request).execute();
if (response.code() != 200) {
Log.e("ERROR", "Server returned HTTP " + response.message());
return Collections.emptyList();
return Collections.emptySet();
}
InputStream stream = response.body().byteStream();
List<Item> items = parseJson(stream, config.getSize(resources), config.isAlbum(resources));
Set<Item> items = parseJson(stream, config.getSize(resources), config.isAlbum(resources));
stream.close();
return items;
}
private List<Item> parseJson(InputStream stream, int size, boolean isAlbums) throws IOException {
private Set<Item> parseJson(InputStream stream, int size, boolean isAlbums) throws IOException {
JsonReader reader = new JsonReader(new BufferedReader(new InputStreamReader(stream, "UTF-8")));
List<Item> items = new ArrayList<>();
List<ArrayList<Item>> albums = new ArrayList<>();
@ -87,28 +92,31 @@ public class BeetsFetcher {
// Select random
if (isAlbums) {
List<ArrayList<Item>> randomAlbums = selectRandom(albums, size);
Set<ArrayList<Item>> randomAlbums = selectRandom(albums, size);
for (ArrayList<Item> album : randomAlbums) {
for (List<Item> album : randomAlbums) {
items.addAll(album);
}
return Collections.unmodifiableList(items);
return Collections.unmodifiableSet(new HashSet<Item>(items));
} else {
return selectRandom(items, size);
}
}
public <T> List<T> selectRandom(List<T> list, int n) {
public <T> Set<T> selectRandom(List<T> list, int n) {
if (list.isEmpty()) {
return Collections.emptyList();
return Collections.emptySet();
}
ArrayList<T> out = new ArrayList<>();
Set<T> out = new HashSet<T>();
for (int i = 0; i < n; i++) {
out.add(list.get(RANDOM.nextInt(list.size() - 1)));
int item = list.size() > 1 ? RANDOM.nextInt(list.size() - 1) : 0;
out.add(list.get(item));
}
return Collections.unmodifiableList(out);
return Collections.unmodifiableSet(out);
}
private ArrayList<Item> parseAlbum(JsonReader reader) throws IOException {
@ -144,8 +152,14 @@ public class BeetsFetcher {
case "id":
item.setID(reader.nextInt());
break;
case "path":
item.setPath(reader.nextString());
case "format":
item.setFormat(reader.nextString());
break;
case "title":
item.setTitle(reader.nextString());
break;
case "artist":
item.setArtist(reader.nextString());
break;
default:
reader.skipValue();

View File

@ -23,26 +23,38 @@ public class DownloadTask implements Runnable {
private final SynchronizeConfig config;
private final String url;
private final String itemPath;
private final String libraryPath;
private final String username;
private final String password;
private final FileTracker tracker;
private final ProgressUpdater progressUpdater;
private CountDownLatch itemsLeftLatch;
public static final OkHttpClient CLIENT = new OkHttpClient();
public DownloadTask(SynchronizeConfig config, String url, String itemPath,
FileTracker tracker, ProgressUpdater progressUpdater) {
public DownloadTask(SynchronizeConfig config, String url,
String libraryPath, String itemPath,
FileTracker tracker, ProgressUpdater progressUpdater,
String username, String password
) {
this.config = config;
this.url = url;
this.itemPath = itemPath;
this.libraryPath = libraryPath;
this.username = username;
this.password = password;
this.tracker = tracker;
this.progressUpdater = progressUpdater;
}
private InputStream prepareConnection() throws IOException {
String auth = okhttp3.Credentials.basic(username != null ? username : "",
password != null ? password : "");
Request request = new Request.Builder()
.url(url)
.header("Authorization", auth)
.build();
Response response = CLIENT.newCall(request).execute();
@ -61,35 +73,41 @@ public class DownloadTask implements Runnable {
@Override
public void run() {
File root = new File(Environment.getExternalStorageDirectory(), "library");
File root = new File(Environment.getExternalStorageDirectory(),
libraryPath);
if (itemPath != null) {
try {
File target = new File(root, itemPath);
if (! target.exists()) {
Adler32 checksum = new Adler32();
try {
File target = new File(root, itemPath);
Adler32 checksum = new Adler32();
InputStream input = prepareConnection();
InputStream input = prepareConnection();
if (input != null) {
Log.d("DOWNLOAD", "Writing file: " + target);
FileOutputStream output = FileUtils.openOutputStream(target);
if (input != null) {
byte[] buffer = new byte[4 * 1024];
int n;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
checksum.update(buffer, 0, n);
}
FileOutputStream output = FileUtils.openOutputStream(target);
output.flush();
output.close();
input.close();
}
byte[] buffer = new byte[4 * 1024];
int n;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
checksum.update(buffer, 0, n);
tracker.track(config, target, checksum.getValue());
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
Log.e("DOWNLOAD", "Failed to download", e);
}
tracker.track(config, target, checksum.getValue());
} catch (IOException e) {
Log.e("DOWNLOAD", "Failed to download", e);
Log.i("DOWNLOAD", "Success");
} else {
Log.e("DOWNLOAD", "Missing download path, FAILED!");
}
progressUpdater.increment();
itemsLeftLatch.countDown();
}

View File

@ -4,6 +4,9 @@ public class Item {
private int id;
private String path;
private String artist;
private String title;
private String format;
public int getID() {
return id;
@ -14,10 +17,32 @@ public class Item {
}
public String getPath() {
return path;
if (path != null) {
return path;
} else {
return "/" + artist + "/" + title + "_" + id + "." + format.toLowerCase();
}
}
public String getArtist() {
return artist;
}
public String getTitle() {
return title;
}
public String getFormat() {
return format;
}
public void setPath(String path) {
this.path = path;
}
public void setTitle(String title) {
this.title = title;
}
public void setFormat(String format) {
this.format = format;
}
public void setArtist(String artist) {
this.artist = artist;
}
}

View File

@ -18,13 +18,15 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import com.maxmpz.poweramp.player.PowerampAPI;
// Poweramp support
// import com.maxmpz.poweramp.player.PowerampAPI;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -133,10 +135,14 @@ public class LibraryService extends IntentService {
for (Parcelable parcelable : configs) {
SynchronizeConfig config = (SynchronizeConfig) parcelable;
List<Item> items;
Set<Item> items;
try {
updater.showOngoingMessage("Fetching music information for %s", config.getName());
items = fetcher.fetch(config);
items = fetcher.fetch(config,
globalSettings.getString("username", null),
globalSettings.getString("password", null));
Log.d("LISTOUT", "Length: " + items.size());
} catch (IOException e) {
Log.wtf("WTF", e);
updater.showMessage("Remote not available");
@ -149,7 +155,12 @@ public class LibraryService extends IntentService {
for (Item item : items) {
String url = address + "/item/" + item.getID() + "/file";
tasks.add(new DownloadTask(config, url, item.getPath(), tracker, updater));
tasks.add(new DownloadTask(config, url,
globalSettings.getString("library_path", "library"),
config.getName() + item.getPath(), tracker, updater,
globalSettings.getString("username", null),
globalSettings.getString("password", null)
));
}
}
@ -168,14 +179,14 @@ public class LibraryService extends IntentService {
e.printStackTrace();
}
updater.showMessage("Musik aktualisiert");
// Poweramp support
Intent poweramp = new Intent(PowerampAPI.Scanner.ACTION_SCAN_DIRS);
poweramp.setPackage(PowerampAPI.PACKAGE_NAME);
poweramp.putExtra(PowerampAPI.Scanner.EXTRA_FULL_RESCAN, true);
startService(poweramp);
updater.showMessage(getResources().getString(R.string.music_updated));
// I don't want to support proprietary things
// If you need to enable Poweramp support, uncomment this
// Intent poweramp = new Intent(PowerampAPI.Scanner.ACTION_SCAN_DIRS);
// poweramp.setPackage(PowerampAPI.PACKAGE_NAME);
// poweramp.putExtra(PowerampAPI.Scanner.EXTRA_FULL_RESCAN, true);
// startService(poweramp);
finished();
}

View File

@ -2,6 +2,8 @@
<resources>
<string name="address">http://localhost:8337</string>
<integer name="threads">2</integer>
<string name="username"></string>
<string name="password"></string>
<integer name="size">10</integer>
<bool name="random">true</bool>

View File

@ -7,6 +7,9 @@
<string name="version">Version</string>
<string name="synchronizing">Synchronizing</string>
<string name="already_synchronizing">Already synchronizing!</string>
<string name="music_updated">Music Updated!</string>
<string name="library_path">library</string>
<string name="default_config_name">Default</string>
<string name="rename">Rename</string>
</resources>

View File

@ -7,12 +7,32 @@
android:key="address"
android:summary="Address of the synchronisation server"
android:title="Address" />
<EditTextPreference
android:defaultValue="@integer/threads"
android:inputType="number"
android:key="threads"
android:summary="Number of threads to use for downloading"
android:title="Threads" />
<EditTextPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:key="library_path"
android:summary="Where to save the music"
android:title="Library Path" />
<EditTextPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:key="username"
android:summary="HTTP auth username, if required!"
android:title="HTTP username" />
<EditTextPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:key="password"
android:summary="HTTP auth password, if required!"
android:title="HTTP Password" />
</PreferenceScreen>
</PreferenceScreen>

View File

@ -3,12 +3,10 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:3.1.2'
}
}

View File

@ -1,6 +1,6 @@
#Wed Jun 01 15:28:51 CEST 2016
#Thu May 24 16:50:41 GMT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip

19
music-cyclon.iml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="music-cyclon" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>