Browse Source

Merge pull request #554 from TacoTheDank/master

Major library updates
pull/565/head
Eric Kok 4 years ago committed by GitHub
parent
commit
531527d5ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      app/build.gradle
  2. 86
      app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java
  3. 244
      app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java
  4. 131
      app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java
  5. 225
      app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java
  6. 425
      app/src/main/java/com/android/internalcopy/http/multipart/Part.java
  7. 150
      app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java
  8. 72
      app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java
  9. 143
      app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java
  10. 16
      app/src/main/java/de/timroes/axmlrpc/Call.java
  11. 15
      app/src/main/java/de/timroes/axmlrpc/ResponseParser.java
  12. 35
      app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java
  13. 2
      app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java
  14. 4
      app/src/main/java/de/timroes/axmlrpc/XMLUtil.java
  15. 17
      app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java
  16. 4
      app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java
  17. 8
      app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java
  18. 60
      app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java
  19. 7
      app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java
  20. 10
      app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java
  21. 12
      app/src/main/java/de/timroes/base64/Base64.java
  22. 141
      app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
  23. 321
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
  24. 210
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
  25. 551
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
  26. 1357
      app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
  27. 65
      app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java
  28. 1998
      app/src/main/java/org/base64/android/Base64.java
  29. 4
      app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java
  30. 4
      app/src/main/java/org/transdroid/core/gui/DetailsActivity.java
  31. 6
      app/src/main/java/org/transdroid/core/gui/DetailsFragment.java
  32. 4
      app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java
  33. 16
      app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
  34. 8
      app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java
  35. 4
      app/src/main/java/org/transdroid/core/gui/TransdroidApp.java
  36. 2
      app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java
  37. 6
      app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java
  38. 2
      app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java
  39. 14
      app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java
  40. 2
      app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java
  41. 4
      app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java
  42. 4
      app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java
  43. 6
      app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
  44. 2
      app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
  45. 2
      app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java
  46. 10
      app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java
  47. 2
      app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java
  48. 2
      app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java
  49. 2
      app/src/main/java/org/transdroid/core/service/AppUpdateJob.java
  50. 2
      app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java
  51. 6
      app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java
  52. 2
      app/src/main/java/org/transdroid/core/service/RssCheckerJob.java
  53. 2
      app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java
  54. 4
      app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java
  55. 2
      app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java
  56. 2
      app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java
  57. 4
      app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java
  58. 2
      app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java
  59. 48
      app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java
  60. 16
      app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java
  61. 28
      app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java
  62. 46
      app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java
  63. 2
      app/src/main/java/org/transdroid/daemon/DaemonException.java
  64. 8
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java
  65. 2
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java
  66. 4
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java
  67. 2
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java
  68. 14
      app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java
  69. 6
      app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java
  70. 16
      app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java
  71. 14
      app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java
  72. 6
      app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java
  73. 14
      app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java
  74. 14
      app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
  75. 108
      app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java
  76. 480
      app/src/main/java/org/transdroid/multipart/BitCometFilePart.java
  77. 88
      app/src/main/java/org/transdroid/multipart/Utf8StringPart.java
  78. 131
      app/src/main/res/layout-land/dialog_color_picker.xml
  79. 2
      app/src/main/res/layout-w600dp/activity_search.xml
  80. 8
      app/src/main/res/layout-w600dp/activity_torrents.xml
  81. 8
      app/src/main/res/layout-w900dp/activity_rssfeeds.xml
  82. 10
      app/src/main/res/layout-w900dp/activity_torrents.xml
  83. 2
      app/src/main/res/layout/activity_details.xml
  84. 8
      app/src/main/res/layout/activity_rssfeeds.xml
  85. 2
      app/src/main/res/layout/activity_rssitems.xml
  86. 4
      app/src/main/res/layout/activity_search.xml
  87. 12
      app/src/main/res/layout/activity_torrents.xml
  88. 137
      app/src/main/res/layout/dialog_color_picker.xml
  89. 8
      app/src/main/res/layout/fragment_details.xml
  90. 4
      app/src/main/res/layout/fragment_torrents.xml
  91. 2
      app/src/main/res/menu/activity_search.xml
  92. 2
      app/src/main/res/menu/activity_torrents_main.xml
  93. 15
      build.gradle
  94. 2
      gradle.properties
  95. BIN
      gradle/wrapper/gradle-wrapper.jar
  96. 3
      gradle/wrapper/gradle-wrapper.properties
  97. 117
      gradlew
  98. 34
      gradlew.bat

36
app/build.gradle

@ -2,8 +2,7 @@ apply plugin: 'com.android.application'
android { android {
compileSdkVersion 29 compileSdkVersion 29
buildToolsVersion '28.0.3' buildToolsVersion '29.0.3'
useLibrary 'org.apache.http.legacy'
defaultConfig { defaultConfig {
minSdkVersion 15 minSdkVersion 15
@ -20,6 +19,7 @@ android {
} }
} }
} }
signingConfigs { signingConfigs {
releaseConfig { releaseConfig {
def propsFile = rootProject.file('keystore.properties') def propsFile = rootProject.file('keystore.properties')
@ -35,6 +35,7 @@ android {
} }
} }
} }
buildTypes { buildTypes {
debug { debug {
minifyEnabled false minifyEnabled false
@ -46,6 +47,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
} }
flavorDimensions "version" flavorDimensions "version"
productFlavors { productFlavors {
full { full {
@ -59,30 +61,44 @@ android {
resValue "string", "search_history_authority", applicationId + ".search.SearchHistoryProvider" resValue "string", "search_history_authority", applicationId + ".search.SearchHistoryProvider"
} }
} }
lintOptions { lintOptions {
disable 'MissingTranslation', 'ExtraTranslation', 'StringFormatInvalid', 'ValidFragment', 'Registered' disable 'MissingTranslation', 'ExtraTranslation', 'StringFormatInvalid', 'ValidFragment', 'Registered'
} }
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
useLibrary 'org.apache.http.legacy'
} }
dependencies { dependencies {
// Android support
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'com.google.android.material:material:1.1.0'
// Other
implementation 'org.androidannotations:androidannotations-api:4.7.0' implementation 'org.androidannotations:androidannotations-api:4.7.0'
implementation 'org.androidannotations:ormlite-api:4.7.0' implementation 'org.androidannotations:ormlite-api:4.7.0'
implementation 'com.j256.ormlite:ormlite-core:4.48' implementation 'com.j256.ormlite:ormlite-core:5.1'
implementation 'com.j256.ormlite:ormlite-android:4.48' implementation 'com.j256.ormlite:ormlite-android:5.1'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.getbase:floatingactionbutton:1.10.1' implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'com.nispok:snackbar:2.11.0' implementation 'com.nispok:snackbar:2.11.0'
implementation 'com.github.aegnor:rencode-java:cb628e824e' implementation 'com.github.aegnor:rencode-java:cb628e824e'
implementation 'org.apache.openjpa:openjpa-lib:3.1.1'
implementation 'net.iharder:base64:2.3.9'
//implementation 'fr.turri:aXMLRPC:1.12.0'
implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') { implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') {
transitive = true transitive = true
} }
implementation 'com.evernote:android-job:1.2.6' implementation 'com.evernote:android-job:1.2.6'
annotationProcessor 'org.androidannotations:androidannotations:4.7.0' annotationProcessor 'org.androidannotations:androidannotations:4.7.0'
annotationProcessor 'org.androidannotations:ormlite:4.7.0' annotationProcessor 'org.androidannotations:ormlite:4.7.0'
} }

86
app/src/main/java/com/android/internalcopy/http/multipart/ByteArrayPartSource.java

@ -1,86 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/ByteArrayPartSource.java,v 1.7 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* A PartSource that reads from a byte array. This class should be used when
* the data to post is already loaded into memory.
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
*
* @since 2.0
*/
public class ByteArrayPartSource implements PartSource {
/** Name of the source file. */
private String fileName;
/** Byte array of the source file. */
private byte[] bytes;
/**
* Constructor for ByteArrayPartSource.
*
* @param fileName the name of the file these bytes represent
* @param bytes the content of this part
*/
public ByteArrayPartSource(String fileName, byte[] bytes) {
this.fileName = fileName;
this.bytes = bytes;
}
/**
* @see PartSource#getLength()
*/
public long getLength() {
return bytes.length;
}
/**
* @see PartSource#getFileName()
*/
public String getFileName() {
return fileName;
}
/**
* @see PartSource#createInputStream()
*/
public InputStream createInputStream() {
return new ByteArrayInputStream(bytes);
}
}

244
app/src/main/java/com/android/internalcopy/http/multipart/FilePart.java

@ -1,244 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* This class implements a part of a Multipart post object that
* consists of a file.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*
*/
public class FilePart extends PartBase {
/** Default content encoding of file attachments. */
public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
/** Default charset of file attachments. */
public static final String DEFAULT_CHARSET = "ISO-8859-1";
/** Default transfer encoding of file attachments. */
public static final String DEFAULT_TRANSFER_ENCODING = "binary";
/** Attachment's file name */
protected static final String FILE_NAME = "; filename=";
/** Attachment's file name as a byte array */
private static final byte[] FILE_NAME_BYTES =
EncodingUtils.getAsciiBytes(FILE_NAME);
/** Source of the file part. */
private PartSource source;
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*/
public FilePart(String name, PartSource partSource, String contentType, String charset) {
super(
name,
contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
charset == null ? "ISO-8859-1" : charset,
DEFAULT_TRANSFER_ENCODING
);
if (partSource == null) {
throw new IllegalArgumentException("Source may not be null");
}
this.source = partSource;
}
/**
* FilePart Constructor.
*
* @param name the name for this part
* @param partSource the source for this part
*/
public FilePart(String name, PartSource partSource) {
this(name, partSource, null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, File file)
throws FileNotFoundException {
this(name, new FilePartSource(file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(file), contentType, charset);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, String fileName, File file)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), null, null);
}
/**
* FilePart Constructor.
*
* @param name the name of the file part
* @param fileName the file name
* @param file the file to post
* @param contentType the content type for this part, if <code>null</code> the
* {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
* {@link #DEFAULT_CHARSET default} is used
*
* @throws FileNotFoundException if the <i>file</i> is not a normal
* file or if it is not readable.
*/
public FilePart(String name, String fileName, File file, String contentType, String charset)
throws FileNotFoundException {
this(name, new FilePartSource(fileName, file), contentType, charset);
}
/**
* Write the disposition header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs
* @see Part#sendDispositionHeader(OutputStream)
*/
@Override
protected void sendDispositionHeader(OutputStream out)
throws IOException {
super.sendDispositionHeader(out);
String filename = this.source.getFileName();
if (filename != null) {
out.write(FILE_NAME_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(filename));
out.write(QUOTE_BYTES);
}
}
/**
* Write the data in "source" to the specified stream.
* @param out The output stream.
* @throws IOException if an IO problem occurs.
* @see Part#sendData(OutputStream)
*/
@Override
protected void sendData(OutputStream out) throws IOException {
if (lengthOfData() == 0) {
// this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
// cause an infinite loop when reading.
return;
}
byte[] tmp = new byte[4096];
InputStream instream = source.createInputStream();
try {
int len;
while ((len = instream.read(tmp)) >= 0) {
out.write(tmp, 0, len);
}
} finally {
// we're done with the stream, close it
instream.close();
}
}
/**
* Returns the source of the file part.
*
* @return The source.
*/
protected PartSource getSource() {
return this.source;
}
/**
* Return the length of the data.
* @return The length.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return source.getLength();
}
}

131
app/src/main/java/com/android/internalcopy/http/multipart/FilePartSource.java

@ -1,131 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePartSource.java,v 1.10 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* A PartSource that reads from a File.
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
*
* @since 2.0
*/
public class FilePartSource implements PartSource {
/** File part file. */
private File file = null;
/** File part file name. */
private String fileName = null;
/**
* Constructor for FilePartSource.
*
* @param file the FilePart source File.
*
* @throws FileNotFoundException if the file does not exist or
* cannot be read
*/
public FilePartSource(File file) throws FileNotFoundException {
this.file = file;
if (file != null) {
if (!file.isFile()) {
throw new FileNotFoundException("File is not a normal file.");
}
if (!file.canRead()) {
throw new FileNotFoundException("File is not readable.");
}
this.fileName = file.getName();
}
}
/**
* Constructor for FilePartSource.
*
* @param fileName the file name of the FilePart
* @param file the source File for the FilePart
*
* @throws FileNotFoundException if the file does not exist or
* cannot be read
*/
public FilePartSource(String fileName, File file)
throws FileNotFoundException {
this(file);
if (fileName != null) {
this.fileName = fileName;
}
}
/**
* Return the length of the file
* @return the length of the file.
* @see PartSource#getLength()
*/
public long getLength() {
if (this.file != null) {
return this.file.length();
} else {
return 0;
}
}
/**
* Return the current filename
* @return the filename.
* @see PartSource#getFileName()
*/
public String getFileName() {
return (fileName == null) ? "noname" : fileName;
}
/**
* Return a new {@link FileInputStream} for the current filename.
* @return the new input stream.
* @throws IOException If an IO problem occurs.
* @see PartSource#createInputStream()
*/
public InputStream createInputStream() throws IOException {
if (this.file != null) {
return new FileInputStream(this.file);
} else {
return new ByteArrayInputStream(new byte[] {});
}
}
}

225
app/src/main/java/com/android/internalcopy/http/multipart/MultipartEntity.java

@ -1,225 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.java,v 1.1 2004/10/06 03:39:59 mbecke Exp $
* $Revision: 502647 $
* $Date: 2007-02-02 17:22:54 +0100 (Fri, 02 Feb 2007) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Random;
import org.apache.http.Header;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EncodingUtils;
/**
* Implements a request entity suitable for an HTTP multipart POST method.
* <p>
* The HTTP multipart POST method is defined in section 3.3 of
* <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC1867</a>:
* <blockquote>
* The media-type multipart/form-data follows the rules of all multipart
* MIME data streams as outlined in RFC 1521. The multipart/form-data contains
* a series of parts. Each part is expected to contain a content-disposition
* header where the value is "form-data" and a name attribute specifies
* the field name within the form, e.g., 'content-disposition: form-data;
* name="xxxxx"', where xxxxx is the field name corresponding to that field.
* Field names originally in non-ASCII character sets may be encoded using
* the method outlined in RFC 1522.
* </blockquote>
* </p>
* <p>This entity is designed to be used in conjunction with the
* {@link org.apache.http.HttpRequest} to provide
* multipart posts. Example usage:</p>
* <pre>
* File f = new File("/path/fileToUpload.txt");
* HttpRequest request = new HttpRequest("http://host/some_path");
* Part[] parts = {
* new StringPart("param_name", "value"),
* new FilePart(f.getName(), f)
* };
* filePost.setEntity(
* new MultipartRequestEntity(parts, filePost.getParams())
* );
* HttpClient client = new HttpClient();
* int status = client.executeMethod(filePost);
* </pre>
*
* @since 3.0
*/
public class MultipartEntity extends AbstractHttpEntity {
/** The Content-Type for multipart/form-data. */
private static final String MULTIPART_FORM_CONTENT_TYPE = "multipart/form-data";
/**
* Sets the value to use as the multipart boundary.
* <p>
* This parameter expects a value if type {@link String}.
* </p>
*/
public static final String MULTIPART_BOUNDARY = "http.method.multipart.boundary";
/**
* The pool of ASCII chars to be used for generating a multipart boundary.
*/
private static byte[] MULTIPART_CHARS = EncodingUtils.getAsciiBytes(
"-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
/**
* Generates a random multipart boundary string.
*/
private static byte[] generateMultipartBoundary() {
Random rand = new Random();
byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size from 30 to 40
for (int i = 0; i < bytes.length; i++) {
bytes[i] = MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)];
}
return bytes;
}
/** The MIME parts as set by the constructor */
protected Part[] parts;
private byte[] multipartBoundary;
private HttpParams params;
private boolean contentConsumed = false;
/**
* Creates a new multipart entity containing the given parts.
* @param parts The parts to include.
* @param params The params of the HttpMethod using this entity.
*/
public MultipartEntity(Part[] parts, HttpParams params) {
if (parts == null) {
throw new IllegalArgumentException("parts cannot be null");
}
if (params == null) {
throw new IllegalArgumentException("params cannot be null");
}
this.parts = parts;
this.params = params;
}
public MultipartEntity(Part[] parts) {
setContentType(MULTIPART_FORM_CONTENT_TYPE);
if (parts == null) {
throw new IllegalArgumentException("parts cannot be null");
}
this.parts = parts;
this.params = null;
}
/**
* Returns the MIME boundary string that is used to demarcate boundaries of
* this part. The first call to this method will implicitly create a new
* boundary string. To create a boundary string first the
* HttpMethodParams.MULTIPART_BOUNDARY parameter is considered. Otherwise
* a random one is generated.
*
* @return The boundary string of this entity in ASCII encoding.
*/
protected byte[] getMultipartBoundary() {
if (multipartBoundary == null) {
String temp = null;
if (params != null) {
temp = (String) params.getParameter(MULTIPART_BOUNDARY);
}
if (temp != null) {
multipartBoundary = EncodingUtils.getAsciiBytes(temp);
} else {
multipartBoundary = generateMultipartBoundary();
}
}
return multipartBoundary;
}
/**
* Returns <code>true</code> if all parts are repeatable, <code>false</code> otherwise.
*/
public boolean isRepeatable() {
for (int i = 0; i < parts.length; i++) {
if (!parts[i].isRepeatable()) {
return false;
}
}
return true;
}
/* (non-Javadoc)
*/
public void writeTo(OutputStream out) throws IOException {
Part.sendParts(out, parts, getMultipartBoundary());
}
/* (non-Javadoc)
* @see org.apache.commons.http.AbstractHttpEntity.#getContentType()
*/
@Override
public Header getContentType() {
StringBuffer buffer = new StringBuffer(MULTIPART_FORM_CONTENT_TYPE);
buffer.append("; boundary=");
buffer.append(EncodingUtils.getAsciiString(getMultipartBoundary()));
return new BasicHeader(HTTP.CONTENT_TYPE, buffer.toString());
}
/* (non-Javadoc)
*/
public long getContentLength() {
try {
return Part.getLengthOfParts(parts, getMultipartBoundary());
} catch (Exception e) {
return 0;
}
}
public InputStream getContent() throws IOException, IllegalStateException {
if(!isRepeatable() && this.contentConsumed ) {
throw new IllegalStateException("Content has been consumed");
}
this.contentConsumed = true;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Part.sendParts(baos, this.parts, this.multipartBoundary);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return bais;
}
public boolean isStreaming() {
return false;
}
}

