Skip to content

Commit

Permalink
Added a Service to listen to a configurable port and send the receive…
Browse files Browse the repository at this point in the history
…d link list to the server

See issue pyload#37
  • Loading branch information
Daniel Prange committed Apr 30, 2021
1 parent 520035a commit b8088d5
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 23 deletions.
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,10 @@

<activity android:name=".RemoteSettings" android:label="@string/remotesettings_activity"/>

<service
android:name=".services.clicknload.ClickNLoadService"
android:exported="true"
android:process=":cnl_service"/>

</application>
</manifest>
57 changes: 36 additions & 21 deletions app/src/main/java/org/pyload/android/client/pyLoad.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package org.pyload.android.client;

import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.view.*;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TabHost;

import androidx.core.view.MenuItemCompat;

import org.pyload.android.client.components.FragmentTabsPager;
import org.pyload.android.client.dialogs.AccountDialog;
Expand All @@ -18,31 +24,26 @@
import org.pyload.android.client.fragments.QueueFragment;
import org.pyload.android.client.module.Eula;
import org.pyload.android.client.module.GuiTask;
import org.pyload.android.client.services.clicknload.ClickNLoadService;
import org.pyload.thrift.Destination;
import org.pyload.thrift.PackageDoesNotExists;
import org.pyload.thrift.Pyload.Client;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.TabHost;
import androidx.core.view.MenuItemCompat;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

public class pyLoad extends FragmentTabsPager
{

private pyLoadApp app;

// keep reference to set indeterminateProgress
private MenuItem refreshItem;

/** Called when the activity is first created. */

public void onCreate(Bundle savedInstanceState)
{

Expand Down Expand Up @@ -90,6 +91,8 @@ public void onCreate(Bundle savedInstanceState)
spec = mTabHost.newTabSpec(title).setIndicator(title,
res.getDrawable(tab_collector));
mTabsAdapter.addTab(spec, CollectorFragment.class, null);

startClickNLoadService();
}

@Override
Expand Down Expand Up @@ -359,4 +362,16 @@ public MenuItem getRefreshItem()
{
return refreshItem;
}
}

private void startClickNLoadService() {
if(app.prefs.getBoolean("check_box_clicknload", false)){
Intent i= new Intent(getApplicationContext(), ClickNLoadService.class);
i.setAction("START");
int port = Integer.parseInt(app.prefs.getString("edit_text_clicknload_port", "9666"));
i.putExtra("port", port);

getApplicationContext().startService(i);
}
}

}
10 changes: 10 additions & 0 deletions app/src/main/java/org/pyload/android/client/pyLoadApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
Expand Down Expand Up @@ -332,4 +333,13 @@ public boolean getCaptchaNotificationShown()
return captchaNotificationShown;
}

