548 lines
21 KiB
Java
Executable File
548 lines
21 KiB
Java
Executable File
package com.kaanaxinc.portalstudio;
|
|
|
|
import android.app.Activity;
|
|
import android.bluetooth.BluetoothAdapter;
|
|
import android.bluetooth.BluetoothDevice;
|
|
import android.bluetooth.BluetoothSocket;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.ParcelUuid;
|
|
import android.os.StrictMode;
|
|
import android.text.Editable;
|
|
import android.text.TextWatcher;
|
|
import android.util.Log;
|
|
import android.view.KeyEvent;
|
|
import android.view.View;
|
|
import android.view.View.OnClickListener;
|
|
import android.view.View.OnKeyListener;
|
|
import android.widget.Button;
|
|
import android.widget.EditText;
|
|
import android.widget.ImageButton;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileOutputStream;
|
|
import java.io.FileReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.io.OutputStreamWriter;
|
|
import java.net.URL;
|
|
import java.net.URLConnection;
|
|
import java.util.ArrayList;
|
|
import java.util.Set;
|
|
|
|
public class MainActivity extends Activity {
|
|
// La chaîne de caractères par défaut
|
|
private final String defaut = "Le code d'accès est inscrit sur la notice.";
|
|
Toast myToast;
|
|
Button sendPost = null;
|
|
Button sendComment = null;
|
|
ImageButton logo = null;
|
|
TextView entrezCode = null;
|
|
TextView codeSurNotice = null;
|
|
TextView texteRecu = null;
|
|
Handler bluetoothIn;
|
|
boolean currentView = false;
|
|
final int handlerState = 0;
|
|
String messageFinal = "jmesoiejsmoi";
|
|
|
|
BluetoothAdapter blueAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
private OutputStream outputStream;
|
|
private InputStream inStream;
|
|
ArrayList<String> postIds = new ArrayList<String>();
|
|
int postNumber = 0;
|
|
String subreddit = "";
|
|
|
|
String[] subreddits = {"talesfromtechsupport", "talesfromretail", "caddit", "askreddit", "nosleep"};
|
|
char[] subCommands = {'t', 'r', 'c', 'a', 'n'};
|
|
String messageAEnvoyer = "";
|
|
int progressionEnvoi = 0;
|
|
int progressionPage = 0;
|
|
|
|
String connectionError = "PortalStudio n'a pas pu se connecter au portail. Vérifiez votre connexion bluetooth. Tapez sur le logo pour réessayer la connexion.";
|
|
|
|
//Initializes the Bluetooth connection.
|
|
//Important detail: it always connects to the device that is the lowest in your paired devices list.
|
|
private void init() throws IOException {
|
|
Thread connexionThread = new Thread(new Runnable()
|
|
{
|
|
public void run() {
|
|
try {
|
|
if (blueAdapter != null) {
|
|
if (blueAdapter.isEnabled()) {
|
|
Set<BluetoothDevice> bondedDevices = blueAdapter.getBondedDevices();
|
|
|
|
if(bondedDevices.size() > 0){
|
|
BluetoothDevice bt2 = null;
|
|
for(BluetoothDevice bt : bondedDevices) {
|
|
bt2 = bt;
|
|
}
|
|
|
|
|
|
BluetoothDevice device = bt2;
|
|
ParcelUuid[] uuids = device.getUuids();
|
|
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
|
|
socket.connect();
|
|
outputStream = socket.getOutputStream();
|
|
inStream = socket.getInputStream();
|
|
}
|
|
|
|
Log.e("error", "No appropriate paired devices.");
|
|
} else {
|
|
Log.e("error", "Bluetooth is disabled.");
|
|
}
|
|
}
|
|
} catch (IOException e) {
|
|
|
|
}
|
|
}
|
|
});
|
|
|
|
connexionThread.start();
|
|
|
|
}
|
|
|
|
//Writes a string to the bluetooth device.
|
|
public void write(String s) throws IOException, NullPointerException {
|
|
outputStream.write(s.getBytes());
|
|
}
|
|
|
|
//Once this method is called, begins listening for data.
|
|
//Note: always place this method in a if checking if inStream != null. Else it will crash.
|
|
void beginListenForData() {
|
|
Thread workerThread = new Thread(new Runnable()
|
|
{
|
|
public void run() {
|
|
|
|
byte[] buffer = new byte[256];
|
|
int bytes;
|
|
|
|
while(!Thread.currentThread().isInterrupted()) {
|
|
try {
|
|
bytes = inStream.read(buffer); //read bytes from input buffer
|
|
String readMessage = new String(buffer, 0, bytes);
|
|
// Send the obtained bytes to the UI Activity via handler
|
|
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
|
|
} catch (IOException e) {
|
|
break;
|
|
} catch (NullPointerException e) {
|
|
toast("Null pointer exception 3");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
workerThread.start();
|
|
}
|
|
|
|
//Checks if the bluetooth is enabled, and tries connecting.
|
|
void checkBluetooth() {
|
|
//Prompt user to turn on Bluetooth if Bluetooth is disabled
|
|
if (!blueAdapter.isEnabled()) {
|
|
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
|
startActivityForResult(enableBtIntent, 1);
|
|
}
|
|
|
|
try {
|
|
init();
|
|
} catch (IOException e2) {
|
|
|
|
}
|
|
}
|
|
|
|
void toast(String str) {
|
|
myToast.setText(str);
|
|
myToast.show();
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_main);
|
|
myToast = Toast.makeText(getBaseContext(), "", Toast.LENGTH_SHORT);
|
|
sendPost = (Button)findViewById(R.id.sendPost);
|
|
sendComment = (Button)findViewById(R.id.sendComment);
|
|
codeSurNotice = (TextView)findViewById(R.id.codeSurNotice);
|
|
entrezCode = (TextView)findViewById(R.id.entrezCode);
|
|
texteRecu = (TextView)findViewById(R.id.texteRecu);
|
|
logo = (ImageButton)findViewById(R.id.logo);
|
|
logo.setOnClickListener(logoListener);
|
|
sendPost.setOnClickListener(sendPostListener);
|
|
sendComment.setOnClickListener(sendCommentListener);
|
|
|
|
//This code allows connecting to the internet without doing so in a new thread.
|
|
if (android.os.Build.VERSION.SDK_INT > 9) {
|
|
StrictMode.ThreadPolicy policy =
|
|
new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
|
StrictMode.setThreadPolicy(policy);
|
|
}
|
|
|
|
//Handler that receives the data from the bluetooth device.
|
|
//Any manipulation of the received data must be done here (after the messageFinal assignment to msg.obj).
|
|
bluetoothIn = new Handler() {
|
|
public void handleMessage(android.os.Message msg) {
|
|
if (msg.what == handlerState) {
|
|
toast(messageFinal);
|
|
messageFinal += (String) msg.obj; //for some reason removing the + causes it to remove the first character
|
|
texteRecu.setText(messageFinal);
|
|
if (messageFinal.matches("[\\s\\S]*\\w\\w;[\\s\\S]*")) {
|
|
char command = messageFinal.charAt(messageFinal.indexOf(";")-2);
|
|
char arg = messageFinal.charAt(messageFinal.indexOf(";")-1);
|
|
toast("command = " + command + "\narg = " + arg);
|
|
if (command == 's') {
|
|
for (int i = 0; i < subCommands.length; i++) {
|
|
if (arg == subCommands[i]) {
|
|
subreddit = subreddits[i];
|
|
}
|
|
}
|
|
getPost("https://reddit.com/r/"+subreddit+".json");
|
|
|
|
}
|
|
else if (command == 'p') {
|
|
postNumber = arg-65;
|
|
try {
|
|
getComments("https://reddit.com/" + postIds.get(postNumber) + ".json");
|
|
toast("Post ID: "+ postIds.get(postNumber));
|
|
} catch (ArrayIndexOutOfBoundsException e) {
|
|
toast("Couldn't find a valid post rank, defaulting to the first post.");
|
|
getComments("https://reddit.com/" + postIds.get(0) + ".json");
|
|
}
|
|
}
|
|
else if (command == 'a' && arg == 'k') {
|
|
sendString();
|
|
}
|
|
else if (command == 'n' && arg == 'p') {
|
|
/*if (messageAEnvoyer.substring(progressionPage).length() > 5000) {
|
|
progressionPage += 5000;
|
|
}*/
|
|
progressionEnvoi = 0;
|
|
sendString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
// connection methods are best here in case program goes into the background etc
|
|
checkBluetooth();
|
|
}
|
|
|
|
|
|
|
|
//Tapping on the logo retries the connection if it failed.
|
|
private OnClickListener logoListener = new OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
codeSurNotice.setText("Connexion en cours...");
|
|
try {
|
|
init();
|
|
} catch (IOException e2) {
|
|
|
|
}
|
|
codeSurNotice.setText(defaut);
|
|
}
|
|
};
|
|
|
|
//Listener for the "send post" button. Is debug and planned to be removed.
|
|
private OnClickListener sendPostListener = new OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
messageFinal = "";
|
|
if (inStream != null) {
|
|
beginListenForData();
|
|
|
|
getPost("https://reddit.com/r/" + subreddit + ".json");
|
|
sendString();
|
|
|
|
} else {
|
|
toast(connectionError);
|
|
}
|
|
|
|
|
|
}
|
|
};
|
|
|
|
//Listener for the "send comment" button, is also debug.
|
|
private OnClickListener sendCommentListener = new OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
currentView = false;
|
|
messageFinal = "";
|
|
if (inStream != null) {
|
|
beginListenForData();
|
|
|
|
try {
|
|
getComments("https://reddit.com/" + postIds.get(postNumber) + ".json");
|
|
} catch (ArrayIndexOutOfBoundsException e) {
|
|
toast("Index out of bounds!");
|
|
}
|
|
toast("Post ID: "+ postIds.get(postNumber));
|
|
sendString();
|
|
|
|
} else {
|
|
toast(connectionError);
|
|
}
|
|
|
|
|
|
}
|
|
};
|
|
|
|
void sendString() {
|
|
String aEnvoyer = "";
|
|
messageFinal = "";
|
|
int progTotale = progressionEnvoi + progressionPage;
|
|
//progressionEnvoi = 0;
|
|
if (messageAEnvoyer.substring(progressionPage).length() > 1000 && progressionEnvoi < 4000
|
|
&& messageAEnvoyer.substring(progTotale, progTotale+1000).length() > 1000) {
|
|
aEnvoyer = messageAEnvoyer.substring(
|
|
progTotale, progTotale + 1000) + ",\"";
|
|
|
|
progressionEnvoi += 1000;
|
|
} else if (messageAEnvoyer.length() > progressionPage+5000){
|
|
int max = messageAEnvoyer.lastIndexOf(messageAEnvoyer.substring(progTotale,progTotale+1000),'>');
|
|
boolean mettreChevron = false;
|
|
if (max == -1) { //no occurrence of '>'
|
|
max = messageAEnvoyer.lastIndexOf(messageAEnvoyer.substring(progTotale,progTotale+1000),'\n');
|
|
if (max == -1) //no occurrence of '\n'
|
|
max = progressionEnvoi+progressionPage+1000;
|
|
mettreChevron = true; //there's no occurrence of '>' so we add one
|
|
}
|
|
|
|
aEnvoyer = messageAEnvoyer.substring(progressionEnvoi+progressionPage, max);
|
|
if (mettreChevron) {
|
|
aEnvoyer += '>';
|
|
//inserts a '<' after
|
|
messageAEnvoyer = messageAEnvoyer.substring(0, progTotale+max) + '<' + messageAEnvoyer.substring(progTotale+max+1);
|
|
}
|
|
aEnvoyer += ";\"";
|
|
progressionPage += messageAEnvoyer.lastIndexOf('>', progressionEnvoi+progressionPage);
|
|
} else {
|
|
aEnvoyer = messageAEnvoyer.substring(progressionEnvoi+progressionPage) + "\"";
|
|
}
|
|
try {
|
|
write(aEnvoyer);
|
|
} catch (IOException e) {
|
|
|
|
} catch (NullPointerException e) {
|
|
toast(connectionError);
|
|
}
|
|
}
|
|
|
|
//Parses the json from a reddit url containing comments.
|
|
//Don't try to understand this, it works, that's all you need to know.
|
|
void getComments(String url) {
|
|
|
|
String str = "test";
|
|
try {
|
|
str = getText(url);
|
|
} catch (Exception e) {
|
|
toast("Erreur de connexion");
|
|
}
|
|
toast(str);
|
|
String result = "";
|
|
String textPostContent = "";
|
|
String commentText = "";
|
|
String commentAuthor = "";
|
|
String commentScore = "";
|
|
String[] jsonAttributes = {"selftext", "title"};
|
|
String[] cmtVars = {commentAuthor, commentScore, commentText};
|
|
String[] cmtAttributes = {"replies", "author", "score", "body"};
|
|
|
|
ArrayList<Integer> commentLvls = new ArrayList<Integer>();
|
|
int currentComment = -1;
|
|
//first, browse through the string
|
|
int commentLvl = 1; //that way it's set to 1 after the }}], "after" of the text post
|
|
|
|
System.out.println("Beginning comment level analysis");
|
|
for (int i = 10; i < str.length(); i++) {
|
|
if (str.startsWith("}}], \"after\"", i)) {
|
|
commentLvl--;
|
|
} else if (str.startsWith("[{\"kind\": \"t1\"", i)) {
|
|
commentLvl++;
|
|
commentLvls.add(commentLvl);
|
|
|
|
} else if (str.startsWith(" {\"kind\": \"t1\"", i)) {
|
|
commentLvls.add(commentLvl);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < str.length(); i++) {
|
|
if (str.startsWith("{\"kind\": \"t3\"", i)) {
|
|
int j = 0;
|
|
while (!str.substring(i - 1, i + 11).equals("}}], \"after\"")) {
|
|
i++;
|
|
if (j < jsonAttributes.length && str.startsWith("\"" + jsonAttributes[j] + "\": ", i)) {
|
|
i += jsonAttributes[j].length() + 4;
|
|
int end = 0;
|
|
i++;
|
|
end = i;
|
|
while (!str.substring(end - 1, end + 3).equals("\", \"")) {
|
|
end++;
|
|
}
|
|
end--;
|
|
if (j == 1)
|
|
textPostContent = str.substring(i, end) + "\n" + textPostContent;
|
|
else
|
|
textPostContent += str.substring(i, end);
|
|
j++;
|
|
}
|
|
}
|
|
result += "<t " + textPostContent + "> \n";
|
|
} else if (str.startsWith("{\"kind\": \"t1\"", i)) {
|
|
currentComment++;
|
|
int l = i;
|
|
int j = 0;
|
|
int k = 0;
|
|
while (!str.substring(l - 1, l + 11).equals("}}], \"after\"")
|
|
&& !str.substring(l - 1, l + 16).equals("}}, {\"kind\": \"t1\"")) {
|
|
l++;
|
|
if (j < cmtAttributes.length && str.startsWith("\"" + cmtAttributes[j] + "\": ", l)) {
|
|
l += cmtAttributes[j].length() + 4;
|
|
|
|
int end = l;
|
|
if (j == 0) {
|
|
|
|
l += 57;
|
|
do {
|
|
if (str.startsWith("{\"kind\": \"t1\"", l)) {
|
|
k++;
|
|
}
|
|
if (str.startsWith("}}], \"after\"", l)) {
|
|
k--;
|
|
}
|
|
if (str.startsWith("}}, {\"kind\": \"t1\"", l)) {
|
|
l += 10;
|
|
}
|
|
l++;
|
|
} while (k != 0);
|
|
l++;
|
|
} else {
|
|
if (j != 2) {
|
|
while (!str.substring(end - 1, end + 3).equals("\", \"")) {
|
|
end++;
|
|
}
|
|
end--;
|
|
l++;
|
|
} else {
|
|
end = str.indexOf(',', l);
|
|
}
|
|
cmtVars[j - 1] = str.substring(l, end);
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
result += "<" + commentLvls.get(currentComment) + " " + cmtVars[2]
|
|
+ "\n/u/" + cmtVars[0] + " " + cmtVars[1] + " upvotes>";
|
|
}
|
|
}
|
|
result = modifyText(result);
|
|
messageAEnvoyer = result;
|
|
progressionEnvoi = 0;
|
|
sendString();
|
|
}
|
|
|
|
//Parses the json of a reddit sub (which contains posts)
|
|
void getPost(String url) {
|
|
String str = "test";
|
|
//connects to the given url
|
|
try {
|
|
str = getText(url);
|
|
} catch (Exception e) {
|
|
toast("Erreur de connexion");
|
|
}
|
|
|
|
String posts = "";
|
|
String currentPostTitle = "";
|
|
String currentPostUser = "";
|
|
String currentPostId = "";
|
|
String currentPostSub = "";
|
|
String currentPostUrl = "";
|
|
String currentPostScore = "";
|
|
String currentPostCmts = "";
|
|
String[] postAttributes = {currentPostUrl, currentPostSub, currentPostId, currentPostUser, currentPostScore, currentPostCmts, currentPostTitle};
|
|
String[] jsonAttributes = {"domain", "subreddit", "id", "author", "score", "num_comments", "title"};
|
|
|
|
for (int i = 0; i < str.length(); i++) { //browses through the string
|
|
if (str.startsWith("{\"kind\": \"t3\"", i)) { //beginning of post
|
|
int j = 0;
|
|
while (!str.substring(i - 1, i + 27).equals("}}, {\"kind\": \"t3\", \"data\": {") //loops while post is not finished
|
|
&& !str.substring(i - 1, i + 11).equals("}}], \"after\"")) {
|
|
i++;
|
|
if (j < jsonAttributes.length && str.startsWith("\"" + jsonAttributes[j] + "\": ", i)) { //assigns values of attributes to their variables
|
|
i += jsonAttributes[j].length() + 4;
|
|
int end = 0;
|
|
if (j == 4 || j == 5)
|
|
end = str.indexOf(',', i);
|
|
else {
|
|
i++;
|
|
end = i;
|
|
while (!str.substring(end - 1, end + 3).equals("\", \"")) {
|
|
end++;
|
|
}
|
|
end--;
|
|
}
|
|
postAttributes[j] = str.substring(i, end);
|
|
j++;
|
|
}
|
|
}
|
|
if (postAttributes[0].startsWith("self."))
|
|
postAttributes[0] = "self";
|
|
else
|
|
postAttributes[0] = "ext.link";
|
|
|
|
postIds.add(postAttributes[2]);
|
|
posts += "<p " + postAttributes[6] + "\n" + postAttributes[0] + " /r/" + postAttributes[1]
|
|
+ " /u/" + postAttributes[3] + " " + postAttributes[4] + " upvotes " + postAttributes[5] + " comments>\n";
|
|
}
|
|
|
|
}
|
|
|
|
messageAEnvoyer = modifyText(posts);
|
|
progressionEnvoi = 0;
|
|
sendString();
|
|
}
|
|
|
|
//Connects to a given url
|
|
public String getText(String url) throws Exception {
|
|
URL website = new URL(url);
|
|
URLConnection connection = website.openConnection();
|
|
connection.setRequestProperty("User-Agent", "android:com.zezombye.caddit:v1.0 (by /u/Zezombye)");
|
|
BufferedReader in = new BufferedReader(
|
|
new InputStreamReader(
|
|
connection.getInputStream()));
|
|
|
|
StringBuilder response = new StringBuilder();
|
|
String inputLine;
|
|
|
|
while ((inputLine = in.readLine()) != null)
|
|
response.append(inputLine);
|
|
|
|
in.close();
|
|
return response.toString();
|
|
}
|
|
|
|
//Replaces special characters in the json
|
|
static String modifyText(String str) {
|
|
str = str.replaceAll("\\\\\\\"", "&q;"); //replaces \" by &q
|
|
str = str.replaceAll("\\n", "\n"); //replaces \n by the LF character
|
|
str = str.replaceAll("\\\\\\\\", "\\\\"); //replaces \\ by \
|
|
str = str.replaceAll("&", "&");
|
|
return str;
|
|
}
|
|
|
|
} |