425
app/src/main/java/com/android/internalcopy/http/multipart/Part.java

@ -1,425 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.16 2005/01/14 21:16:40 olegk Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.util.EncodingUtils;
/**
* Abstract class for one Part of a multipart post object.
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*/
public abstract class Part {
/**
* The boundary
* @deprecated use {@link org.apache.http.client.methods.multipart#MULTIPART_BOUNDARY}
*/
protected static final String BOUNDARY = "----------------314159265358979323846";
/**
* The boundary as a byte array.
* @deprecated
*/
protected static final byte[] BOUNDARY_BYTES = EncodingUtils.getAsciiBytes(BOUNDARY);
/**
* The default boundary to be used if {@link #setPartBoundary(byte[])} has not
* been called.
*/
private static final byte[] DEFAULT_BOUNDARY_BYTES = BOUNDARY_BYTES;
/** Carriage return/linefeed */
protected static final String CRLF = "\r\n";
/** Carriage return/linefeed as a byte array */
protected static final byte[] CRLF_BYTES = EncodingUtils.getAsciiBytes(CRLF);
/** Content dispostion characters */
protected static final String QUOTE = "\"";
/** Content dispostion as a byte array */
protected static final byte[] QUOTE_BYTES =
EncodingUtils.getAsciiBytes(QUOTE);
/** Extra characters */
protected static final String EXTRA = "--";
/** Extra characters as a byte array */
protected static final byte[] EXTRA_BYTES =
EncodingUtils.getAsciiBytes(EXTRA);
/** Content dispostion characters */
protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name=";
/** Content dispostion as a byte array */
protected static final byte[] CONTENT_DISPOSITION_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_DISPOSITION);
/** Content type header */
protected static final String CONTENT_TYPE = "Content-Type: ";
/** Content type header as a byte array */
protected static final byte[] CONTENT_TYPE_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_TYPE);
/** Content charset */
protected static final String CHARSET = "; charset=";
/** Content charset as a byte array */
protected static final byte[] CHARSET_BYTES =
EncodingUtils.getAsciiBytes(CHARSET);
/** Content type header */
protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: ";
/** Content type header as a byte array */
protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES =
EncodingUtils.getAsciiBytes(CONTENT_TRANSFER_ENCODING);
/**
* Return the boundary string.
* @return the boundary string
* @deprecated uses a constant string. Rather use {@link #getPartBoundary}
*/
public static String getBoundary() {
return BOUNDARY;
}
/**
* The ASCII bytes to use as the multipart boundary.
*/
private byte[] boundaryBytes;
/**
* Return the name of this part.
* @return The name.
*/
public abstract String getName();
/**
* Returns the content type of this part.
* @return the content type, or <code>null</code> to exclude the content type header
*/
public abstract String getContentType();
/**
* Return the character encoding of this part.
* @return the character encoding, or <code>null</code> to exclude the character
* encoding header
*/
public abstract String getCharSet();
/**
* Return the transfer encoding of this part.
* @return the transfer encoding, or <code>null</code> to exclude the transfer encoding header
*/
public abstract String getTransferEncoding();
/**
* Gets the part boundary to be used.
* @return the part boundary as an array of bytes.
*
* @since 3.0
*/
protected byte[] getPartBoundary() {
if (boundaryBytes == null) {
// custom boundary bytes have not been set, use the default.
return DEFAULT_BOUNDARY_BYTES;
} else {
return boundaryBytes;
}
}
/**
* Sets the part boundary. Only meant to be used by
* {@link Part#sendParts(OutputStream, Part[], byte[])}
* and {@link Part#getLengthOfParts(Part[], byte[])}
* @param boundaryBytes An array of ASCII bytes.
* @since 3.0
*/
void setPartBoundary(byte[] boundaryBytes) {
this.boundaryBytes = boundaryBytes;
}
/**
* Tests if this part can be sent more than once.
* @return <code>true</code> if {@link #sendData(OutputStream)} can be successfully called
* more than once.
* @since 3.0
*/
public boolean isRepeatable() {
return true;
}
/**
* Write the start to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendStart(OutputStream out) throws IOException {
out.write(EXTRA_BYTES);
out.write(getPartBoundary());
out.write(CRLF_BYTES);
}
/**
* Write the content disposition header to the specified output stream
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendDispositionHeader(OutputStream out) throws IOException {
out.write(CONTENT_DISPOSITION_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(getName()));
out.write(QUOTE_BYTES);
}
/**
* Write the content type header to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendContentTypeHeader(OutputStream out) throws IOException {
String contentType = getContentType();
if (contentType != null) {
out.write(CRLF_BYTES);
out.write(CONTENT_TYPE_BYTES);
out.write(EncodingUtils.getAsciiBytes(contentType));
String charSet = getCharSet();
if (charSet != null) {
out.write(CHARSET_BYTES);
out.write(EncodingUtils.getAsciiBytes(charSet));
}
}
}
/**
* Write the content transfer encoding header to the specified
* output stream
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendTransferEncodingHeader(OutputStream out) throws IOException {
String transferEncoding = getTransferEncoding();
if (transferEncoding != null) {
out.write(CRLF_BYTES);
out.write(CONTENT_TRANSFER_ENCODING_BYTES);
out.write(EncodingUtils.getAsciiBytes(transferEncoding));
}
}
/**
* Write the end of the header to the output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendEndOfHeader(OutputStream out) throws IOException {
out.write(CRLF_BYTES);
out.write(CRLF_BYTES);
}
/**
* Write the data to the specified output stream
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected abstract void sendData(OutputStream out) throws IOException;
/**
* Return the length of the main content
*
* @return long The length.
* @throws IOException If an IO problem occurs
*/
protected abstract long lengthOfData() throws IOException;
/**
* Write the end data to the output stream.
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
protected void sendEnd(OutputStream out) throws IOException {
out.write(CRLF_BYTES);
}
/**
* Write all the data to the output stream.
* If you override this method make sure to override
* #length() as well
*
* @param out The output stream
* @throws IOException If an IO problem occurs.
*/
public void send(OutputStream out) throws IOException {
sendStart(out);
sendDispositionHeader(out);
sendContentTypeHeader(out);
sendTransferEncodingHeader(out);
sendEndOfHeader(out);
sendData(out);
sendEnd(out);
}
/**
* Return the full length of all the data.
* If you override this method make sure to override
* #send(OutputStream) as well
*
* @return long The length.
* @throws IOException If an IO problem occurs
*/
public long length() throws IOException {
if (lengthOfData() < 0) {
return -1;
}
ByteArrayOutputStream overhead = new ByteArrayOutputStream();
sendStart(overhead);
sendDispositionHeader(overhead);
sendContentTypeHeader(overhead);
sendTransferEncodingHeader(overhead);
sendEndOfHeader(overhead);
sendEnd(overhead);
return overhead.size() + lengthOfData();
}
/**
* Return a string representation of this object.
* @return A string representation of this object.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.getName();
}
/**
* Write all parts and the last boundary to the specified output stream.
*
* @param out The stream to write to.
* @param parts The parts to write.
*
* @throws IOException If an I/O error occurs while writing the parts.
*/
public static void sendParts(OutputStream out, final Part[] parts)
throws IOException {
sendParts(out, parts, DEFAULT_BOUNDARY_BYTES);
}
/**
* Write all parts and the last boundary to the specified output stream.
*
* @param out The stream to write to.
* @param parts The parts to write.
* @param partBoundary The ASCII bytes to use as the part boundary.
*
* @throws IOException If an I/O error occurs while writing the parts.
*
* @since 3.0
*/
public static void sendParts(OutputStream out, Part[] parts, byte[] partBoundary)
throws IOException {
if (parts == null) {
throw new IllegalArgumentException("Parts may not be null");
}
if (partBoundary == null || partBoundary.length == 0) {
throw new IllegalArgumentException("partBoundary may not be empty");
}
for (int i = 0; i < parts.length; i++) {
// set the part boundary before the part is sent
parts[i].setPartBoundary(partBoundary);
parts[i].send(out);
}
out.write(EXTRA_BYTES);
out.write(partBoundary);
out.write(EXTRA_BYTES);
out.write(CRLF_BYTES);
}
/**
* Return the total sum of all parts and that of the last boundary
*
* @param parts The parts.
* @return The total length
*
* @throws IOException If an I/O error occurs while writing the parts.
*/
public static long getLengthOfParts(Part[] parts)
throws IOException {
return getLengthOfParts(parts, DEFAULT_BOUNDARY_BYTES);
}
/**
* Gets the length of the multipart message including the given parts.
*
* @param parts The parts.
* @param partBoundary The ASCII bytes to use as the part boundary.
* @return The total length
*
* @throws IOException If an I/O error occurs while writing the parts.
*
* @since 3.0
*/
public static long getLengthOfParts(Part[] parts, byte[] partBoundary) throws IOException {
if (parts == null) {
throw new IllegalArgumentException("Parts may not be null");
}
long total = 0;
for (int i = 0; i < parts.length; i++) {
// set the part boundary before we calculate the part's length
parts[i].setPartBoundary(partBoundary);
long l = parts[i].length();
if (l < 0) {
return -1;
}
total += l;
}
total += EXTRA_BYTES.length;
total += partBoundary.length;
total += EXTRA_BYTES.length;
total += CRLF_BYTES.length;
return total;
}
}

150
app/src/main/java/com/android/internalcopy/http/multipart/PartBase.java

@ -1,150 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartBase.java,v 1.5 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
/**
* Provides setters and getters for the basic Part properties.
*
* @author Michael Becke
*/
public abstract class PartBase extends Part {
/** Name of the file part. */
private String name;
/** Content type of the file part. */
private String contentType;
/** Content encoding of the file part. */
private String charSet;
/** The transfer encoding. */
private String transferEncoding;
/**
* Constructor.
*
* @param name The name of the part
* @param contentType The content type, or <code>null</code>
* @param charSet The character encoding, or <code>null</code>
* @param transferEncoding The transfer encoding, or <code>null</code>
*/
public PartBase(String name, String contentType, String charSet, String transferEncoding) {
if (name == null) {
throw new IllegalArgumentException("Name must not be null");
}
this.name = name;
this.contentType = contentType;
this.charSet = charSet;
this.transferEncoding = transferEncoding;
}
/**
* Returns the name.
* @return The name.
* @see Part#getName()
*/
@Override
public String getName() {
return this.name;
}
/**
* Returns the content type of this part.
* @return String The name.
*/
@Override
public String getContentType() {
return this.contentType;
}
/**
* Return the character encoding of this part.
* @return String The name.
*/
@Override
public String getCharSet() {
return this.charSet;
}
/**
* Returns the transfer encoding of this part.
* @return String The name.
*/
@Override
public String getTransferEncoding() {
return transferEncoding;
}
/**
* Sets the character encoding.
*
* @param charSet the character encoding, or <code>null</code> to exclude the character
* encoding header
*/
public void setCharSet(String charSet) {
this.charSet = charSet;
}
/**
* Sets the content type.
*
* @param contentType the content type, or <code>null</code> to exclude the content type header
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* Sets the part name.
*
* @param name
*/
public void setName(String name) {
if (name == null) {
throw new IllegalArgumentException("Name must not be null");
}
this.name = name;
}
/**
* Sets the transfer encoding.
*
* @param transferEncoding the transfer encoding, or <code>null</code> to exclude the
* transfer encoding header
*/
public void setTransferEncoding(String transferEncoding) {
this.transferEncoding = transferEncoding;
}
}

72
app/src/main/java/com/android/internalcopy/http/multipart/PartSource.java

@ -1,72 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/PartSource.java,v 1.6 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.IOException;
import java.io.InputStream;
/**
* An interface for providing access to data when posting MultiPart messages.
*
* @see FilePart
*
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
*
* @since 2.0
*/
public interface PartSource {
/**
* Gets the number of bytes contained in this source.
*
* @return a value >= 0
*/
long getLength();
/**
* Gets the name of the file this source represents.
*
* @return the fileName used for posting a MultiPart file part
*/
String getFileName();
/**
* Gets a new InputStream for reading this source. This method can be
* called more than once and should therefore return a new stream every
* time.
*
* @return a new InputStream
*
* @throws IOException if an error occurs when creating the InputStream
*/
InputStream createInputStream() throws IOException;
}

143
app/src/main/java/com/android/internalcopy/http/multipart/StringPart.java

@ -1,143 +0,0 @@
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/StringPart.java,v 1.11 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package com.android.internalcopy.http.multipart;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.http.util.EncodingUtils;
/**
* Simple string parameter for a multipart post
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
*
* @since 2.0
*/
public class StringPart extends PartBase {
/** Default content encoding of string parameters. */
public static final String DEFAULT_CONTENT_TYPE = "text/plain";
/** Default charset of string parameters*/
public static final String DEFAULT_CHARSET = "US-ASCII";
/** Default transfer encoding of string parameters*/
public static final String DEFAULT_TRANSFER_ENCODING = "8bit";
/** Contents of this StringPart. */
private byte[] content;
/** The String value of this part. */
private String value;
/**
* Constructor.
*
* @param name The name of the part
* @param value the string to post
* @param charset the charset to be used to encode the string, if <code>null</code>
* the {@link #DEFAULT_CHARSET default} is used
*/
public StringPart(String name, String value, String charset) {
super(
name,
DEFAULT_CONTENT_TYPE,
charset == null ? DEFAULT_CHARSET : charset,
DEFAULT_TRANSFER_ENCODING
);
if (value == null) {
throw new IllegalArgumentException("Value may not be null");
}
if (value.indexOf(0) != -1) {
// See RFC 2048, 2.8. "8bit Data"
throw new IllegalArgumentException("NULs may not be present in string parts");
}
this.value = value;
}
/**
* Constructor.
*
* @param name The name of the part
* @param value the string to post
*/
public StringPart(String name, String value) {
this(name, value, null);
}
/**
* Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* after the part is created.
*
* @return the content in bytes
*/
private byte[] getContent() {
if (content == null) {
content = EncodingUtils.getBytes(value, getCharSet());
}
return content;
}
/**
* Writes the data to the given OutputStream.
* @param out the OutputStream to write to
* @throws IOException if there is a write error
*/
@Override
protected void sendData(OutputStream out) throws IOException {
out.write(getContent());
}
/**
* Return the length of the data.
* @return The length of the data.
* @see Part#lengthOfData()
*/
@Override
protected long lengthOfData() {
return getContent().length;
}
/* (non-Javadoc)
* @see org.apache.commons.httpclient.methods.multipart.BasePart#setCharSet(java.lang.String)
*/
@Override
public void setCharSet(String charSet) {
super.setCharSet(charSet);
this.content = null;
}
}

16
app/src/main/java/de/timroes/axmlrpc/Call.java

