<commit_before>package com.nutomic.syncthingandroid.syncthing;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.WebGuiActivity;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * Holds the native syncthing instance and provides an API to access it.
 */
public class SyncthingService extends Service {

	private static final String TAG = "SyncthingService";

	private static final int NOTIFICATION_ID = 1;

	/**
	 * Path to the native, integrated syncthing binary, relative to the data folder
	 */
	private static final String BINARY_NAME = "lib/libsyncthing.so";

	/**
	 * Interval in ms, at which connections to the web gui are performed on first start
	 * to find out if it's online.
	 */
	private static final long WEB_GUI_POLL_INTERVAL = 100;

	/**
	 * File in the config folder that contains configuration.
	 */
	private static final String CONFIG_FILE = "config.xml";

	private RestApi mApi;

	private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);

	/**
	 * Callback for when the Syncthing web interface becomes first available after service start.
	 */
	public interface OnWebGuiAvailableListener {
		public void onWebGuiAvailable();
	}

	private LinkedList<OnWebGuiAvailableListener> mOnWebGuiAvailableListeners =
			new LinkedList<OnWebGuiAvailableListener>();

	private boolean mIsWebGuiAvailable = false;

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return START_STICKY;
	}

	/**
	 * Thrown when execution of the native syncthing binary returns an error.
	 * Prints the syncthing log.
	 */
	public static class NativeExecutionException extends RuntimeException {

		private final String mLog;

		public NativeExecutionException(String message, String log) {
			super(message);
			mLog = log;
		}

		@Override
		public String getMessage() {
			return super.getMessage() + "\n" + mLog;
		}
	}
	/**
	 * Runs the syncthing binary from command line, and prints its output to logcat.
	 */
	private class NativeSyncthingRunnable implements Runnable {
		@Override
		public void run() throws NativeExecutionException {
			if (isFirstStart(SyncthingService.this)) {
				copyDefaultConfig();
			}
			updateConfig();

			DataOutputStream dos = null;
			InputStreamReader isr = null;
			int ret = 1;
			String log = "";
			try	{
				Process p = Runtime.getRuntime().exec("sh");
				dos = new DataOutputStream(p.getOutputStream());
				// Set home directory to sdcard (so the "create repo" hint makes sense)
				dos.writeBytes("HOME=" +
						Environment.getExternalStorageDirectory().toString() + "\n");
				// Set syncthing config folder to app data folder.
				dos.writeBytes(getApplicationInfo().dataDir + "/" + BINARY_NAME + " " +
						"-home " + getApplicationInfo().dataDir + "\n");
				dos.writeBytes("exit\n");
				dos.flush();

				ret = p.waitFor();

				// Write syncthing binary output to log.
				// NOTE: This is only done on shutdown, not in real time.
				isr = new InputStreamReader(p.getInputStream());
				BufferedReader stdout = new BufferedReader(isr);
				String line;
				while((line = stdout.readLine()) != null) {
					log += "stderr: " + line + "\n";
					Log.w(TAG, "stderr: " + line);
				}
				isr = new InputStreamReader(p.getErrorStream());
				BufferedReader stderr = new BufferedReader(isr);
				while((line = stderr.readLine()) != null) {
					log += "stdout: " + line + "\n";
					Log.i(TAG, "stdout: " + line);
				}
			}
			catch(IOException e) {
				Log.e(TAG, "Failed to execute syncthing binary or read output", e);
			}<commit_msg>Insert missing version 0.3.1 version bump into history.<commit_after>package com.nutomic.syncthingandroid.syncthing;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.WebGuiActivity;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * Holds the native syncthing instance and provides an API to access it.
 */
public class SyncthingService extends Service {

	private static final String TAG = "SyncthingService";

	private static final int NOTIFICATION_ID = 1;

	/**
	 * Path to the native, integrated syncthing binary, relative to the data folder
	 */
	private static final String BINARY_NAME = "lib/libsyncthing.so";

	/**
	 * Interval in ms, at which connections to the web gui are performed on first start
	 * to find out if it's online.
	 */
	private static final long WEB_GUI_POLL_INTERVAL = 100;

	/**
	 * File in the config folder that contains configuration.
	 */
	private static final String CONFIG_FILE = "config.xml";

	private RestApi mApi;

	private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);

	/**
	 * Callback for when the Syncthing web interface becomes first available after service start.
	 */
	public interface OnWebGuiAvailableListener {
		public void onWebGuiAvailable();
	}

	private LinkedList<OnWebGuiAvailableListener> mOnWebGuiAvailableListeners =
			new LinkedList<OnWebGuiAvailableListener>();

	private boolean mIsWebGuiAvailable = false;

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return START_STICKY;
	}

	/**
	 * Thrown when execution of the native syncthing binary returns an error.
	 * Prints the syncthing log.
	 */
	public static class NativeExecutionException extends RuntimeException {

		private final String mLog;

		public NativeExecutionException(String message, String log) {
			super(message);
			mLog = log;
		}

		@Override
		public String getMessage() {
			return super.getMessage() + "\n" + mLog;
		}
	}
	/**
	 * Runs the syncthing binary from command line, and prints its output to logcat.
	 */
	private class NativeSyncthingRunnable implements Runnable {
		@Override
		public void run() throws NativeExecutionException {
			if (isFirstStart(SyncthingService.this)) {
				copyDefaultConfig();
			}
			updateConfig();

			DataOutputStream dos = null;
			InputStreamReader isr = null;
			int ret = 1;
			String log = "";
			try	{
				Process p = Runtime.getRuntime().exec("sh");
				dos = new DataOutputStream(p.getOutputStream());
				// Set home directory to data folder for syncthing to use.
				dos.writeBytes("HOME=" + getApplicationInfo().dataDir + "\n");
				// Call syncthing with -home (as it would otherwise use "~/.config/syncthing/".
				dos.writeBytes(getApplicationInfo().dataDir + "/" + BINARY_NAME + " " +
						"-home " + getApplicationInfo().dataDir + "\n");
				dos.writeBytes("exit\n");
				dos.flush();

				ret = p.waitFor();

				// Write syncthing binary output to log.
				// NOTE: This is only done on shutdown, not live.
				isr = new InputStreamReader(p.getInputStream());
				BufferedReader stdout = new BufferedReader(isr);
				String line;
				while((line = stdout.readLine()) != null) {
					log += "stderr: " + line + "\n";
					Log.w(TAG, "stderr: " + line);
				}
				isr = new InputStreamReader(p.getErrorStream());
				BufferedReader stderr = new BufferedReader(isr);
				while((line = stderr.readLine()) != null) {
					log += "stdout: " + line + "\n";
					Log.i(TAG, "stdout: " + line);
				}
			}
			catch(IOException e) {
				Log.e(TAG, "Failed to execute syncthing binary or read output", e);
			}
{'fraction_non_alphanumeric': 0.10495295212490953, 'fraction_numerical': 0.0021714403887912316, 'mean_word_length': 4.172192513368984, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5760423', 'n_tokens_mistral': 3195, 'n_tokens_neox': 2832, 'n_words': 799}