public void showToast(final String text, final int duration){
new Handler(Looper.getMainLooper()).post(new Runnable(){
@Override
public void run() {
Toast.makeText(getBaseContext(), text, duration).show();
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.pyload.android.client.services.clicknload;

import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import org.pyload.android.client.pyLoadApp;

import java.util.concurrent.Executors;

public class ClickNLoadService extends Service {

private final static String LOGTAG = "ClickNLoad Service";

private ClickNLoadTask clickNLoadTask;
private int port;

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {

if (intent != null) {
String action = intent.getAction();
port = intent.getExtras().getInt("port");
switch(action) {
case "START": startService(); break;
case "STOP": stopService(); break;
default: Log.d(LOGTAG, "This should never happen. No action in the received intent");
}
} else {
Log.d(LOGTAG, "with a null intent. It has been probably restarted by the system.");
}

return Service.START_STICKY;
}

private void stopService() {
clickNLoadTask.stop();
}

public void startService() {
clickNLoadTask = new ClickNLoadTask(port, (pyLoadApp) getApplicationContext());
Executors.newSingleThreadExecutor().submit(clickNLoadTask);
}

@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.pyload.android.client.services.clicknload;


import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import org.pyload.android.client.R;
import org.pyload.android.client.pyLoadApp;
import org.pyload.thrift.Destination;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class ClickNLoadTask implements Runnable{

private final static String LOGTAG= "ClickNLoadTask";

private volatile boolean stopped = false;
private int port;
private pyLoadApp app;

public ClickNLoadTask(int port, pyLoadApp app){
this.port = port;
this.app = app;

app.prefs.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//stop if clicknload gets disabled
if(key.equals("check_box_clicknload") && !sharedPreferences.getBoolean(key, true)){
stop();
}
}
});
}

@Override
public void run() {
Socket clientSocket = null;
BufferedReader in;
PrintStream out;
ServerSocket serverSocket = null;

while (!stopped) {

try {
if (serverSocket != null) {
serverSocket.close();
clientSocket.close();
}
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();

Log.d(LOGTAG, "Receiving ClickNLoad Event");
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
Log.e(LOGTAG, "Socket could not be opened", e);
stop();
break;
}

try {
String input;
while ((input = in.readLine()) != null) {
if (input.startsWith("source")) {
List<String> urlList = getURLParamsAsMap(input).get("urls");
app.getClient().addPackage("TestName", urlList, Destination.Collector);
app.showToast(String.format(getLocalizedResources(app).getString(R.string.clicknload_toast_msg), urlList.size()), Toast.LENGTH_LONG);
}
}
out.println("success");
} catch (Exception e) {
Log.e(LOGTAG, "Data could not be parsed");
break;
}
}
}

public static Map<String, List<String>> getURLParamsAsMap(String parameters) throws UnsupportedEncodingException {
final Map<String, List<String>> parameterMap = new LinkedHashMap<>();
final String[] pairs = parameters.split("&");
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
if (!parameterMap.containsKey(key)) {
parameterMap.put(key, new LinkedList<String>());
}
final String[] values = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8").split("\\r?\\n") : new String[0];
for (String value : values) {
parameterMap.get(key).add(value);
}
}
return parameterMap;
}

public void stop() {
stopped = true;
}

Resources getLocalizedResources(Context context) {
Configuration conf = context.getResources().getConfiguration();
conf = new Configuration(conf);
conf.setLocale(Locale.getDefault());
Context localizedContext = context.createConfigurationContext(conf);
return localizedContext.getResources();
}
}
5 changes: 5 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
<string name="captcha_dialog_titel">Bitte geben Sie den Text ein</string>
<string name="invert_tabs">Tabfarbe invertieren</string>
<string name="invert_tabs_desc">Du kannst das Tab-Aussehen ändern, damit es besser zu deinem System Theme passt.</string>
<string name="enable_clicknload">Aktiviere Click\'n\'Load</string>
<string name="enable_clicknload_desc">Lässt die App auf Click\'n\'Load Verbindungen reagieren.</string>
<string name="clicknload_port">Click\'n\'Load Port</string>
<string name="clicknload_port_desc">Der Server Port für Click\'n\'Load.</string>
<string name="clicknload_toast_msg">Paket mit %d Links empfangen. Zum Collector gesendet</string>
<string name="ssl">SSL Verbindung</string>
<string name="ssl_desc">Eine sichere Verbindung zum Server aufbauen, wenn SSL aktiviert wurde.</string>
<string name="ssl_validate">Bestätige das SSL Zertifikat</string>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
<string name="captcha_notification_desc">Enter captcha to continue downloading.</string>
<string name="invert_tabs">Invert tab icon color</string>
<string name="invert_tabs_desc">You may change the tab icon layout if it fits better to your theme.</string>
<string name="enable_clicknload">Enable Click\'n\'Load</string>
<string name="enable_clicknload_desc">Have the app listen for Click\'n\'Load connections.</string>
<string name="clicknload_port">Click\'n\'Load Port</string>
<string name="clicknload_port_desc">Server Port for Click\'n\'Load.</string>
<string name="clicknload_toast_msg">Received a package with %d links. Send to Collector</string>
<string name="ssl">SSL Connection</string>
<string name="ssl_desc">Establish a secure connection to the core if you activated SSL</string>
<string name="ssl_validate">Validate SSL Certificate</string>
Expand Down
21 changes: 19 additions & 2 deletions app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,25 @@
<EditTextPreference android:key="refresh_rate" android:defaultValue="5" android:summary="@string/refresh_rate_desc" android:title="@string/refresh_rate" android:numeric="integer"/>
<CheckBoxPreference android:key="pull_captcha" android:title="@string/retrieve_captcha" android:summary="@string/retrieve_captcha_desc" android:defaultValue="true"/>
<CheckBoxPreference android:key="invert_tabs" android:summary="@string/invert_tabs_desc" android:title="@string/invert_tabs" android:defaultValue="false"/>


<CheckBoxPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:defaultValue="false"
android:key="check_box_clicknload"
android:summary="@string/enable_clicknload_desc"
android:title="@string/enable_clicknload" />
<EditTextPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:defaultValue="9666"
android:digits="0123456789"
android:inputType="number"
android:key="edit_text_clicknload_port"
android:singleLine="true"
android:summary="@string/clicknload_port_desc"
android:title="@string/clicknload_port" />


</PreferenceCategory><PreferenceCategory android:key="login" android:title="@string/login">
<EditTextPreference android:key="username" android:summary="@string/username_desc" android:title="@string/username" android:singleLine="true"/>
<EditTextPreference android:key="password" android:title="@string/password" android:singleLine="true" android:password="true"/>
Expand Down

0 comments on commit b8088d5

Please sign in to comment.