@ -16,13 +16,14 @@ public class Call {
private String method; private String method;
private Object[] params; private Object[] params;
private final SerializerHandler serializerHandler;
/** /**
* Create a new method call with the given name and no parameters. * Create a new method call with the given name and no parameters.
* @param method The method to be called. * @param method The method to be called.
*/ */
public Call(String method) { public Call(SerializerHandler serializerHandler, String method) {
this(method, null); this(serializerHandler, method, null);
} }
/** /**
@ -30,9 +31,10 @@ public class Call {
* @param method The method to be called. * @param method The method to be called.
* @param params An array of parameters for the method. * @param params An array of parameters for the method.
*/ */
public Call(String method, Object[] params) { public Call(SerializerHandler serializerHandler, String method, Object[] params) {
this.method = method; this.method = method;
this.params = params; this.params = params;
this.serializerHandler = serializerHandler;
} }
/** /**
@ -57,11 +59,11 @@ public class Call {
methodCall.addChildren(methodName); methodCall.addChildren(methodName);
if(params != null && params.length > 0) { if(params != null && params.length > 0) {
XmlElement params = new XmlElement(XMLRPCClient.PARAMS); XmlElement callParams = new XmlElement(XMLRPCClient.PARAMS);
methodCall.addChildren(params); methodCall.addChildren(callParams);
for(Object o : this.params) { for(Object o : this.params) {
params.addChildren(getXMLParam(o)); callParams.addChildren(getXMLParam(o));
} }
} }
@ -79,7 +81,7 @@ public class Call {
XmlElement param = new XmlElement(XMLRPCClient.PARAM); XmlElement param = new XmlElement(XMLRPCClient.PARAM);
XmlElement value = new XmlElement(XMLRPCClient.VALUE); XmlElement value = new XmlElement(XMLRPCClient.VALUE);
param.addChildren(value); param.addChildren(value);
value.addChildren(SerializerHandler.getDefault().serialize(o)); value.addChildren(serializerHandler.serialize(o));
return param; return param;
} }

15
app/src/main/java/de/timroes/axmlrpc/ResponseParser.java

@ -16,7 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
* *
* @author Tim Roes * @author Tim Roes
*/ */
class ResponseParser { public class ResponseParser {
private static final String FAULT_CODE = "faultCode"; private static final String FAULT_CODE = "faultCode";
private static final String FAULT_STRING = "faultString"; private static final String FAULT_STRING = "faultString";
@ -71,13 +71,13 @@ class ResponseParser {
pullParser.nextTag(); // TAG_VALUE (<value>) pullParser.nextTag(); // TAG_VALUE (<value>)
// no parser.require() here since its called in XMLRPCSerializer.deserialize() below // no parser.require() here since its called in XMLRPCSerializer.deserialize() below
// deserialize result // deserialize result
Object obj = SerializerHandler.getDefault().deserialize(pullParser); Object obj = SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
return obj; return obj;
} else if (tag.equals(XMLRPCClient.FAULT)) { } else if (tag.equals(XMLRPCClient.FAULT)) {
// fault response // fault response
pullParser.nextTag(); // TAG_VALUE (<value>) pullParser.nextTag(); // TAG_VALUE (<value>)
Map<String, Object> map = (Map<String, Object>) SerializerHandler.getDefault().deserialize(pullParser); Map<String, Object> map = (Map<String, Object>) SerializerHandler.deserialize(pullParser);
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
//Check that required tags are in the response //Check that required tags are in the response
@ -92,12 +92,11 @@ class ResponseParser {
} catch (XmlPullParserException ex) { } catch (XmlPullParserException ex) {
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
throw new XMLRPCException("Error parsing response.", ex); throw new XMLRPCException("Error parsing response.", ex);
} catch(XMLRPCServerException e) {
throw e;
} catch (Exception ex) { } catch (Exception ex) {
consumeHttpEntity(response, entity); consumeHttpEntity(response, entity);
if(ex instanceof XMLRPCServerException) throw new XMLRPCException("Error getting result from server.", ex);
throw (XMLRPCServerException)ex;
else
throw new XMLRPCException("Error getting result from server.", ex);
} }
} }
} }

35
app/src/main/java/de/timroes/axmlrpc/XMLRPCClient.java

@ -127,6 +127,11 @@ public class XMLRPCClient {
*/ */
public static final int FLAGS_NO_STRING_ENCODE = 0x1000; public static final int FLAGS_NO_STRING_ENCODE = 0x1000;
/**
* Accepts response containing eg: <dateTime.iso8601/>
*/
public static final int FLAGS_ACCEPT_NULL_DATES = 0x4000;
/** /**
* This flag should be used if the server is an apache ws xmlrpc server. * This flag should be used if the server is an apache ws xmlrpc server.
* This will set some flags, so that the not standard conform behavior * This will set some flags, so that the not standard conform behavior
@ -140,28 +145,30 @@ public class XMLRPCClient {
private final int flags; private final int flags;
private DefaultHttpClient httpclient; private DefaultHttpClient httpclient;
private String url; private String url;
private Map<Long,Caller> backgroundCalls = new ConcurrentHashMap<Long, Caller>(); private Map<Long,Caller> backgroundCalls = new ConcurrentHashMap<Long, Caller>();
private ResponseParser responseParser; private ResponseParser responseParser;
private final SerializerHandler serializerHandler;
/** /**
* Create a new XMLRPC client for the given URL. * Create a new XMLRPC client for the given URL.
* *
* @param httpclient The already-initialized Apache HttpClient to use for connection. * @param httpclient The already-initialized Apache HttpClient to use for connection.
* @param url The URL to send the requests to. * @param url The URL to send the requests to.
* @param flags A combination of flags to be set. * @param flags A combination of flags to be set.
*/ */
public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) { public XMLRPCClient(DefaultHttpClient httpclient, String url, int flags) {
SerializerHandler.initialize(flags); this.serializerHandler = new SerializerHandler(flags);
this.httpclient = httpclient; this.httpclient = httpclient;
this.url = url; this.url = url;
this.flags = flags; this.flags = flags;
// Create a parser for the http responses. // Create a parser for the http responses.
responseParser = new ResponseParser(); responseParser = new ResponseParser();
@ -260,7 +267,7 @@ public class XMLRPCClient {
throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / "); throw new XMLRPCRuntimeException("Method name must only contain A-Z a-z . : _ / ");
} }
return new Call(method, params); return new Call(serializerHandler, method, params);
} }
@ -368,7 +375,7 @@ public class XMLRPCClient {
try { try {
Call c = createCall(methodName, params); Call c = createCall(methodName, params);
// Prepare POST request // Prepare POST request
// FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything // FIXME: where creating a new HttpPost so calling #cancel isn't going to do anything
HttpPost post = new HttpPost(url); HttpPost post = new HttpPost(url);
@ -377,10 +384,10 @@ public class XMLRPCClient {
StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8); StringEntity entity = new StringEntity(c.getXML(), HTTP.UTF_8);
entity.setContentType(TYPE_XML); entity.setContentType(TYPE_XML);
post.setEntity(entity); post.setEntity(entity);
HttpResponse response = httpclient.execute(post); HttpResponse response = httpclient.execute(post);
int statusCode = response.getStatusLine().getStatusCode(); int statusCode = response.getStatusLine().getStatusCode();
InputStream istream; InputStream istream;
// If status code was 401 or 403 throw exception or if appropriate // If status code was 401 or 403 throw exception or if appropriate
@ -406,7 +413,7 @@ public class XMLRPCClient {
|| statusCode == HttpURLConnection.HTTP_MOVED_TEMP) { || statusCode == HttpURLConnection.HTTP_MOVED_TEMP) {
// ... do either a foward // ... do either a foward
if(isFlagSet(FLAGS_FORWARD)) { if(isFlagSet(FLAGS_FORWARD)) {
boolean temporaryForward = (statusCode == HttpURLConnection.HTTP_MOVED_TEMP); boolean temporaryForward = statusCode == HttpURLConnection.HTTP_MOVED_TEMP;
// Get new location from header field. // Get new location from header field.
String newLocation = response.getFirstHeader("Location").getValue(); String newLocation = response.getFirstHeader("Location").getValue();
@ -440,10 +447,8 @@ public class XMLRPCClient {
} }
// Check for strict parameters // Check for strict parameters
if(isFlagSet(FLAGS_STRICT)) { if(isFlagSet(FLAGS_STRICT) && !response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
if(!response.getFirstHeader("Content-Type").getValue().startsWith(TYPE_XML)) {
throw new XMLRPCException("The Content-Type of the response must be text/xml."); throw new XMLRPCException("The Content-Type of the response must be text/xml.");
}
} }
return responseParser.parse(istream, entity); return responseParser.parse(istream, entity);
@ -462,9 +467,9 @@ public class XMLRPCClient {
} }
} }
} }
public static class CancelException extends Exception { public static class CancelException extends Exception {
private static final long serialVersionUID = 9125122307255855136L; private static final long serialVersionUID = 9125122307255855136L;
} }
@ -475,5 +480,5 @@ public class XMLRPCClient {
public UnauthorizdException(int statusCode) { this.statusCode = statusCode; } public UnauthorizdException(int statusCode) { this.statusCode = statusCode; }
public int getStatusCode() { return statusCode; } public int getStatusCode() { return statusCode; }
} }
} }

2
app/src/main/java/de/timroes/axmlrpc/XMLRPCServerException.java

@ -8,7 +8,7 @@ package de.timroes.axmlrpc;
*/ */
public class XMLRPCServerException extends XMLRPCException { public class XMLRPCServerException extends XMLRPCException {
private int errornr; private final int errornr;
public XMLRPCServerException(String ex, int errnr) { public XMLRPCServerException(String ex, int errnr) {
super(ex); super(ex);

4
app/src/main/java/de/timroes/axmlrpc/XMLUtil.java

@ -9,6 +9,8 @@ import de.timroes.axmlrpc.xmlcreator.XmlElement;
*/ */
public class XMLUtil { public class XMLUtil {
private XMLUtil() {}
/** /**
* Creates an xml tag with a given type and content. * Creates an xml tag with a given type and content.
* *
@ -22,4 +24,4 @@ public class XMLUtil {
return xml; return xml;
} }
} }

17
app/src/main/java/de/timroes/axmlrpc/serializer/ArraySerializer.java

@ -3,6 +3,7 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCException; import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException; import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement; import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.util.Arrays;
/** /**
* *
@ -12,10 +13,20 @@ public class ArraySerializer implements Serializer {
private static final String ARRAY_DATA = "data"; private static final String ARRAY_DATA = "data";
private static final String ARRAY_VALUE = "value"; private static final String ARRAY_VALUE = "value";
private final SerializerHandler serializerHandler;
public ArraySerializer(SerializerHandler serializerHandler){
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
Iterable<?> iter = (Iterable<?>)object; Iterable<?> iter;
if ( object instanceof Iterable<?>){
iter = (Iterable<?>)object;
} else {
iter = Arrays.asList((Object[]) object);
}
XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY); XmlElement array = new XmlElement(SerializerHandler.TYPE_ARRAY);
XmlElement data = new XmlElement(ARRAY_DATA); XmlElement data = new XmlElement(ARRAY_DATA);
array.addChildren(data); array.addChildren(data);
@ -25,7 +36,7 @@ public class ArraySerializer implements Serializer {
XmlElement e; XmlElement e;
for(Object obj : iter) { for(Object obj : iter) {
e = new XmlElement(ARRAY_VALUE); e = new XmlElement(ARRAY_VALUE);
e.addChildren(SerializerHandler.getDefault().serialize(obj)); e.addChildren(serializerHandler.serialize(obj));
data.addChildren(e); data.addChildren(e);
} }
@ -37,4 +48,4 @@ public class ArraySerializer implements Serializer {
} }
} }

4
app/src/main/java/de/timroes/axmlrpc/serializer/BooleanSerializer.java

@ -11,7 +11,7 @@ public class BooleanSerializer implements Serializer {
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN, return XMLUtil.makeXmlTag(SerializerHandler.TYPE_BOOLEAN,
((Boolean)object == true) ? "1" : "0"); (Boolean) object ? "1" : "0");
} }
} }

8
app/src/main/java/de/timroes/axmlrpc/serializer/DateTimeSerializer.java

@ -10,9 +10,15 @@ import java.text.SimpleDateFormat;
*/ */
public class DateTimeSerializer implements Serializer { public class DateTimeSerializer implements Serializer {
public static final String DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss"; public static final String DATETIME_FORMAT = "yyyyMMdd'T'HHmmss";
public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT); public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat(DATETIME_FORMAT);
public final boolean accepts_null_input;
public DateTimeSerializer(boolean accepts_null_input) {
this.accepts_null_input = accepts_null_input;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME, return XMLUtil.makeXmlTag(SerializerHandler.TYPE_DATETIME,
DATE_FORMATER.format(object)); DATE_FORMATER.format(object));

60
app/src/main/java/de/timroes/axmlrpc/serializer/SerializerHandler.java

@ -2,7 +2,6 @@ package de.timroes.axmlrpc.serializer;
import de.timroes.axmlrpc.XMLRPCClient; import de.timroes.axmlrpc.XMLRPCClient;
import de.timroes.axmlrpc.XMLRPCException; import de.timroes.axmlrpc.XMLRPCException;
import de.timroes.axmlrpc.XMLRPCRuntimeException;
import de.timroes.axmlrpc.xmlcreator.XmlElement; import de.timroes.axmlrpc.xmlcreator.XmlElement;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -60,54 +59,29 @@ public class SerializerHandler {
public static final String TYPE_BASE64 = "base64"; public static final String TYPE_BASE64 = "base64";
public static final String TYPE_NULL = "nil"; public static final String TYPE_NULL = "nil";
private static SerializerHandler instance;
/**
* Initialize the serialization handler. This method must be called before
* the get method returns any object.
*
* @param flags The flags that has been set in the XMLRPCClient.
* @see XMLRPCClient
*/
public static void initialize(int flags) {
instance = new SerializerHandler(flags);
}
/**
* Return the instance of the SerializerHandler.
* It must have been initialized with initialize() before.
*
* @return The instance of the SerializerHandler.
*/
public static SerializerHandler getDefault() {
if(instance == null) {
throw new XMLRPCRuntimeException("The SerializerHandler has not been initialized.");
}
return instance;
}
private StringSerializer string; private StringSerializer string;
private BooleanSerializer bool = new BooleanSerializer(); private BooleanSerializer bool = new BooleanSerializer();
private IntSerializer integer = new IntSerializer(); private IntSerializer integer = new IntSerializer();
private LongSerializer long8 = new LongSerializer(); private LongSerializer long8 = new LongSerializer();
private StructSerializer struct = new StructSerializer(); private StructSerializer struct;
private DoubleSerializer floating = new DoubleSerializer(); private DoubleSerializer floating = new DoubleSerializer();
private DateTimeSerializer datetime = new DateTimeSerializer(); private DateTimeSerializer datetime;
private ArraySerializer array = new ArraySerializer(); public static boolean accepts_null_input;
public SerializerHandler(boolean accepts_null_input) {
SerializerHandler.accepts_null_input = accepts_null_input;
}
private ArraySerializer array;
private Base64Serializer base64 = new Base64Serializer(); private Base64Serializer base64 = new Base64Serializer();
private NullSerializer nil = new NullSerializer(); private NullSerializer nil = new NullSerializer();
private int flags; private int flags;
/** public SerializerHandler(int flags) {
* Generates the SerializerHandler.
* This method can only called from within the class (the initialize method).
*
* @param flags The flags to use.
*/
private SerializerHandler(int flags) {
this.flags = flags; this.flags = flags;
string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0); string = new StringSerializer((flags & XMLRPCClient.FLAGS_NO_STRING_ENCODE) == 0);
struct = new StructSerializer(this);
array = new ArraySerializer(this);
datetime = new DateTimeSerializer((flags & XMLRPCClient.FLAGS_ACCEPT_NULL_DATES) != 0);
} }
/** /**
@ -152,8 +126,12 @@ public class SerializerHandler {
obj = parser.nextText(); obj = parser.nextText();
} else } else
if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) { if (typeNodeName.equals(TYPE_DATE_TIME_ISO8601)) {
dateFormat.setCalendar(cal); dateFormat.setCalendar(cal);
String value = parser.nextText(); String value = parser.nextText();
if (accepts_null_input && (value==null || value.trim().length()==0)) {
return null;
}
try { try {
obj = dateFormat.parseObject(value); obj = dateFormat.parseObject(value);
} catch (ParseException e) { } catch (ParseException e) {
@ -232,7 +210,7 @@ public class SerializerHandler {
*/ */
public XmlElement serialize(Object object) throws XMLRPCException { public XmlElement serialize(Object object) throws XMLRPCException {
Serializer s = null; Serializer s;
if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) { if((flags & XMLRPCClient.FLAGS_NIL) != 0 && object == null) {
s = nil; s = nil;
@ -277,7 +255,7 @@ public class SerializerHandler {
s = base64; s = base64;
} else if(object instanceof Byte[]) { } else if(object instanceof Byte[]) {
s = base64; s = base64;
} else if(object instanceof Iterable<?>) { } else if(object instanceof Iterable<?> || object instanceof Object[]) {
s = array; s = array;
} else { } else {
throw new XMLRPCException("No serializer found for type '" throw new XMLRPCException("No serializer found for type '"
@ -288,4 +266,4 @@ public class SerializerHandler {
} }
} }

7
app/src/main/java/de/timroes/axmlrpc/serializer/StringSerializer.java

@ -19,9 +19,12 @@ public class StringSerializer implements Serializer {
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
String content = object.toString(); String content = object.toString();
if(encodeStrings) { if(encodeStrings) {
content = content.replaceAll("&", "&amp;").replaceAll("<", "&lt;"); content = content
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll("]]>", "]]&gt;");
} }
return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content); return XMLUtil.makeXmlTag(SerializerHandler.TYPE_STRING, content);
} }
} }

10
app/src/main/java/de/timroes/axmlrpc/serializer/StructSerializer.java

@ -15,6 +15,12 @@ public class StructSerializer implements Serializer {
private static final String STRUCT_NAME = "name"; private static final String STRUCT_NAME = "name";
private static final String STRUCT_VALUE = "value"; private static final String STRUCT_VALUE = "value";
private final SerializerHandler serializerHandler;
public StructSerializer(SerializerHandler serializerHandler) {
this.serializerHandler = serializerHandler;
}
public XmlElement serialize(Object object) { public XmlElement serialize(Object object) {
XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT); XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT);
@ -33,7 +39,7 @@ public class StructSerializer implements Serializer {
name = new XmlElement(STRUCT_NAME); name = new XmlElement(STRUCT_NAME);
value = new XmlElement(STRUCT_VALUE); value = new XmlElement(STRUCT_VALUE);
name.setContent(member.getKey()); name.setContent(member.getKey());
value.addChildren(SerializerHandler.getDefault().serialize(member.getValue())); value.addChildren(serializerHandler.serialize(member.getValue()));
entry.addChildren(name); entry.addChildren(name);
entry.addChildren(value); entry.addChildren(value);
struct.addChildren(entry); struct.addChildren(entry);
@ -46,4 +52,4 @@ public class StructSerializer implements Serializer {
return struct; return struct;
} }
} }

12
app/src/main/java/de/timroes/base64/Base64.java

@ -14,6 +14,8 @@ public class Base64 {
private static final HashMap<Character,Byte> map = new HashMap<Character, Byte>(); private static final HashMap<Character,Byte> map = new HashMap<Character, Byte>();
private Base64() {}
static { static {
for(int i = 0; i < code.length; i++) { for(int i = 0; i < code.length; i++) {
map.put(code[i], (byte)i); map.put(code[i], (byte)i);
@ -44,10 +46,10 @@ public class Base64 {
int outi = 0; int outi = 0;
int b1, b2, b3, b4; int b1, b2, b3, b4;
for(int i = 0; i < input.length; i+=4) { for(int i = 0; i < input.length; i+=4) {
b1 = (map.get(input[i]) - 1); b1 = map.get(input[i]) - 1;
b2 = (map.get(input[i+1]) - 1); b2 = map.get(input[i+1]) - 1;
b3 = (map.get(input[i+2]) - 1); b3 = map.get(input[i+2]) - 1;
b4 = (map.get(input[i+3]) - 1); b4 = map.get(input[i+3]) - 1;
out[outi++] = (byte)(b1 << 2 | b2 >>> 4); out[outi++] = (byte)(b1 << 2 | b2 >>> 4);
out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2); out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2);
out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F)); out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F));
@ -158,4 +160,4 @@ public class Base64 {
return out; return out;
} }
} }

141
app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -28,101 +30,102 @@ import android.graphics.drawable.Drawable;
* This drawable that draws a simple white and gray chessboard pattern. * This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a * It's pattern you will often see as a background behind a
* partly transparent image in many applications. * partly transparent image in many applications.
*
* @author Daniel Nilsson * @author Daniel Nilsson
*/ */
public class AlphaPatternDrawable extends Drawable { public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10; private int mRectangleSize = 10;
private Paint mPaint = new Paint(); private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint(); private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint(); private Paint mPaintGray = new Paint();
private int numRectanglesHorizontal; private int numRectanglesHorizontal;
private int numRectanglesVertical; private int numRectanglesVertical;
/** /**
* Bitmap in which the pattern will be cahched. * Bitmap in which the pattern will be cahched.
*/ */
private Bitmap mBitmap; private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) { public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize; mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff); mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb); mPaintGray.setColor(0xffcbcbcb);
} }
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint); canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
} }
@Override @Override
public int getOpacity() { public int getOpacity() {
return 0; return 0;
} }
@Override @Override
public void setAlpha(int alpha) { public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable."); throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
} }
@Override @Override
public void setColorFilter(ColorFilter cf) { public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable."); throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
} }
@Override @Override
protected void onBoundsChange(Rect bounds) { protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds); super.onBoundsChange(bounds);
int height = bounds.height(); int height = bounds.height();
int width = bounds.width(); int width = bounds.width();
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize)); numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize); numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
generatePatternBitmap(); generatePatternBitmap();
} }
/** /**
* This will generate a bitmap with the pattern * This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on. * as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to * We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it * recreate it each time draw() is called since it
* takes a few milliseconds. * takes a few milliseconds.
*/ */
private void generatePatternBitmap() { private void generatePatternBitmap() {
if (getBounds().width() <= 0 || getBounds().height() <= 0) { if (getBounds().width() <= 0 || getBounds().height() <= 0) {
return; return;
} }
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888); mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap); Canvas canvas = new Canvas(mBitmap);
Rect r = new Rect(); Rect r = new Rect();
boolean verticalStartWhite = true; boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) { for (int i = 0; i <= numRectanglesVertical; i++) {
boolean isWhite = verticalStartWhite; boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) { for (int j = 0; j <= numRectanglesHorizontal; j++) {
r.top = i * mRectangleSize; r.top = i * mRectangleSize;
r.left = j * mRectangleSize; r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize; r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize; r.right = r.left + mRectangleSize;
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray); canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
isWhite = !isWhite; isWhite = !isWhite;
} }
verticalStartWhite = !verticalStartWhite; verticalStartWhite = !verticalStartWhite;
} }
} }
} }

321
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java

@ -14,123 +14,240 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.os.Bundle; import android.os.Bundle;
import android.text.InputFilter;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import org.transdroid.R; import androidx.appcompat.app.AppCompatDialog;
public class ColorPickerDialog extends Dialog implements ColorPickerView.OnColorChangedListener, View.OnClickListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private OnColorChangedListener mListener;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor) {
super(context);
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) { import org.transdroid.R;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
setContentView(layout);
setTitle(R.string.dialog_color_picker);
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent())
.setPadding(Math.round(mColorPicker.getDrawingOffset()), 0, Math.round(mColorPicker.getDrawingOffset()),
0);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color); import java.util.Locale;
public class ColorPickerDialog
extends
AppCompatDialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private EditText mHexVal;
private boolean mHexValueEnabled = false;
private ColorStateList mHexDefaultTextColor;
private OnColorChangedListener mListener;
private int mOrientation;
private View mLayout;
private String mTitle;
@Override
public void onGlobalLayout() {
if (getContext().getResources().getConfiguration().orientation != mOrientation) {
final int oldcolor = mOldColor.getColor();
final int newcolor = mNewColor.getColor();
mLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
setUp(oldcolor);
mNewColor.setColor(newcolor);
mColorPicker.setColor(newcolor);
}
}
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor, String title) {
super(context);
mTitle = title;
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mLayout = inflater.inflate(R.layout.dialog_color_picker, null);
mLayout.getViewTreeObserver().addOnGlobalLayoutListener(this);
mOrientation = getContext().getResources().getConfiguration().orientation;
setContentView(mLayout);
setTitle(mTitle);
mColorPicker = (ColorPickerView) mLayout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) mLayout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) mLayout.findViewById(R.id.new_color_panel);
mHexVal = (EditText) mLayout.findViewById(R.id.hex_val);
mHexVal.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
mHexDefaultTextColor = mHexVal.getTextColors();
mHexVal.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
String s = mHexVal.getText().toString();
if (s.length() > 5 || s.length() < 10) {
try {
int c = ColorPickerPreference.convertToColorInt(s.toString());
mColorPicker.setColor(c, true);
mHexVal.setTextColor(mHexDefaultTextColor);
} catch (IllegalArgumentException e) {
mHexVal.setTextColor(Color.RED);
}
} else {
mHexVal.setTextColor(Color.RED);
}
return true;
}
return false;
}
});
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
if (mHexValueEnabled)
updateHexValue(color);
/* /*
if (mListener != null) { if (mListener != null) {
mListener.onColorChanged(color); mListener.onColorChanged(color);
} }
*/ */
} }
public void setAlphaSliderVisible(boolean visible) { public void setHexValueEnabled(boolean enable) {
mColorPicker.setAlphaSliderVisible(visible); mHexValueEnabled = enable;
} if (enable) {
mHexVal.setVisibility(View.VISIBLE);
/** updateHexLengthFilter();
* Set a OnColorChangedListener to get notified when the color updateHexValue(getColor());
* selected by the user has changed. } else
* @param listener mHexVal.setVisibility(View.GONE);
*/ }
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener; public boolean getHexValueEnabled() {
} return mHexValueEnabled;
}
public int getColor() {
return mColorPicker.getColor(); private void updateHexLengthFilter() {
} if (getAlphaSliderVisible())
mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(9)});
@Override else
public void onClick(View v) { mHexVal.setFilters(new InputFilter[]{new InputFilter.LengthFilter(7)});
if (v.getId() == R.id.new_color_panel) { }
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor()); private void updateHexValue(int color) {
} if (getAlphaSliderVisible()) {
} mHexVal.setText(ColorPickerPreference.convertToARGB(color).toUpperCase(Locale.getDefault()));
dismiss(); } else {
} mHexVal.setText(ColorPickerPreference.convertToRGB(color).toUpperCase(Locale.getDefault()));
}
@Override mHexVal.setTextColor(mHexDefaultTextColor);
public Bundle onSaveInstanceState() { }
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor()); public void setAlphaSliderVisible(boolean visible) {
state.putInt("new_color", mNewColor.getColor()); mColorPicker.setAlphaSliderVisible(visible);
return state; if (mHexValueEnabled) {
} updateHexLengthFilter();
updateHexValue(getColor());
@Override }
public void onRestoreInstanceState(Bundle savedInstanceState) { }
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color")); public boolean getAlphaSliderVisible() {
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true); return mColorPicker.getAlphaSliderVisible();
} }
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
*
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener) {
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
} }

210
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.content.Context; import android.content.Context;
@ -27,140 +29,148 @@ import android.view.View;
* This class draws a panel which which will be filled with a color which can be set. * This class draws a panel which which will be filled with a color which can be set.
* It can be used to show the currently selected color which you will get from * It can be used to show the currently selected color which you will get from
* the {@link ColorPickerView}. * the {@link ColorPickerView}.
*
* @author Daniel Nilsson * @author Daniel Nilsson
*/ */
public class ColorPickerPanelView extends View { public class ColorPickerPanelView extends View {
/** /**
* The width in pixels of the border * The width in pixels of the border
* surrounding the color panel. * surrounding the color panel.
*/ */
private final static float BORDER_WIDTH_PX = 1; private final static float BORDER_WIDTH_PX = 1;
private float mDensity = 1f;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
private Paint mBorderPaint; private float mDensity = 1f;
private Paint mColorPaint;
private RectF mDrawingRect; private int mBorderColor = 0xff6E6E6E;
private RectF mColorRect; private int mColor = 0xff000000;
private AlphaPatternDrawable mAlphaPattern; private Paint mBorderPaint;
private Paint mColorPaint;
private RectF mDrawingRect;
private RectF mColorRect;
public ColorPickerPanelView(Context context) { private AlphaPatternDrawable mAlphaPattern;
this(context, null);
}
public ColorPickerPanelView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) { public ColorPickerPanelView(Context context) {
super(context, attrs, defStyle); this(context, null);
init(); }
}
private void init() { public ColorPickerPanelView(Context context, AttributeSet attrs) {
mBorderPaint = new Paint(); this(context, attrs, 0);
mColorPaint = new Paint(); }
mDensity = getContext().getResources().getDisplayMetrics().density;
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override private void init() {
protected void onDraw(Canvas canvas) { mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
final RectF rect = mColorRect;
if (BORDER_WIDTH_PX > 0) { @Override
mBorderPaint.setColor(mBorderColor); protected void onDraw(Canvas canvas) {
canvas.drawRect(mDrawingRect, mBorderPaint);
}
if (mAlphaPattern != null) { final RectF rect = mColorRect;
mAlphaPattern.draw(canvas);
}
mColorPaint.setColor(mColor); if (BORDER_WIDTH_PX > 0) {
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
canvas.drawRect(rect, mColorPaint); if (mAlphaPattern != null) {
} mAlphaPattern.draw(canvas);
}
@Override mColorPaint.setColor(mColor);
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec); canvas.drawRect(rect, mColorPaint);
int height = MeasureSpec.getSize(heightMeasureSpec); }
setMeasuredDimension(width, height); @Override
} protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@Override int width = MeasureSpec.getSize(widthMeasureSpec);
protected void onSizeChanged(int w, int h, int oldw, int oldh) { int height = MeasureSpec.getSize(heightMeasureSpec);
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF(); setMeasuredDimension(width, height);
mDrawingRect.left = getPaddingLeft(); }
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
setUpColorRect(); @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
} mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
private void setUpColorRect() { setUpColorRect();
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX; }
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mColorRect = new RectF(left, top, right, bottom); private void setUpColorRect() {
final RectF dRect = mDrawingRect;
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity)); float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mAlphaPattern.setBounds(Math.round(mColorRect.left), Math.round(mColorRect.top), Math.round(mColorRect.right), mColorRect = new RectF(left, top, right, bottom);
Math.round(mColorRect.bottom));
} mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
/** mAlphaPattern.setBounds(
* Set the color that should be shown by this view. Math.round(mColorRect.left),
* @param color Math.round(mColorRect.top),
*/ Math.round(mColorRect.right),
public void setColor(int color) { Math.round(mColorRect.bottom)
mColor = color; );
invalidate();
}
/** }
* Get the color currently show by this view.
* @return
*/
public int getColor() {
return mColor;
}
/** /**
* Set the color of the border surrounding the panel. * Set the color that should be shown by this view.
* @param color *
*/ * @param color
public void setBorderColor(int color) { */
mBorderColor = color; public void setColor(int color) {
invalidate(); mColor = color;
} invalidate();
}
/** /**
* Get the color of the border surrounding the panel. * Get the color currently show by this view.
*/ *
public int getBorderColor() { * @return
return mBorderColor; */
} public int getColor() {
return mColor;
}
/**
* Set the color of the border surrounding the panel.
*
* @param color
*/
public void setBorderColor(int color) {
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor() {
return mBorderColor;
}
} }

551
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
package net.margaritov.preference.colorpicker; package net.margaritov.preference.colorpicker;
import android.content.Context; import android.content.Context;
@ -24,259 +26,312 @@ import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
/** /**
* A preference type that allows a user to choose a time * A preference type that allows a user to choose a color
*
* @author Sergey Margaritov * @author Sergey Margaritov
*/ */
public class ColorPickerPreference extends Preference public class ColorPickerPreference
implements Preference.OnPreferenceClickListener, ColorPickerDialog.OnColorChangedListener { extends
Preference
View mView; implements
ColorPickerDialog mDialog; Preference.OnPreferenceClickListener,
private int mValue = Color.BLACK; ColorPickerDialog.OnColorChangedListener {
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false; View mView;
ColorPickerDialog mDialog;
public ColorPickerPreference(Context context) { private int mValue = Color.BLACK;
super(context); private float mDensity = 0;
init(context, null); private boolean mAlphaSliderEnabled = false;
} private boolean mHexValueEnabled = false;
public ColorPickerPreference(Context context, AttributeSet attrs) { public ColorPickerPreference(Context context) {
super(context, attrs); super(context);
init(context, attrs); init(context, null);
} }
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) { public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs, defStyle); super(context, attrs);
init(context, attrs); init(context, attrs);
} }
@Override public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
protected Object onGetDefaultValue(TypedArray a, int index) { super(context, attrs, defStyle);
return a.getColor(index, Color.BLACK); init(context, attrs);
} }
@Override /**Method edited by
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { * @author Anna Berkovitch
onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue); * added functionality to accept hex string as defaultValue
} * and to properly persist resources reference string, such as @color/someColor
* previously persisted 0*/
private void init(Context context, AttributeSet attrs) { @Override
mDensity = getContext().getResources().getDisplayMetrics().density; protected Object onGetDefaultValue(TypedArray a, int index) {
setOnPreferenceClickListener(this); int colorInt;
if (attrs != null) { String mHexDefaultValue = a.getString(index);
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false); if (mHexDefaultValue != null && mHexDefaultValue.startsWith("#")) {
} colorInt = convertToColorInt(mHexDefaultValue);
} return colorInt;
@Override } else {
protected void onBindView(View view) { return a.getColor(index, Color.BLACK);
super.onBindView(view); }
mView = view; }
setPreviewColor();
} @Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
private void setPreviewColor() { onColorChanged(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
if (mView == null) { }
return;
} private void init(Context context, AttributeSet attrs) {
ImageView iView = new ImageView(getContext()); mDensity = getContext().getResources().getDisplayMetrics().density;
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame)); setOnPreferenceClickListener(this);
if (widgetFrameView == null) { if (attrs != null) {
return; mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
} mHexValueEnabled = attrs.getAttributeBooleanValue(null, "hexValue", false);
widgetFrameView.setVisibility(View.VISIBLE); }
widgetFrameView }
.setPadding(widgetFrameView.getPaddingLeft(), widgetFrameView.getPaddingTop(), (int) (mDensity * 8),
widgetFrameView.getPaddingBottom()); @Override
// remove already create preview image public void onBindViewHolder(PreferenceViewHolder holder) {
int count = widgetFrameView.getChildCount(); super.onBindViewHolder(holder);
if (count > 0) {
widgetFrameView.removeViews(0, count); mView = holder.itemView;
} setPreviewColor();
widgetFrameView.addView(iView); }
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity))); private void setPreviewColor() {
iView.setImageBitmap(getPreviewBitmap()); if (mView == null) return;
} ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout) mView.findViewById(android.R.id.widget_frame));
private Bitmap getPreviewBitmap() { if (widgetFrameView == null) return;
int d = (int) (mDensity * 31); //30dip widgetFrameView.setVisibility(View.VISIBLE);
int color = mValue; widgetFrameView.setPadding(
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888); widgetFrameView.getPaddingLeft(),
int w = bm.getWidth(); widgetFrameView.getPaddingTop(),
int h = bm.getHeight(); (int) (mDensity * 8),
int c = color; widgetFrameView.getPaddingBottom()
for (int i = 0; i < w; i++) { );
for (int j = i; j < h; j++) { // remove already create preview image
c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color; int count = widgetFrameView.getChildCount();
bm.setPixel(i, j, c); if (count > 0) {
if (i != j) { widgetFrameView.removeViews(0, count);
bm.setPixel(j, i, c); }
} widgetFrameView.addView(iView);
} widgetFrameView.setMinimumWidth(0);
} iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
return bm; }
}
private Bitmap getPreviewBitmap() {
@Override int d = (int) (mDensity * 31); //30dip
public void onColorChanged(int color) { int color = mValue;
if (isPersistent()) { Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
persistInt(color); int w = bm.getWidth();
} int h = bm.getHeight();
mValue = color; int c = color;
setPreviewColor(); for (int i = 0; i < w; i++) {
try { for (int j = i; j < h; j++) {
getOnPreferenceChangeListener().onPreferenceChange(this, color); c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color;
} catch (NullPointerException e) { bm.setPixel(i, j, c);
if (i != j) {
} bm.setPixel(j, i, c);
} }
}
public boolean onPreferenceClick(Preference preference) { }
showDialog(null);
return false; return bm;
} }
protected void showDialog(Bundle state) { @Override
mDialog = new ColorPickerDialog(getContext(), mValue); public void onColorChanged(int color) {
mDialog.setOnColorChangedListener(this); if (isPersistent()) {
if (mAlphaSliderEnabled) { persistInt(color);
mDialog.setAlphaSliderVisible(true); }
} mValue = color;
if (state != null) { setPreviewColor();
mDialog.onRestoreInstanceState(state); try {
} getOnPreferenceChangeListener().onPreferenceChange(this, color);
mDialog.show(); } catch (NullPointerException e) {
}
}
/** }
* Toggle Alpha Slider visibility (by default it's disabled)
* @param enable public boolean onPreferenceClick(Preference preference) {
*/ showDialog(null);
public void setAlphaSliderEnabled(boolean enable) { return false;
mAlphaSliderEnabled = enable; }
}
protected void showDialog(Bundle state) {
/** mDialog = new ColorPickerDialog(getContext(), mValue, getTitle().toString());
* For custom purposes. Not used by ColorPickerPreferrence mDialog.setOnColorChangedListener(this);
* @param color if (mAlphaSliderEnabled) {
* @author Unknown mDialog.setAlphaSliderVisible(true);
*/ }
public static String convertToARGB(int color) { if (mHexValueEnabled) {
String alpha = Integer.toHexString(Color.alpha(color)); mDialog.setHexValueEnabled(true);
String red = Integer.toHexString(Color.red(color)); }
String green = Integer.toHexString(Color.green(color)); if (state != null) {
String blue = Integer.toHexString(Color.blue(color)); mDialog.onRestoreInstanceState(state);
}
if (alpha.length() == 1) { mDialog.show();
alpha = "0" + alpha; }
}
/**
if (red.length() == 1) { * Toggle Alpha Slider visibility (by default it's disabled)
red = "0" + red; *
} * @param enable
*/
if (green.length() == 1) { public void setAlphaSliderEnabled(boolean enable) {
green = "0" + green; mAlphaSliderEnabled = enable;
} }
if (blue.length() == 1) { /**
blue = "0" + blue; * Toggle Hex Value visibility (by default it's disabled)
} *
* @param enable
return "#" + alpha + red + green + blue; */
} public void setHexValueEnabled(boolean enable) {
mHexValueEnabled = enable;
/** }
* For custom purposes. Not used by ColorPickerPreferrence
* @param argb /**
* @throws NumberFormatException * For custom purposes. Not used by ColorPickerPreferrence
* @author Unknown *
*/ * @param color
public static int convertToColorInt(String argb) throws NumberFormatException { * @author Unknown
*/
if (argb.startsWith("#")) { public static String convertToARGB(int color) {
argb = argb.replace("#", ""); String alpha = Integer.toHexString(Color.alpha(color));
} String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
int alpha = -1, red = -1, green = -1, blue = -1; String blue = Integer.toHexString(Color.blue(color));
if (argb.length() == 8) { if (alpha.length() == 1) {
alpha = Integer.parseInt(argb.substring(0, 2), 16); alpha = "0" + alpha;
red = Integer.parseInt(argb.substring(2, 4), 16); }
green = Integer.parseInt(argb.substring(4, 6), 16);
blue = Integer.parseInt(argb.substring(6, 8), 16); if (red.length() == 1) {
} else if (argb.length() == 6) { red = "0" + red;
alpha = 255; }
red = Integer.parseInt(argb.substring(0, 2), 16);
green = Integer.parseInt(argb.substring(2, 4), 16); if (green.length() == 1) {
blue = Integer.parseInt(argb.substring(4, 6), 16); green = "0" + green;
} }
return Color.argb(alpha, red, green, blue); if (blue.length() == 1) {
} blue = "0" + blue;
}
@Override
protected Parcelable onSaveInstanceState() { return "#" + alpha + red + green + blue;
final Parcelable superState = super.onSaveInstanceState(); }
if (mDialog == null || !mDialog.isShowing()) {
return superState; /**
} * Method currently used by onGetDefaultValue method to
* convert hex string provided in android:defaultValue to color integer.
final SavedState myState = new SavedState(superState); *
myState.dialogBundle = mDialog.onSaveInstanceState(); * @param color
return myState; * @return A string representing the hex value of color,
} * without the alpha value
* @author Charles Rosaaen
@Override */
protected void onRestoreInstanceState(Parcelable state) { public static String convertToRGB(int color) {
if (state == null || !(state instanceof SavedState)) { String red = Integer.toHexString(Color.red(color));
// Didn't save state for us in onSaveInstanceState String green = Integer.toHexString(Color.green(color));
super.onRestoreInstanceState(state); String blue = Integer.toHexString(Color.blue(color));
return;
} if (red.length() == 1) {
red = "0" + red;
SavedState myState = (SavedState) state; }
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle); if (green.length() == 1) {
} green = "0" + green;
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle; if (blue.length() == 1) {
blue = "0" + blue;
public SavedState(Parcel source) { }
super(source);
dialogBundle = source.readBundle(); return "#" + red + green + blue;
} }
@Override /**
public void writeToParcel(Parcel dest, int flags) { * For custom purposes. Not used by ColorPickerPreferrence
super.writeToParcel(dest, flags); *
dest.writeBundle(dialogBundle); * @param argb
} * @throws NumberFormatException
* @author Unknown
public SavedState(Parcelable superState) { */
super(superState); public static int convertToColorInt(String argb) throws IllegalArgumentException {
}
if (!argb.startsWith("#")) {
@SuppressWarnings("unused") argb = "#" + argb;
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { }
public SavedState createFromParcel(Parcel in) {
return new SavedState(in); return Color.parseColor(argb);
} }
public SavedState[] newArray(int size) { @Override
return new SavedState[size]; protected Parcelable onSaveInstanceState() {
} final Parcelable superState = super.onSaveInstanceState();
}; if (mDialog == null || !mDialog.isShowing()) {
} return superState;
} }
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

1357
app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java

File diff suppressed because it is too large Load Diff

65
app/src/main/java/org/apache/openjpa/lib/util/Base16Encoder.java

@ -1,65 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.openjpa.lib.util;
/**
* Base 16 encoder.
*
* @author Marc Prud'hommeaux
* @nojavadoc
*/
public class Base16Encoder {
private final static char[] HEX = new char[]{
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* Convert bytes to a base16 string.
*/
public static String encode(byte[] byteArray) {
StringBuffer hexBuffer = new StringBuffer(byteArray.length * 2);
for (int i = 0; i < byteArray.length; i++)
for (int j = 1; j >= 0; j--)
hexBuffer.append(HEX[(byteArray[i] >> (j * 4)) & 0xF]);
return hexBuffer.toString();
}
/**
* Convert a base16 string into a byte array.
*/
public static byte[] decode(String s) {
int len = s.length();
byte[] r = new byte[len / 2];
for (int i = 0; i < r.length; i++) {
int digit1 = s.charAt(i * 2), digit2 = s.charAt(i * 2 + 1);
if (digit1 >= '0' && digit1 <= '9')
digit1 -= '0';
else if (digit1 >= 'A' && digit1 <= 'F')
digit1 -= 'A' - 10;
if (digit2 >= '0' && digit2 <= '9')
digit2 -= '0';
else if (digit2 >= 'A' && digit2 <= 'F')
digit2 -= 'A' - 10;
r[i] = (byte) ((digit1 << 4) + digit2);
}
return r;
}
}

1998
app/src/main/java/org/base64/android/Base64.java

File diff suppressed because it is too large Load Diff

4
app/src/main/java/org/transdroid/core/app/settings/SettingsUtils.java

@ -2,8 +2,8 @@ package org.transdroid.core.app.settings;
import android.content.Context; import android.content.Context;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.Theme; import com.afollestad.materialdialogs.Theme;

4
app/src/main/java/org/transdroid/core/gui/DetailsActivity.java

@ -20,8 +20,8 @@ import android.annotation.TargetApi;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.Snackbar;
import com.nispok.snackbar.SnackbarManager; import com.nispok.snackbar.SnackbarManager;

6
app/src/main/java/org/transdroid/core/gui/DetailsFragment.java

@ -23,9 +23,9 @@ import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.v4.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView; import androidx.appcompat.widget.ActionMenuView;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;

4
app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java

@ -16,8 +16,8 @@
*/ */
package org.transdroid.core.gui; package org.transdroid.core.gui;
import android.support.v7.widget.ActionMenuView; import androidx.appcompat.widget.ActionMenuView;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import org.transdroid.daemon.Priority; import org.transdroid.daemon.Priority;
import org.transdroid.daemon.Torrent; import org.transdroid.daemon.Torrent;

16
app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java

@ -24,14 +24,14 @@ import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v4.view.MenuItemCompat; import androidx.core.view.MenuItemCompat;
import android.support.v4.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView; import androidx.appcompat.widget.ActionMenuView;
import android.support.v7.widget.SearchView; import androidx.appcompat.widget.SearchView;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;

8
app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java

@ -18,10 +18,10 @@ package org.transdroid.core.gui;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.ActionMenuView; import androidx.appcompat.widget.ActionMenuView;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;

4
app/src/main/java/org/transdroid/core/gui/TransdroidApp.java

@ -17,8 +17,8 @@
package org.transdroid.core.gui; package org.transdroid.core.gui;
import android.app.Application; import android.app.Application;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.evernote.android.job.JobConfig; import com.evernote.android.job.JobConfig;
import com.evernote.android.job.JobManager; import com.evernote.android.job.JobManager;
import com.evernote.android.job.util.JobLogger; import com.evernote.android.job.util.JobLogger;

2
app/src/main/java/org/transdroid/core/gui/log/DatabaseHelper.java

@ -20,7 +20,7 @@ import java.sql.SQLException;
import android.content.Context; import android.content.Context;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Keep; import androidx.annotation.Keep;
import android.util.Log; import android.util.Log;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;

6
app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java

@ -26,9 +26,9 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v4.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.TypefaceSpan; import android.text.style.TypefaceSpan;

2
app/src/main/java/org/transdroid/core/gui/remoterss/RemoteRssFragment.java

@ -17,7 +17,7 @@
package org.transdroid.core.gui.remoterss; package org.transdroid.core.gui.remoterss;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;

14
app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java

@ -22,13 +22,13 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.design.widget.TabLayout; import com.google.android.material.tabs.TabLayout;
import android.support.v4.view.PagerAdapter; import androidx.viewpager.widget.PagerAdapter;
import android.support.v4.view.ViewPager; import androidx.viewpager.widget.ViewPager;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

2
app/src/main/java/org/transdroid/core/gui/rss/RssFeedsFragment.java

@ -16,7 +16,7 @@
*/ */
package org.transdroid.core.gui.rss; package org.transdroid.core.gui.rss;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;

4
app/src/main/java/org/transdroid/core/gui/rss/RssItemsActivity.java

@ -20,8 +20,8 @@ import android.annotation.TargetApi;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.EActivity;

4
app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java

@ -23,8 +23,8 @@ import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Menu; import android.view.Menu;

6
app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java

@ -23,9 +23,9 @@ import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.SearchRecentSuggestions; import android.provider.SearchRecentSuggestions;
import android.support.v4.view.MenuItemCompat; import androidx.core.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;

2
app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java

@ -20,7 +20,7 @@ import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Menu; import android.view.Menu;

2
app/src/main/java/org/transdroid/core/gui/settings/InterceptableEditTextPreference.java

@ -3,7 +3,7 @@ package org.transdroid.core.gui.settings;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.support.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import android.util.AttributeSet; import android.util.AttributeSet;
public class InterceptableEditTextPreference extends EditTextPreference { public class InterceptableEditTextPreference extends EditTextPreference {

10
app/src/main/java/org/transdroid/core/gui/settings/PreferenceCompatActivity.java

@ -3,11 +3,11 @@ package org.transdroid.core.gui.settings;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v7.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.support.v7.app.AppCompatCallback; import androidx.appcompat.app.AppCompatCallback;
import android.support.v7.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import android.support.v7.view.ActionMode; import androidx.appcompat.view.ActionMode;
public class PreferenceCompatActivity extends PreferenceActivity implements AppCompatCallback { public class PreferenceCompatActivity extends PreferenceActivity implements AppCompatCallback {

2
app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java

@ -28,7 +28,7 @@ import android.os.Bundle;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.OptionsItem;

2
app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java

@ -28,7 +28,7 @@ import android.os.Bundle;
import android.preference.Preference; import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener; import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.Snackbar;

2
app/src/main/java/org/transdroid/core/service/AppUpdateJob.java

@ -17,7 +17,7 @@
package org.transdroid.core.service; package org.transdroid.core.service;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager; import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest; import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java

@ -23,7 +23,7 @@ import android.content.Intent;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;

6
app/src/main/java/org/transdroid/core/service/ConnectivityHelper.java

@ -23,9 +23,9 @@ import android.content.DialogInterface;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.support.v4.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import android.support.v7.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.EBean.Scope; import org.androidannotations.annotations.EBean.Scope;
import org.androidannotations.annotations.SystemService; import org.androidannotations.annotations.SystemService;

2
app/src/main/java/org/transdroid/core/service/RssCheckerJob.java

@ -17,7 +17,7 @@
package org.transdroid.core.service; package org.transdroid.core.service;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager; import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest; import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java

@ -20,7 +20,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;

4
app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java

@ -16,8 +16,8 @@
*/ */
package org.transdroid.core.service; package org.transdroid.core.service;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator; import com.evernote.android.job.JobCreator;

2
app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java

@ -17,7 +17,7 @@
package org.transdroid.core.service; package org.transdroid.core.service;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import com.evernote.android.job.JobManager; import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest; import com.evernote.android.job.JobRequest;

2
app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java

@ -20,7 +20,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import android.text.TextUtils; import android.text.TextUtils;
import com.evernote.android.job.Job; import com.evernote.android.job.Job;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;

4
app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java

@ -22,8 +22,8 @@ import android.appwidget.AppWidgetManager;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.CheckBox; import android.widget.CheckBox;

2
app/src/main/java/org/transdroid/core/widget/ListWidgetProvider.java

@ -24,7 +24,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;

48
app/src/main/java/org/transdroid/daemon/Aria2c/Aria2Adapter.java

@ -1,19 +1,19 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Aria2c; package org.transdroid.daemon.Aria2c;
@ -25,7 +25,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.base64.android.Base64; import net.iharder.Base64;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -360,27 +360,27 @@ public class Aria2Adapter implements IDaemonAdapter {
} }
// @formatter:off // @formatter:off
torrents.add(new Torrent( torrents.add(new Torrent(
j, j,
tor.getString("gid"), tor.getString("gid"),
name, name,
status, status,
tor.getString("dir"), tor.getString("dir"),
downloadSpeed, downloadSpeed,
tor.getInt("uploadSpeed"), tor.getInt("uploadSpeed"),
tor.getInt("connections"), tor.getInt("connections"),
numSeeders , numSeeders ,
tor.getInt("connections"), tor.getInt("connections"),
numSeeders, numSeeders,
(downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1), (downloadSpeed > 0? (int) (totalLength / downloadSpeed): -1),
completedLength, completedLength,
tor.getLong("uploadLength"), tor.getLong("uploadLength"),
totalLength, totalLength,
completedLength / (float) totalLength, // Percentage to [0..1] completedLength / (float) totalLength, // Percentage to [0..1]
0f, // Not available 0f, // Not available
null, // Not available null, // Not available
null, // Not available null, // Not available
null, // Not available null, // Not available
error, error,
settings.getType())); settings.getType()));
// @formatter:on // @formatter:on
@ -403,12 +403,12 @@ public class Aria2Adapter implements IDaemonAdapter {
} }
// @formatter:off // @formatter:off
files.add(new TorrentFile( files.add(new TorrentFile(
Integer.toString(file.getInt("index")), Integer.toString(file.getInt("index")),
rel, rel,
rel, rel,
file.getString("path"), file.getString("path"),
file.getLong("length"), file.getLong("length"),
file.getLong("completedLength"), file.getLong("completedLength"),
file.getBoolean("selected") ? Priority.Normal : Priority.Off)); file.getBoolean("selected") ? Priority.Normal : Priority.Off));
// @formatter:on // @formatter:on

16
app/src/main/java/org/transdroid/daemon/BitComet/BitCometAdapter.java

@ -1,26 +1,26 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.BitComet; package org.transdroid.daemon.BitComet;
import com.android.internalcopy.http.multipart.BitCometFilePart; import org.transdroid.multipart.BitCometFilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import com.android.internalcopy.http.multipart.Utf8StringPart; import org.transdroid.multipart.Utf8StringPart;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;

28
app/src/main/java/org/transdroid/daemon/BuffaloNas/BuffaloNasAdapter.java

@ -1,25 +1,25 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.BuffaloNas; package org.transdroid.daemon.BuffaloNas;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
@ -108,8 +108,8 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Request to add a torrent by URL // Request to add a torrent by URL
String url = ((AddByUrlTask) task).getUrl(); String url = ((AddByUrlTask) task).getUrl();
// @formatter:off // @formatter:off
makeRequest(log, "/api/torrent-add", makeRequest(log, "/api/torrent-add",
new BasicNameValuePair("url", url), new BasicNameValuePair("url", url),
new BasicNameValuePair("start", "yes")); new BasicNameValuePair("start", "yes"));
// @formatter:on // @formatter:on
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
@ -119,9 +119,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
// Remove a torrent // Remove a torrent
RemoveTask removeTask = (RemoveTask) task; RemoveTask removeTask = (RemoveTask) task;
// @formatter:off // @formatter:off
makeRequest(log, "/api/torrent-remove", makeRequest(log, "/api/torrent-remove",
new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()), new BasicNameValuePair("hash", removeTask.getTargetTorrent().getUniqueID()),
new BasicNameValuePair("delete-torrent", "yes"), new BasicNameValuePair("delete-torrent", "yes"),
new BasicNameValuePair("delete-data", (removeTask.includingData() ? "yes" : "no"))); new BasicNameValuePair("delete-data", (removeTask.includingData() ? "yes" : "no")));
// @formatter:on // @formatter:on
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
@ -149,9 +149,9 @@ public class BuffaloNasAdapter implements IDaemonAdapter {
String ul = Integer.toString( String ul = Integer.toString(
(ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate() * 1024)); (ratesTask.getUploadRate() == null ? -1 : ratesTask.getUploadRate() * 1024));
// @formatter:off // @formatter:off
makeRequest(log, "/api/app-settings-set", makeRequest(log, "/api/app-settings-set",
new BasicNameValuePair("auto_bandwidth_management", "0"), new BasicNameValuePair("auto_bandwidth_management", "0"),
new BasicNameValuePair("max_dl_rate", dl), new BasicNameValuePair("max_dl_rate", dl),
new BasicNameValuePair("max_ul_rate", ul), new BasicNameValuePair("max_ul_rate", ul),
new BasicNameValuePair("max_ul_rate_seed", ul)); new BasicNameValuePair("max_ul_rate_seed", ul));
// @formatter:on // @formatter:on

46
app/src/main/java/org/transdroid/daemon/DLinkRouterBT/DLinkRouterBTAdapter.java

@ -1,25 +1,25 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.DLinkRouterBT; package org.transdroid.daemon.DLinkRouterBT;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
@ -358,23 +358,23 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter {
// @formatter:off // @formatter:off
Torrent new_t = new Torrent( Torrent new_t = new Torrent(
i, i,
tor.getString(BT_HASH), tor.getString(BT_HASH),
tor.getString(BT_CAPTION), tor.getString(BT_CAPTION),
status, status,
null, // Not supported? null, // Not supported?
tor.getInt(BT_DOWNLOAD_RATE), tor.getInt(BT_DOWNLOAD_RATE),
tor.getInt(BT_UPLOAD_RATE), tor.getInt(BT_UPLOAD_RATE),
tor.getInt(BT_PEERS_CONNECTED), tor.getInt(BT_PEERS_CONNECTED),
tor.getInt(BT_PEERS_TOTAL), tor.getInt(BT_PEERS_TOTAL),
tor.getInt(BT_SEEDS_CONNECTED), tor.getInt(BT_SEEDS_CONNECTED),
tor.getInt(BT_SEEDS_TOTAL), tor.getInt(BT_SEEDS_TOTAL),
eta, eta,
tor.getLong(BT_DONE), tor.getLong(BT_DONE),
tor.getLong(BT_PAYLOAD_UPLOAD), tor.getLong(BT_PAYLOAD_UPLOAD),
tor.getLong(BT_SIZE), tor.getLong(BT_SIZE),
tor.getLong(BT_DONE) / (float) tor.getLong(BT_SIZE), tor.getLong(BT_DONE) / (float) tor.getLong(BT_SIZE),
Float.parseFloat(tor.getString(BT_COPYS)), Float.parseFloat(tor.getString(BT_COPYS)),
null, null,
null, null,
null, null,
@ -402,11 +402,11 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter {
// @formatter:off // @formatter:off
torrentfiles.add(new TorrentFile( torrentfiles.add(new TorrentFile(
String.valueOf(i), String.valueOf(i),
file.getString(BT_FILE_NAME), file.getString(BT_FILE_NAME),
file.getString(BT_FILE_NAME), file.getString(BT_FILE_NAME),
null, // Not supported? null, // Not supported?
file.getLong(BT_FILE_SIZE), file.getLong(BT_FILE_SIZE),
file.getLong(BT_FILE_DONE), file.getLong(BT_FILE_DONE),
convertTransmissionPriority(file.getInt(BT_FILE_PRIORITY)))); convertTransmissionPriority(file.getInt(BT_FILE_PRIORITY))));
// @formatter:on // @formatter:on
} }

2
app/src/main/java/org/transdroid/daemon/DaemonException.java

@ -18,7 +18,7 @@
package org.transdroid.daemon; package org.transdroid.daemon;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
/** /**
* An exception thrown when an error occurs inside a server daemon adapter. * An exception thrown when an error occurs inside a server daemon adapter.

8
app/src/main/java/org/transdroid/daemon/Deluge/DelugeAdapter.java

@ -17,9 +17,9 @@
*/ */
package org.transdroid.daemon.Deluge; package org.transdroid.daemon.Deluge;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
@ -418,7 +418,7 @@ public class DelugeAdapter implements IDaemonAdapter {
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString())); return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.FileAccessError, e.toString()));
} }
} }
/*private JSONArray buildSetTorrentOptions(String torrent, String key, String value) throws JSONException { /*private JSONArray buildSetTorrentOptions(String torrent, String key, String value) throws JSONException {
JSONArray params = new JSONArray(); JSONArray params = new JSONArray();
params.put(new JSONArray().put(torrent)); // torrent_id params.put(new JSONArray().put(torrent)); // torrent_id

2
app/src/main/java/org/transdroid/daemon/Deluge/DelugeCommon.java

@ -17,7 +17,7 @@
*/ */
package org.transdroid.daemon.Deluge; package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import org.transdroid.daemon.Priority; import org.transdroid.daemon.Priority;
import org.transdroid.daemon.TorrentStatus; import org.transdroid.daemon.TorrentStatus;

4
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcAdapter.java

@ -17,8 +17,8 @@
*/ */
package org.transdroid.daemon.Deluge; package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import org.base64.android.Base64; import net.iharder.Base64;
import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.remoterss.data.RemoteRssChannel; import org.transdroid.core.gui.remoterss.data.RemoteRssChannel;
import org.transdroid.core.gui.remoterss.data.RemoteRssItem; import org.transdroid.core.gui.remoterss.data.RemoteRssItem;

2
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java

@ -17,7 +17,7 @@
*/ */
package org.transdroid.daemon.Deluge; package org.transdroid.daemon.Deluge;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import org.transdroid.daemon.DaemonException; import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.DaemonException.ExceptionType; import org.transdroid.daemon.DaemonException.ExceptionType;
import org.transdroid.daemon.DaemonSettings; import org.transdroid.daemon.DaemonSettings;

14
app/src/main/java/org/transdroid/daemon/Ktorrent/KtorrentAdapter.java

@ -1,25 +1,25 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Ktorrent; package org.transdroid.daemon.Ktorrent;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;

6
app/src/main/java/org/transdroid/daemon/Qbittorrent/QbittorrentAdapter.java

@ -17,9 +17,9 @@
*/ */
package org.transdroid.daemon.Qbittorrent; package org.transdroid.daemon.Qbittorrent;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;

16
app/src/main/java/org/transdroid/daemon/Synology/SynologyAdapter.java

@ -1,26 +1,26 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Synology; package org.transdroid.daemon.Synology;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import com.android.internalcopy.http.multipart.Utf8StringPart; import org.transdroid.multipart.Utf8StringPart;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;

14
app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java

@ -1,19 +1,19 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Tfb4rt; package org.transdroid.daemon.Tfb4rt;
@ -47,9 +47,9 @@ import org.transdroid.daemon.task.RemoveTask;
import org.transdroid.daemon.task.RetrieveTask; import org.transdroid.daemon.task.RetrieveTask;
import org.transdroid.daemon.task.RetrieveTaskSuccessResult; import org.transdroid.daemon.task.RetrieveTaskSuccessResult;
import org.transdroid.daemon.util.HttpHelper; import org.transdroid.daemon.util.HttpHelper;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
/** /**
* An adapter that allows for easy access to Torrentflux-b4rt installs. Communication is handled via HTTP GET requests * An adapter that allows for easy access to Torrentflux-b4rt installs. Communication is handled via HTTP GET requests

6
app/src/main/java/org/transdroid/daemon/Transmission/TransmissionAdapter.java

@ -22,8 +22,8 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.base64.android.Base64; import net.iharder.Base64;
import org.base64.android.Base64.InputStream; import net.iharder.Base64.InputStream;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -192,7 +192,7 @@ public class TransmissionAdapter implements IDaemonAdapter {
// Encode the .torrent file's data // Encode the .torrent file's data
InputStream in = InputStream in =
new Base64.InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE); new InputStream(new FileInputStream(new File(URI.create(file))), Base64.ENCODE);
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
int c; int c;
while ((c = in.read()) != -1) { while ((c = in.read()) != -1) {

14
app/src/main/java/org/transdroid/daemon/Ttorrent/TtorrentAdapter.java

@ -1,25 +1,25 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Ttorrent; package org.transdroid.daemon.Ttorrent;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;

14
app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java

@ -1,25 +1,25 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Utorrent; package org.transdroid.daemon.Utorrent;
import com.android.internalcopy.http.multipart.FilePart; import com.android.internal.http.multipart.FilePart;
import com.android.internalcopy.http.multipart.MultipartEntity; import com.android.internal.http.multipart.MultipartEntity;
import com.android.internalcopy.http.multipart.Part; import com.android.internal.http.multipart.Part;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;

108
app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java

@ -1,19 +1,19 @@
/* /*
* This file is part of Transdroid <http://www.transdroid.org> * This file is part of Transdroid <http://www.transdroid.org>
* *
* Transdroid is free software: you can redistribute it and/or modify * Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Transdroid is distributed in the hope that it will be useful, * Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. * along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
package org.transdroid.daemon.Vuze; package org.transdroid.daemon.Vuze;
@ -43,7 +43,7 @@ import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams; import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams; import org.apache.http.params.HttpProtocolParams;
import org.base64.android.Base64; import net.iharder.Base64;
import org.transdroid.daemon.DaemonException; import org.transdroid.daemon.DaemonException;
import org.transdroid.daemon.DaemonSettings; import org.transdroid.daemon.DaemonSettings;
import org.transdroid.daemon.DaemonException.ExceptionType; import org.transdroid.daemon.DaemonException.ExceptionType;
@ -56,16 +56,16 @@ import org.xmlpull.v1.XmlSerializer;
import android.util.Xml; import android.util.Xml;
/** /**
* Implements an XML-RPC-like client that build and parses XML following * Implements an XML-RPC-like client that build and parses XML following
* Vuze's XML over HTTP plug-in (which unfortunately is incompatible with * Vuze's XML over HTTP plug-in (which unfortunately is incompatible with
* the default XML-RPC protocol). * the default XML-RPC protocol).
* *
* The documentation can be found at http://azureus.sourceforge.net/plugin_details.php?plugin=xml_http_if&docu=1#1 * The documentation can be found at http://azureus.sourceforge.net/plugin_details.php?plugin=xml_http_if&docu=1#1
* and some stuff is at http://wiki.vuze.com/index.php/XML_over_HTTP * and some stuff is at http://wiki.vuze.com/index.php/XML_over_HTTP
* *
* A lot of it is copied from the org.xmlrpc.android library's XMLRPCClient * A lot of it is copied from the org.xmlrpc.android library's XMLRPCClient
* as can be found at http://code.google.com/p/android-xmlrpc * as can be found at http://code.google.com/p/android-xmlrpc
* *
* @author erickok * @author erickok
* *
*/ */
@ -87,7 +87,7 @@ public class VuzeXmlOverHttpClient {
private final static String TAG_ANNOUNCE = "announce_result"; private final static String TAG_ANNOUNCE = "announce_result";
private final static String TAG_SCRAPE = "scrape_result"; private final static String TAG_SCRAPE = "scrape_result";
private final static String TAG_CACHED_PROPERTY_NAMES = "cached_property_names"; private final static String TAG_CACHED_PROPERTY_NAMES = "cached_property_names";
private DefaultHttpClient client; private DefaultHttpClient client;
private HttpPost postMethod; private HttpPost postMethod;
private Random random; private Random random;
@ -105,14 +105,14 @@ public class VuzeXmlOverHttpClient {
postMethod.addHeader("Content-Type", "text/xml"); postMethod.addHeader("Content-Type", "text/xml");
// WARNING // WARNING
// I had to disable "Expect: 100-Continue" header since I had // I had to disable "Expect: 100-Continue" header since I had
// two second delay between sending http POST request and POST body // two second delay between sending http POST request and POST body
HttpParams httpParams = postMethod.getParams(); HttpParams httpParams = postMethod.getParams();
HttpProtocolParams.setUseExpectContinue(httpParams, false); HttpProtocolParams.setUseExpectContinue(httpParams, false);
HttpConnectionParams.setConnectionTimeout(httpParams, settings.getTimeoutInMilliseconds()); HttpConnectionParams.setConnectionTimeout(httpParams, settings.getTimeoutInMilliseconds());
HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds()); HttpConnectionParams.setSoTimeout(httpParams, settings.getTimeoutInMilliseconds());
SchemeRegistry registry = new SchemeRegistry(); SchemeRegistry registry = new SchemeRegistry();
SocketFactory httpsSocketFactory; SocketFactory httpsSocketFactory;
if (settings.getSslTrustKey() != null) { if (settings.getSslTrustKey() != null) {
@ -124,7 +124,7 @@ public class VuzeXmlOverHttpClient {
} }
registry.register(new Scheme("http", new PlainSocketFactory(), 80)); registry.register(new Scheme("http", new PlainSocketFactory(), 80));
registry.register(new Scheme("https", httpsSocketFactory, 443)); registry.register(new Scheme("https", httpsSocketFactory, 443));
client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams); client = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);
if (settings.shouldUseAuthentication()) { if (settings.shouldUseAuthentication()) {
if (settings.getUsername() == null || settings.getPassword() == null) { if (settings.getUsername() == null || settings.getPassword() == null) {
@ -137,11 +137,11 @@ public class VuzeXmlOverHttpClient {
new UsernamePasswordCredentials(username, password)); new UsernamePasswordCredentials(username, password));
} }
} }
random = new Random(); random = new Random();
random.nextInt(); random.nextInt();
} }
/** /**
* Convenience constructor. Creates new instance based on server String address * Convenience constructor. Creates new instance based on server String address
* @param settings The server connection settings * @param settings The server connection settings
@ -151,23 +151,23 @@ public class VuzeXmlOverHttpClient {
public VuzeXmlOverHttpClient(DaemonSettings settings, String url) throws DaemonException { public VuzeXmlOverHttpClient(DaemonSettings settings, String url) throws DaemonException {
this(settings, URI.create(url)); this(settings, URI.create(url));
} }
protected Map<String, Object> callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException { protected Map<String, Object> callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException {
try { try {
// prepare POST body // prepare POST body
XmlSerializer serializer = Xml.newSerializer(); XmlSerializer serializer = Xml.newSerializer();
StringWriter bodyWriter = new StringWriter(); StringWriter bodyWriter = new StringWriter();
serializer.setOutput(bodyWriter); serializer.setOutput(bodyWriter);
serializer.startDocument(null, null); serializer.startDocument(null, null);
serializer.startTag(null, TAG_REQUEST); serializer.startTag(null, TAG_REQUEST);
// set object // set object
if (object != null) { if (object != null) {
serializer.startTag(null, TAG_OBJECT).startTag(null, TAG_OBJECT_ID) serializer.startTag(null, TAG_OBJECT).startTag(null, TAG_OBJECT_ID)
.text(object.toString()).endTag(null, TAG_OBJECT_ID).endTag(null, TAG_OBJECT); .text(object.toString()).endTag(null, TAG_OBJECT_ID).endTag(null, TAG_OBJECT);
} }
// set method // set method
serializer.startTag(null, TAG_METHOD).text(method).endTag(null, TAG_METHOD); serializer.startTag(null, TAG_METHOD).text(method).endTag(null, TAG_METHOD);
if (params != null && params.length != 0) { if (params != null && params.length != 0) {
@ -188,7 +188,7 @@ public class VuzeXmlOverHttpClient {
} }
serializer.endTag(null, TAG_PARAMS); serializer.endTag(null, TAG_PARAMS);
} }
// set connection id // set connection id
if (connectionID != null) { if (connectionID != null) {
serializer.startTag(null, TAG_CONNECTION_ID).text(connectionID.toString()).endTag(null, TAG_CONNECTION_ID); serializer.startTag(null, TAG_CONNECTION_ID).text(connectionID.toString()).endTag(null, TAG_CONNECTION_ID);
@ -199,16 +199,16 @@ public class VuzeXmlOverHttpClient {
serializer.endTag(null, TAG_REQUEST); serializer.endTag(null, TAG_REQUEST);
serializer.endDocument(); serializer.endDocument();
// set POST body // set POST body
HttpEntity entity = new StringEntity(bodyWriter.toString()); HttpEntity entity = new StringEntity(bodyWriter.toString());
postMethod.setEntity(entity); postMethod.setEntity(entity);
// Force preemptive authentication // Force preemptive authentication
// This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying // This makes sure there is an 'Authentication: ' header being send before trying and failing and retrying
// by the basic authentication mechanism of DefaultHttpClient // by the basic authentication mechanism of DefaultHttpClient
postMethod.addHeader("Authorization", "Basic " + Base64.encodeBytes((username + ":" + password).getBytes())); postMethod.addHeader("Authorization", "Basic " + Base64.encodeBytes((username + ":" + password).getBytes()));
// execute HTTP POST request // execute HTTP POST request
HttpResponse response = client.execute(postMethod); HttpResponse response = client.execute(postMethod);
@ -225,33 +225,33 @@ public class VuzeXmlOverHttpClient {
// setup pull parser // setup pull parser
XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser(); XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();
entity = response.getEntity(); entity = response.getEntity();
//String temp = HttpHelper.ConvertStreamToString(entity.getContent()); //String temp = HttpHelper.ConvertStreamToString(entity.getContent());
//Reader reader = new StringReader(temp); //Reader reader = new StringReader(temp);
Reader reader = new InputStreamReader(entity.getContent()); Reader reader = new InputStreamReader(entity.getContent());
pullParser.setInput(reader); pullParser.setInput(reader);
// lets start pulling... // lets start pulling...
pullParser.nextTag(); pullParser.nextTag();
pullParser.require(XmlPullParser.START_TAG, null, TAG_RESPONSE); pullParser.require(XmlPullParser.START_TAG, null, TAG_RESPONSE);
// build list of returned values // build list of returned values
int next = pullParser.nextTag(); // skip to first start tag in list int next = pullParser.nextTag(); // skip to first start tag in list
String name = pullParser.getName(); // get name of the first start tag String name = pullParser.getName(); // get name of the first start tag
// Empty response? // Empty response?
if (next == XmlPullParser.END_TAG && name.equals(TAG_RESPONSE)) { if (next == XmlPullParser.END_TAG && name.equals(TAG_RESPONSE)) {
return null; return null;
} else if (name.equals(TAG_ERROR)) { } else if (name.equals(TAG_ERROR)) {
// Error // Error
String errorText = pullParser.nextText(); // the value of the ERROR String errorText = pullParser.nextText(); // the value of the ERROR
entity.consumeContent(); entity.consumeContent();
throw new DaemonException(ExceptionType.ConnectionError, errorText); throw new DaemonException(ExceptionType.ConnectionError, errorText);
} else { } else {
// Consume a list of ENTRYs? // Consume a list of ENTRYs?
if (name.equals(TAG_ENTRY)) { if (name.equals(TAG_ENTRY)) {
@ -262,15 +262,15 @@ public class VuzeXmlOverHttpClient {
} }
entity.consumeContent(); entity.consumeContent();
return entries; return entries;
} else { } else {
// Only a single object was returned, not an entry listing // Only a single object was returned, not an entry listing
return consumeObject(pullParser); return consumeObject(pullParser);
} }
} }
} catch (IOException e) { } catch (IOException e) {
throw new DaemonException(ExceptionType.ConnectionError, e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString());
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {
@ -282,11 +282,11 @@ public class VuzeXmlOverHttpClient {
int next = pullParser.nextTag(); int next = pullParser.nextTag();
String name = pullParser.getName(); String name = pullParser.getName();
// Consume the ENTRY objects // Consume the ENTRY objects
Map<String, Object> returnValues = new HashMap<String, Object>(); Map<String, Object> returnValues = new HashMap<String, Object>();
while (next == XmlPullParser.START_TAG) { while (next == XmlPullParser.START_TAG) {
if (name.equals(TAG_TORRENT) || name.equals(TAG_ANNOUNCE) || name.equals(TAG_SCRAPE) || name.equals(TAG_STATS)) { if (name.equals(TAG_TORRENT) || name.equals(TAG_ANNOUNCE) || name.equals(TAG_SCRAPE) || name.equals(TAG_STATS)) {
// One of the objects contained inside an entry // One of the objects contained inside an entry
pullParser.nextTag(); pullParser.nextTag();
@ -297,21 +297,21 @@ public class VuzeXmlOverHttpClient {
} }
next = pullParser.nextTag(); // skip to next start tag next = pullParser.nextTag(); // skip to next start tag
name = pullParser.getName(); // get name of the new start tag name = pullParser.getName(); // get name of the new start tag
} }
// Consume ENTRY ending // Consume ENTRY ending
pullParser.nextTag(); pullParser.nextTag();
return returnValues; return returnValues;
} }
private Map<String, Object> consumeObject(XmlPullParser pullParser) throws XmlPullParserException, IOException { private Map<String, Object> consumeObject(XmlPullParser pullParser) throws XmlPullParserException, IOException {
int next = XmlPullParser.START_TAG; int next = XmlPullParser.START_TAG;
String name = pullParser.getName(); String name = pullParser.getName();
// Consume bottom-level (contains no objects of its own) object // Consume bottom-level (contains no objects of its own) object
Map<String, Object> returnValues = new HashMap<String, Object>(); Map<String, Object> returnValues = new HashMap<String, Object>();
while (next == XmlPullParser.START_TAG && !(name.equals(TAG_CACHED_PROPERTY_NAMES))) { while (next == XmlPullParser.START_TAG && !(name.equals(TAG_CACHED_PROPERTY_NAMES))) {
@ -326,11 +326,11 @@ public class VuzeXmlOverHttpClient {
} }
next = pullParser.nextTag(); // skip to next start tag next = pullParser.nextTag(); // skip to next start tag
name = pullParser.getName(); // get name of the new start tag name = pullParser.getName(); // get name of the new start tag
} }
return returnValues; return returnValues;
} }
private String serialize(Object value) { private String serialize(Object value) {
@ -344,7 +344,7 @@ public class VuzeXmlOverHttpClient {
return null; return null;
} }
/* For now cast all integers as Long; this prevents casting problems later on when /* For now cast all integers as Long; this prevents casting problems later on when
* we know it's a long but the value was small so it is casted to an Integer here * we know it's a long but the value was small so it is casted to an Integer here
// Integer? // Integer?
try { try {
@ -353,7 +353,7 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Just continue trying the next type // Just continue trying the next type
}*/ }*/
// Long? // Long?
try { try {
Long longnum = Long.parseLong(rawText); Long longnum = Long.parseLong(rawText);
@ -361,7 +361,7 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Just continue trying the next type // Just continue trying the next type
} }
// Double? // Double?
try { try {
Double doublenum = Double.parseDouble(rawText); Double doublenum = Double.parseDouble(rawText);
@ -369,9 +369,9 @@ public class VuzeXmlOverHttpClient {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// Just continue trying the next type // Just continue trying the next type
} }
// String otherwise // String otherwise
return rawText; return rawText;
} }
} }

480
app/src/main/java/com/android/internalcopy/http/multipart/BitCometFilePart.java → app/src/main/java/org/transdroid/multipart/BitCometFilePart.java

@ -1,238 +1,242 @@
/* /*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
* $Revision: 480424 $ * $Revision: 480424 $
* $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $ * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
* *
* ==================================================================== * ====================================================================
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0 * The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at * the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* ==================================================================== * ====================================================================
* *
* This software consists of voluntary contributions made by many * This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more * individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see * information on the Apache Software Foundation, please see
* <http://www.apache.org/>. * <http://www.apache.org/>.
* *
*/ */
package com.android.internalcopy.http.multipart; package org.transdroid.multipart;
import java.io.File; import com.android.internal.http.multipart.FilePartSource;
import java.io.FileNotFoundException; import com.android.internal.http.multipart.PartBase;
import java.io.IOException; import com.android.internal.http.multipart.PartSource;
import java.io.InputStream;
import java.io.OutputStream; import java.io.File;
import org.apache.http.util.EncodingUtils; import java.io.FileNotFoundException;
import java.io.IOException;
/** import java.io.InputStream;
* This class implements a part of a Multipart post object that import java.io.OutputStream;
* consists of a file. import org.apache.http.util.EncodingUtils;
*
* @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a> /**
* @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> * This class implements a part of a Multipart post object that
* @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a> * consists of a file.
* @author <a href="mailto:becke@u.washington.edu">Michael Becke</a> *
* @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a> * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
* @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
* @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
* * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
* @since 2.0 * @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
* * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
*/ * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
public class BitCometFilePart extends PartBase { *
* @since 2.0
/** Default content encoding of file attachments. */ *
public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent"; */
public class BitCometFilePart extends PartBase {
/** Attachment's file name */
protected static final String FILE_NAME = "; filename="; /** Default content encoding of file attachments. */
public static final String DEFAULT_CONTENT_TYPE = "application/x-bittorrent";
/** Attachment's file name as a byte array */
private static final byte[] FILE_NAME_BYTES = /** Attachment's file name */
EncodingUtils.getAsciiBytes(FILE_NAME); protected static final String FILE_NAME = "; filename=";
/** Source of the file part. */ /** Attachment's file name as a byte array */
private PartSource source; private static final byte[] FILE_NAME_BYTES =
EncodingUtils.getAsciiBytes(FILE_NAME);
/**
* FilePart Constructor. /** Source of the file part. */
* private PartSource source;
* @param name the name for this part
* @param partSource the source for this part /**
* @param contentType the content type for this part, if <code>null</code> the * FilePart Constructor.
* {@link #DEFAULT_CONTENT_TYPE default} is used *
* @param charset the charset encoding for this part, if <code>null</code> the * @param name the name for this part
* {@link #DEFAULT_CHARSET default} is used * @param partSource the source for this part
*/ * @param contentType the content type for this part, if <code>null</code> the
public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) { * {@link #DEFAULT_CONTENT_TYPE default} is used
* @param charset the charset encoding for this part, if <code>null</code> the
super( * {@link #DEFAULT_CHARSET default} is used
name, */
contentType == null ? DEFAULT_CONTENT_TYPE : contentType, public BitCometFilePart(String name, PartSource partSource, String contentType, String charset) {
charset == null ? "ISO-8859-1" : charset,
null super(
); name,
contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
if (partSource == null) { charset == null ? "ISO-8859-1" : charset,
throw new IllegalArgumentException("Source may not be null"); null
} );
this.source = partSource;
} if (partSource == null) {
throw new IllegalArgumentException("Source may not be null");
/** }
* FilePart Constructor. this.source = partSource;
* }
* @param name the name for this part
* @param partSource the source for this part /**
*/ * FilePart Constructor.
public BitCometFilePart(String name, PartSource partSource) { *
this(name, partSource, null, null); * @param name the name for this part
} * @param partSource the source for this part
*/
/** public BitCometFilePart(String name, PartSource partSource) {
* FilePart Constructor. this(name, partSource, null, null);
* }
* @param name the name of the file part
* @param file the file to post /**
* * FilePart Constructor.
* @throws FileNotFoundException if the <i>file</i> is not a normal *
* file or if it is not readable. * @param name the name of the file part
*/ * @param file the file to post
public BitCometFilePart(String name, File file) *
throws FileNotFoundException { * @throws FileNotFoundException if the <i>file</i> is not a normal
this(name, new FilePartSource(file), null, null); * file or if it is not readable.
} */
public BitCometFilePart(String name, File file)
/** throws FileNotFoundException {
* FilePart Constructor. this(name, new FilePartSource(file), null, null);
* }
* @param name the name of the file part
* @param file the file to post /**
* @param contentType the content type for this part, if <code>null</code> the * FilePart Constructor.
* {@link #DEFAULT_CONTENT_TYPE default} is used *
* @param charset the charset encoding for this part, if <code>null</code> the * @param name the name of the file part
* {@link #DEFAULT_CHARSET default} is used * @param file the file to post
* * @param contentType the content type for this part, if <code>null</code> the
* @throws FileNotFoundException if the <i>file</i> is not a normal * {@link #DEFAULT_CONTENT_TYPE default} is used
* file or if it is not readable. * @param charset the charset encoding for this part, if <code>null</code> the
*/ * {@link #DEFAULT_CHARSET default} is used
public BitCometFilePart(String name, File file, String contentType, String charset) *
throws FileNotFoundException { * @throws FileNotFoundException if the <i>file</i> is not a normal
this(name, new FilePartSource(file), contentType, charset); * file or if it is not readable.
} */
public BitCometFilePart(String name, File file, String contentType, String charset)
/** throws FileNotFoundException {
* FilePart Constructor. this(name, new FilePartSource(file), contentType, charset);
* }
* @param name the name of the file part
* @param fileName the file name /**
* @param file the file to post * FilePart Constructor.
* *
* @throws FileNotFoundException if the <i>file</i> is not a normal * @param name the name of the file part
* file or if it is not readable. * @param fileName the file name
*/ * @param file the file to post
public BitCometFilePart(String name, String fileName, File file) *
throws FileNotFoundException { * @throws FileNotFoundException if the <i>file</i> is not a normal
this(name, new FilePartSource(fileName, file), null, null); * file or if it is not readable.
} */
public BitCometFilePart(String name, String fileName, File file)
/** throws FileNotFoundException {
* FilePart Constructor. this(name, new FilePartSource(fileName, file), null, null);
* }
* @param name the name of the file part
* @param fileName the file name /**
* @param file the file to post * FilePart Constructor.
* @param contentType the content type for this part, if <code>null</code> the *
* {@link #DEFAULT_CONTENT_TYPE default} is used * @param name the name of the file part
* @param charset the charset encoding for this part, if <code>null</code> the * @param fileName the file name
* {@link #DEFAULT_CHARSET default} is used * @param file the file to post
* * @param contentType the content type for this part, if <code>null</code> the
* @throws FileNotFoundException if the <i>file</i> is not a normal * {@link #DEFAULT_CONTENT_TYPE default} is used
* file or if it is not readable. * @param charset the charset encoding for this part, if <code>null</code> the
*/ * {@link #DEFAULT_CHARSET default} is used
public BitCometFilePart(String name, String fileName, File file, String contentType, String charset) *
throws FileNotFoundException { * @throws FileNotFoundException if the <i>file</i> is not a normal
this(name, new FilePartSource(fileName, file), contentType, charset); * file or if it is not readable.
} */
public BitCometFilePart(String name, String fileName, File file, String contentType, String charset)
/** throws FileNotFoundException {
* Write the disposition header to the output stream this(name, new FilePartSource(fileName, file), contentType, charset);
* @param out The output stream }
* @throws IOException If an IO problem occurs
* @see Part#sendDispositionHeader(OutputStream) /**
*/ * Write the disposition header to the output stream
@Override * @param out The output stream
protected void sendDispositionHeader(OutputStream out) * @throws IOException If an IO problem occurs
throws IOException { * @see Part#sendDispositionHeader(OutputStream)
super.sendDispositionHeader(out); */
String filename = this.source.getFileName(); @Override
if (filename != null) { protected void sendDispositionHeader(OutputStream out)
out.write(FILE_NAME_BYTES); throws IOException {
out.write(QUOTE_BYTES); super.sendDispositionHeader(out);
out.write(EncodingUtils.getAsciiBytes(filename)); String filename = this.source.getFileName();
out.write(QUOTE_BYTES); if (filename != null) {
} out.write(FILE_NAME_BYTES);
} out.write(QUOTE_BYTES);
out.write(EncodingUtils.getAsciiBytes(filename));
/** out.write(QUOTE_BYTES);
* Write the data in "source" to the specified stream. }
* @param out The output stream. }
* @throws IOException if an IO problem occurs.
* @see Part#sendData(OutputStream) /**
*/ * Write the data in "source" to the specified stream.
@Override * @param out The output stream.
protected void sendData(OutputStream out) throws IOException { * @throws IOException if an IO problem occurs.
if (lengthOfData() == 0) { * @see Part#sendData(OutputStream)
*/
// this file contains no data, so there is nothing to send. @Override
// we don't want to create a zero length buffer as this will protected void sendData(OutputStream out) throws IOException {
// cause an infinite loop when reading. if (lengthOfData() == 0) {
return;
} // this file contains no data, so there is nothing to send.
// we don't want to create a zero length buffer as this will
byte[] tmp = new byte[4096]; // cause an infinite loop when reading.
InputStream instream = source.createInputStream(); return;
try { }
int len;
while ((len = instream.read(tmp)) >= 0) { byte[] tmp = new byte[4096];
out.write(tmp, 0, len); InputStream instream = source.createInputStream();
} try {
} finally { int len;
// we're done with the stream, close it while ((len = instream.read(tmp)) >= 0) {
instream.close(); out.write(tmp, 0, len);
} }
} } finally {
// we're done with the stream, close it
/** instream.close();
* Returns the source of the file part. }
* }
* @return The source.
*/ /**
protected PartSource getSource() { * Returns the source of the file part.
return this.source; *
} * @return The source.
*/
/** protected PartSource getSource() {
* Return the length of the data. return this.source;
* @return The length. }
* @see Part#lengthOfData()
*/ /**
@Override * Return the length of the data.
protected long lengthOfData() { * @return The length.
return source.getLength(); * @see Part#lengthOfData()
} */
@Override
} protected long lengthOfData() {
return source.getLength();
}
}

88
app/src/main/java/com/android/internalcopy/http/multipart/Utf8StringPart.java → app/src/main/java/org/transdroid/multipart/Utf8StringPart.java

@ -1,43 +1,45 @@
package com.android.internalcopy.http.multipart; package org.transdroid.multipart;
import java.io.IOException; import com.android.internal.http.multipart.PartBase;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.http.util.EncodingUtils; import java.io.OutputStream;
public class Utf8StringPart extends PartBase { import org.apache.http.util.EncodingUtils;
/** Contents of this StringPart. */ public class Utf8StringPart extends PartBase {
private byte[] content;
/** Contents of this StringPart. */
/** The String value of this part. */ private byte[] content;
private String value;
/** The String value of this part. */
public Utf8StringPart(String name, String value) { private String value;
super(name, null, null, null);
this.value = value; public Utf8StringPart(String name, String value) {
} super(name, null, null, null);
this.value = value;
/** }
* Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* after the part is created. /**
* * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed
* @return the content in bytes * after the part is created.
*/ *
private byte[] getContent() { * @return the content in bytes
if (content == null) { */
content = EncodingUtils.getBytes(value, "utf-8"); private byte[] getContent() {
} if (content == null) {
return content; content = EncodingUtils.getBytes(value, "utf-8");
} }
return content;
@Override }
protected void sendData(OutputStream out) throws IOException {
out.write(getContent()); @Override
} protected void sendData(OutputStream out) throws IOException {
out.write(getContent());
@Override }
protected long lengthOfData() throws IOException {
return getContent().length; @Override
} protected long lengthOfData() throws IOException {
} return getContent().length;
}
}

131
app/src/main/res/layout-land/dialog_color_picker.xml

@ -1,77 +1,82 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<!-- Copyright (C) 2010 Daniel Nilsson Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and limitations under the License.
limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
--> -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp">
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerView
<net.margaritov.preference.colorpicker.ColorPickerView android:id="@+id/color_picker_view"
android:id="@+id/color_picker_view" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layerType="software"
android:tag="landscape" android:tag="landscape" />
android:layerType="software"
/> <LinearLayout
android:layout_width="wrap_content"
<LinearLayout android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_marginBottom="10dp"
android:layout_height="wrap_content" android:orientation="vertical">
android:orientation="vertical"
android:layout_marginBottom="10dp"> <EditText
android:id="@+id/hex_val"
<TextView android:layout_width="fill_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:hint="HEX"
android:text="@string/press_color_to_apply" android:imeOptions="actionDone"
android:gravity="center" android:maxLength="7"
android:layout_marginTop="6dp" android:singleLine="true"
android:layout_marginLeft="6dp" android:inputType="textCapCharacters"
android:layout_marginRight="6dp" android:visibility="gone"></EditText>
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall" <TextView
/> android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
android:gravity="center"
android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="↓"
android:textSize="20sp" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5" />
</LinearLayout>
<net.margaritov.preference.colorpicker.ColorPickerPanelView </LinearLayout>
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="↓"
android:textSize="20sp"
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

2
app/src/main/res/layout-w600dp/activity_search.xml

@ -23,7 +23,7 @@
android:orientation="horizontal" android:orientation="horizontal"
tools:context=".core.gui.search.SearchActivity_"> tools:context=".core.gui.search.SearchActivity_">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/search_toolbar" android:id="@+id/search_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"

8
app/src/main/res/layout-w600dp/activity_torrents.xml

@ -31,14 +31,14 @@
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"/> android:focusableInTouchMode="true"/>
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar" android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar" android:id="@+id/actions_toolbar"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -48,7 +48,7 @@
android:paddingEnd="@dimen/ui_actions_padding" android:paddingEnd="@dimen/ui_actions_padding"
android:paddingRight="@dimen/ui_actions_padding" /> android:paddingRight="@dimen/ui_actions_padding" />
<android.support.v7.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu" android:id="@+id/contextual_menu"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -58,7 +58,7 @@
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
<android.support.v7.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/filter_search" android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"

8
app/src/main/res/layout-w900dp/activity_rssfeeds.xml

@ -21,7 +21,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.rss.RssFeedsActivity_"> tools:context=".core.gui.rss.RssFeedsActivity_">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar" android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -32,13 +32,13 @@
style="@style/DefaultToolbarShadow" style="@style/DefaultToolbarShadow"
android:layout_below="@id/rssfeeds_toolbar" /> android:layout_below="@id/rssfeeds_toolbar" />
<android.support.v4.view.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/rssfeeds_pager" android:id="@+id/rssfeeds_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/rssfeeds_toolbar"> android:layout_below="@+id/rssfeeds_toolbar">
<android.support.design.widget.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/rssfeeds_tabs" android:id="@+id/rssfeeds_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
@ -79,6 +79,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:layout="@layout/fragment_torrents" /> tools:layout="@layout/fragment_torrents" />
</LinearLayout> </LinearLayout>
</android.support.v4.view.ViewPager> </androidx.viewpager.widget.ViewPager>
</RelativeLayout> </RelativeLayout>

10
app/src/main/res/layout-w900dp/activity_torrents.xml

@ -30,7 +30,7 @@
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true"/> android:focusableInTouchMode="true"/>
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/selection_toolbar" android:id="@+id/selection_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -41,7 +41,7 @@
android:layout_alignRight="@id/filters_list" android:layout_alignRight="@id/filters_list"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/filter_search" android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -80,7 +80,7 @@
android:layout_height="1dp" android:layout_height="1dp"
android:layout_centerHorizontal="true" /> android:layout_centerHorizontal="true" />
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar" android:id="@+id/actions_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -89,7 +89,7 @@
android:layout_toStartOf="@id/fragments_divider" android:layout_toStartOf="@id/fragments_divider"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_toolbar" android:id="@+id/contextual_toolbar"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -101,7 +101,7 @@
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar" android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"

2
app/src/main/res/layout/activity_details.xml

@ -6,7 +6,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".DetailsActivity"> tools:context=".DetailsActivity">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/selection_toolbar" android:id="@+id/selection_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"

8
app/src/main/res/layout/activity_rssfeeds.xml

@ -21,7 +21,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.rss.RssFeedsActivity_"> tools:context=".core.gui.rss.RssFeedsActivity_">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar" android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -32,14 +32,14 @@
style="@style/DefaultToolbarShadow" style="@style/DefaultToolbarShadow"
android:layout_below="@id/rssfeeds_toolbar" /> android:layout_below="@id/rssfeeds_toolbar" />
<android.support.v4.view.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/rssfeeds_pager" android:id="@+id/rssfeeds_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/rssfeeds_toolbar" android:layout_below="@id/rssfeeds_toolbar"
android:layout_marginTop="-2dp"> android:layout_marginTop="-2dp">
<android.support.design.widget.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/rssfeeds_tabs" android:id="@+id/rssfeeds_tabs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
@ -73,6 +73,6 @@
tools:layout="@layout/fragment_torrents" /> tools:layout="@layout/fragment_torrents" />
</LinearLayout> </LinearLayout>
</android.support.v4.view.ViewPager> </androidx.viewpager.widget.ViewPager>
</RelativeLayout> </RelativeLayout>

2
app/src/main/res/layout/activity_rssitems.xml

@ -21,7 +21,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.rss.RssItemsActivity_"> tools:context=".core.gui.rss.RssItemsActivity_">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/rssfeeds_toolbar" android:id="@+id/rssfeeds_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"

4
app/src/main/res/layout/activity_search.xml

@ -21,7 +21,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.search.SearchActivity_"> tools:context=".core.gui.search.SearchActivity_">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/search_toolbar" android:id="@+id/search_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -33,7 +33,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"

12
app/src/main/res/layout/activity_torrents.xml

@ -16,7 +16,7 @@
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
--> -->
<!-- This layout is for phones in portrait and shows the torrents list with the filters as navigation drawer. --> <!-- This layout is for phones in portrait and shows the torrents list with the filters as navigation drawer. -->
<android.support.v4.widget.DrawerLayout <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
@ -31,14 +31,14 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/torrents_toolbar" android:id="@+id/torrents_toolbar"
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/actions_toolbar" android:id="@+id/actions_toolbar"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -48,7 +48,7 @@
android:paddingEnd="@dimen/ui_actions_padding" android:paddingEnd="@dimen/ui_actions_padding"
android:paddingRight="@dimen/ui_actions_padding" /> android:paddingRight="@dimen/ui_actions_padding" />
<android.support.v7.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu" android:id="@+id/contextual_menu"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -107,7 +107,7 @@
android:divider="@null" android:divider="@null"
tools:listitem="@layout/list_item_filter" /> tools:listitem="@layout/list_item_filter" />
<android.support.v7.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/filter_search" android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -121,4 +121,4 @@
</LinearLayout> </LinearLayout>
</android.support.v4.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

137
app/src/main/res/layout/dialog_color_picker.xml

@ -1,77 +1,88 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<!-- Copyright (C) 2010 Daniel Nilsson Copyright (C) 2010 Daniel Nilsson
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and limitations under the License.
limitations under the License.
// Taken from https://github.com/attenzione/android-ColorPickerPreference/tree/696bb050527d6a7ae14e47b7472a0640a7ff08e6
--> -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:paddingRight="5dp" android:paddingRight="5dp">
android:orientation="vertical">
<net.margaritov.preference.colorpicker.ColorPickerView
<net.margaritov.preference.colorpicker.ColorPickerView android:id="@+id/color_picker_view"
android:id="@+id/color_picker_view" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layerType="software"
android:layout_gravity="center_horizontal" android:tag="portrait" />
android:tag="portrait"
android:layerType="software" <LinearLayout
/> android:id="@+id/text_hex_wrapper"
android:layout_width="fill_parent"
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_marginBottom="5dp"
android:layout_height="wrap_content" android:layout_marginLeft="6dp"
android:text="@string/press_color_to_apply" android:layout_marginRight="6dp">
android:gravity="left"
android:layout_marginLeft="6dp" <TextView
android:layout_marginRight="6dp" android:layout_width="wrap_content"
android:layout_marginBottom="5dp" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" android:gravity="left"
/> android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" />
<LinearLayout
android:layout_width="wrap_content" <EditText
android:layout_height="40dp" android:id="@+id/hex_val"
android:orientation="horizontal" android:layout_width="0dp"
android:layout_marginBottom="10dp"> android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="HEX"
android:imeOptions="actionDone"
android:maxLength="7"
android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:text="→"
android:textSize="20sp" />
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
</LinearLayout>
<net.margaritov.preference.colorpicker.ColorPickerPanelView </LinearLayout>
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="→"
android:textSize="20sp"
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

8
app/src/main/res/layout/fragment_details.xml

@ -23,7 +23,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.DetailsActivity_"> tools:context=".core.gui.DetailsActivity_">
<android.support.v7.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/details_menu" android:id="@+id/details_menu"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -31,7 +31,7 @@
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<android.support.v7.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
android:id="@+id/contextual_menu" android:id="@+id/contextual_menu"
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -41,7 +41,7 @@
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> tools:visibility="visible"/>
<android.support.v4.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout" android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -56,7 +56,7 @@
android:dividerHeight="0dip" android:dividerHeight="0dip"
android:visibility="gone" /> android:visibility="gone" />
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar <ProgressBar
android:id="@+id/loading_progress" android:id="@+id/loading_progress"

4
app/src/main/res/layout/fragment_torrents.xml

@ -20,7 +20,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout" android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -36,7 +36,7 @@
tools:listitem="@layout/list_item_torrent" tools:listitem="@layout/list_item_torrent"
tools:visibility="visible" /> tools:visibility="visible" />
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar <ProgressBar
android:id="@+id/loading_progress" android:id="@+id/loading_progress"

2
app/src/main/res/menu/activity_search.xml

@ -21,7 +21,7 @@
android:id="@+id/action_search" android:id="@+id/action_search"
android:icon="@drawable/ic_action_search" android:icon="@drawable/ic_action_search"
android:title="@string/action_search" android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView" app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" /> app:showAsAction="collapseActionView|ifRoom" />
<item <item
android:id="@+id/action_refresh" android:id="@+id/action_refresh"

2
app/src/main/res/menu/activity_torrents_main.xml

@ -21,7 +21,7 @@
android:id="@+id/action_search" android:id="@+id/action_search"
android:icon="@drawable/ic_action_search" android:icon="@drawable/ic_action_search"
android:title="@string/action_search" android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView" app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom" /> app:showAsAction="collapseActionView|ifRoom" />
<item <item
android:id="@+id/action_rss" android:id="@+id/action_rss"

15
build.gradle

@ -1,19 +1,30 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://jitpack.io" }
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.3' classpath 'com.android.tools.build:gradle:4.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
} }
} }
allprojects { allprojects {
repositories { repositories {
google() google()
mavenCentral()
jcenter() jcenter()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
mavenCentral()
} }
} }
task clean(type: Delete) {
delete rootProject.buildDir
}

2
gradle.properties

@ -11,3 +11,5 @@
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m # Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
android.enableJetifier=true
android.useAndroidX=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored

Binary file not shown.

3
gradle/wrapper/gradle-wrapper.properties vendored

@ -1,6 +1,5 @@
#Sun Feb 09 15:35:10 AEDT 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

117
gradlew vendored

@ -1,4 +1,20 @@
#!/usr/bin/env bash #!/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
#
# https://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.
#
############################################################################## ##############################################################################
## ##
@ -6,20 +22,38 @@
## ##
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Attempt to set APP_HOME
DEFAULT_JVM_OPTS="" # Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle" 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.
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"
warn ( ) { warn () {
echo "$*" echo "$*"
} }
die ( ) { die () {
echo echo
echo "$*" echo "$*"
echo echo
@ -30,6 +64,7 @@ die ( ) {
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false
case "`uname`" in case "`uname`" in
CYGWIN* ) CYGWIN* )
cygwin=true cygwin=true
@ -40,33 +75,14 @@ case "`uname`" in
MINGW* ) MINGW* )
msys=true msys=true
;; ;;
NONSTOP* )
nonstop=true
;;
esac esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@ -90,7 +106,7 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n` MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@ -110,10 +126,12 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if $cygwin ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@ -138,27 +156,30 @@ if $cygwin ; then
else else
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=$((i+1)) i=`expr $i + 1`
done done
case $i in case $i in
(0) set -- ;; 0) set -- ;;
(1) set -- "$args0" ;; 1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;; 2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;; 3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Escape application args
function splitJvmOpts() { save () {
JVM_OPTS=("$@") for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
} }
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS APP_ARGS=`save "$@"`
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" exec "$JAVACMD" "$@"

34
gradlew.bat vendored

@ -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 https://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
@ -8,14 +24,17 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@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 DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@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="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
@ -46,10 +65,9 @@ echo location of your Java installation.
goto fail goto fail
:init :init
@rem Get command-line arguments, handling Windowz variants @rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@ -60,17 +78,13 @@ set _SKIP=2
if "x%~1" == "x" goto execute if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

Loading…
Cancel
Save