├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── pddstudio
│ │ └── tinyifttt
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── com
│ │ │ └── pddstudio
│ │ │ └── tinyifttt
│ │ │ ├── LoginActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── adapter
│ │ │ └── TinyActionItem.java
│ │ │ ├── connection
│ │ │ ├── ConnectionInfo.java
│ │ │ ├── SendActionRequest.java
│ │ │ └── ServerConnection.java
│ │ │ └── utils
│ │ │ └── Dialog.java
│ └── res
│ │ ├── drawable
│ │ └── logo.png
│ │ ├── layout
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ └── item_tiny_action.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-v19
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── pddstudio
│ └── tinyifttt
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── readme_logo.png
├── settings.gradle
├── test-tinyIFTTT.sh
├── tinyIFTTT-android-app-sample.png
├── tinyifttt-model
├── .gitignore
├── build.gradle
└── src
│ └── main
│ └── java
│ └── com
│ └── pddstudio
│ └── tinyifttt
│ └── models
│ ├── TinyAction.java
│ └── TinyActionReceivedListener.java
└── tinyifttt-server
├── .gitignore
├── build.gradle
├── src
└── main
│ └── java
│ └── com
│ └── pddstudio
│ └── tinyifttt
│ └── server
│ ├── ActionExecutor.java
│ ├── ServerRunner.java
│ ├── TinyIFTTT.java
│ ├── async
│ └── ClientConnectionListener.java
│ └── utils
│ ├── Log.java
│ └── Logger.java
└── tiny-sample.json
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | tinyIFTT
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # tinyIFTTT - If This Then That
6 | A tiny, lightweight, easy to use and customize IFTTT (if this, then that) server and (Android) client.
7 |
8 | The ideal thing for hackers and home-automation freaks.
9 |
10 | ### What is IFTTT?
11 |
12 | IFTTT is a mechanism that allows users to create chains of simple conditional statements, called "recipes", which are triggered based on changes to other user interactions. IFTTT is an abbreviation of "If This Then That".
13 |
14 | *Original Source: [Wikipedia](https://en.wikipedia.org/wiki/IFTTT) | Some changes where made in the definition above*
15 |
16 | ### What does tinyIFTTT do?
17 |
18 | Basically, tinyIFTTT can do **everything** that you could do on your personal computer or server, like for example upgrading your server's linux packages, shutting down or rebooting your server, triggering self-written scripts on your RaspberryPi and much more.
19 |
20 | tinyIFTTT aims to let you easily configure different kind of receipes/actions which you can execute remotely from your smartphone using the tinyIFTTT Android-App.
21 |
22 | This repository contains the source and pre-packaged binaries for **both** components, the **Android-App** and the **tinyIFTTT Server Module**
23 |
24 | ### Why does tinyIFTTT exist?
25 |
26 | One day, I was hacking on my RaspberryPi and wrote some scripts to automatically make backups on my NAS.
27 |
28 | As soon as I was done and got everything set up as I needed it, I got sick of using a SSH Client on my smartphone for typing all the commands I need for my script to be executed.
29 |
30 | As an Android Developer I thought it would be nice to develop a kind of IFTTT mechanism which allows me to control whatever I want to (as long as I configured it) directly from my smartphone without using any kind of SSH session.
31 |
32 | All I wanted to do was to press a button and the action should be executed.
33 |
34 | This was the beginning of tinyIFTTT.
35 |
36 | ### What's in the package
37 | tinyIFTTT comes with a plug-and-play server component that you can immediately run on your machine.
38 |
39 | All you need is a machine with a JVM installed, nothing else is required to get everything up and running (well, except of your receipes of course).
40 |
41 | ### Getting Started with tinyIFTTT
42 |
43 | This section gets more into detail how you can get the tinyIFTTT Server Module and the tinyIFTTT Android-App up and running.
44 |
45 | #### Getting the Server Module up and running
46 |
47 | There are two ways to get started with the tinyIFTTT Server Module.
48 |
49 | Either download the [prepackaged binary from the release page](https://github.com/PDDStudio/tinyIFTTT/releases) or build it yourself using gradle:
50 |
51 | ```
52 | ./gradlew tinyIFTTTserver
53 | ```
54 |
55 | All you have to do now is running the `.jar` file using the desired port as parameter (1337 by default) and the location to your config file which includes all specified receipes.
56 |
57 | For example:
58 |
59 | ```java
60 | java -jar tinyIFTTT-server-full-1.0.jar --port 1337 --config ./tinyifttt-config.json
61 | ```
62 |
63 | If you need help:
64 |
65 | ```java
66 | java -jar tinyIFTTT-server-full-1.0.jar --help
67 | ```
68 |
69 | #### Getting the Android App up and running
70 |
71 | There are to ways to get the Android App up and running.
72 | Either download the [prepackaged apk from the release page](https://github.com/PDDStudio/tinyIFTTT/releases) or import the project into AndroidStudio and build it yourself.
73 |
74 | Simply install the application and you're ready to go.
75 |
76 | ### Configuring tinyIFTTT
77 | To configure tinyIFTTT all you have to do is writing a simple file which contains your receipes using `json`-format.
78 | For a life preview check out [the sample json config file here](https://github.com/PDDStudio/tinyIFTTT/blob/master/tinyifttt-server/tiny-sample.json).
79 | The config file holds an array of your receipes. This can contain as much receipes as you want to configure.
80 | Every receipe is build using the same mechanism:
81 |
82 | ```json
83 | {
84 | "actionIdentifier" : 1,
85 | "actionTitle" : "Home PC Shutdown",
86 | "actionDescription" : "Power off my machine upstairs.",
87 | "actionExec" : [ "shutdown", "-h", "now" ]
88 | }
89 | ```
90 |
91 | Explanation:
92 |
93 | - **actionIdentifier**: This identifier is used to validate the action you want to be executed. **Make sure this number is unique and not used twice.**
94 | - **actionTitle**: Here you can specify the title you want to be displayed for this receipe on your smartphone.
95 | - **actionDescription**: Here you can specify the description you want to be displayed for this receipe on your smartphone.
96 | - **actionExec**: An array of String which represents the commands you would execute in your terminal / the process you want to be started with (optional) parameters.
97 |
98 | ### Usage
99 |
100 | As soon as you have both modules up and running you can start connecting to your server using the tinyIFTTT Android-App.
101 |
102 | Once your tinyIFTTT Server is running you should see something similar to this in your terminal:
103 |
104 | ```
105 | [03-30-2016|18:26:57][TinyIFTTT::/D] tinyIFTTT Server configuration loaded.
106 | [03-30-2016|18:26:57][TinyIFTTT::/D] Starting tinyIFTTT Server...
107 | ```
108 |
109 | This means you're good to go and can connect to your tinyIFTTT Server via the Android-App.
110 |
111 | Enter the IP-Address of the machine you're running the tinyIFTTT Server Module on and the Port you specified when launching the tinyIFTTT Server.
112 |
113 | If desired you can save the server connection information in case you don't want to re-enter it all the time.
114 |
115 | Simply click the `Connect` Button and you'll see a list of your specified receipes.
116 |
117 | Clicking on the specified receipe will execute the desired action.
118 |
119 | More samples and demonstrations can be found in the [Samples & Demonstration](https://github.com/PDDStudio/tinyIFTTT#samples--demonstration) Section.
120 |
121 | ### Samples & Demonstration
122 |
123 | Assuming we have the following config file filled with the receipes we want to use:
124 |
125 | ```json
126 | [
127 | {
128 | "actionIdentifier" : 1,
129 | "actionTitle" : "Home PC Shutdown",
130 | "actionDescription" : "Power off my machine upstairs.",
131 | "actionExec" : [ "shutdown", "-h", "now" ]
132 | },
133 | {
134 | "actionIdentifier" : 2,
135 | "actionTitle" : "Home PC Reboot",
136 | "actionDescription" : "Reboot my machine upstairs.",
137 | "actionExec" : [ "reboot" ]
138 | },
139 | {
140 | "actionIdentifier" : 3,
141 | "actionTitle" : "Raspberry Pi Update",
142 | "actionDescription" : "Update the packages on my Pi.",
143 | "actionExec" : [ "apt-get", "update" ]
144 | },
145 | {
146 | "actionIdentifier" : 4,
147 | "actionTitle" : "Raspberry Pi XBMC",
148 | "actionDescription" : "Start XBMC on my Pi.",
149 | "actionExec" : [ "xbmc" ]
150 | },
151 | {
152 | "actionIdentifier" : 5,
153 | "actionTitle" : "Run Backup Script",
154 | "actionDescription" : "Run the backup script to save my data stored on my NAS.",
155 | "actionExec" : [ "sh", "/opt/backup/backup_all.sh" ]
156 | },
157 | {
158 | "actionIdentifier" : 6,
159 | "actionTitle" : "Kitchen Light",
160 | "actionDescription" : "Switch on the Light in the kitchen.",
161 | "actionExec" : [ "python", "/opt/mods/switch_light.py" ]
162 | },
163 | {
164 | "actionIdentifier" : 7,
165 | "actionTitle" : "Android TV",
166 | "actionDescription" : "Power on/off my AndroidTV.",
167 | "actionExec" : [ "sh", "/opt/mods/tv_power.sh" ]
168 | },
169 | {
170 | "actionIdentifier" : 8,
171 | "actionTitle" : "Ping Google.com",
172 | "actionDescription" : "Ping Google's Website to make sure the internet connection is available.",
173 | "actionExec" : [ "ping", "google.com" ]
174 | }
175 | ]
176 | ```
177 |
178 | This is how it would look like inside the tinyIFTTT Android-App
179 |
180 | 
181 |
182 |
183 | In case you want to see a live demonstration, feel free to have a look at the [YouTube Video](https://www.youtube.com/watch?v=HpCYYrplYZ8) I recorded.
184 |
185 |
186 | ### About & Contact
187 | - In case you've a question feel free to hit me up via E-Mail (patrick.pddstudio/gmail)
188 |
189 | ### Special Thanks & Contributors
190 | - A Special Thanks goes to [Manuel Labrador Vianthi (MLV)](https://plus.google.com/+ManuelLabradorVianthi/) for creating the tinyIFTTT Logo for the Android-App
191 |
192 | ### License
193 | Copyright 2016 Patrick J
194 |
195 | Licensed under the Apache License, Version 2.0 (the "License");
196 | you may not use this file except in compliance with the License.
197 | You may obtain a copy of the License at
198 |
199 | http://www.apache.org/licenses/LICENSE-2.0
200 |
201 | Unless required by applicable law or agreed to in writing, software
202 | distributed under the License is distributed on an "AS IS" BASIS,
203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
204 | See the License for the specific language governing permissions and
205 | limitations under the License.
206 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "24.0.0 rc1"
6 |
7 | defaultConfig {
8 | applicationId "com.pddstudio.tinyifttt"
9 | minSdkVersion 16
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.2.1'
26 | compile 'com.android.support:design:23.2.1'
27 | compile 'com.android.support:cardview-v7:23.2.1'
28 | compile 'com.google.code.gson:gson:2.6.2'
29 | compile('com.mikepenz:fastadapter:1.3.0@aar') {
30 | transitive = true
31 | }
32 | compile project(':tinyifttt-model')
33 | }
34 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/pddstudio/Android/Sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/pddstudio/tinyifttt/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt;
2 |
3 | import android.content.Intent;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.preference.PreferenceManager;
7 | import android.support.design.widget.TextInputLayout;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.CheckBox;
12 | import android.widget.EditText;
13 | import android.widget.Toast;
14 |
15 | import com.pddstudio.tinyifttt.connection.ConnectionInfo;
16 |
17 | public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
18 |
19 | private static final String SAVED_HOST_IP = "remoteHost";
20 | private static final String SAVED_HOST_PORT = "remotePort";
21 | public static final int SESSION_END_CODE = 42;
22 |
23 | private TextInputLayout mIpInputLayout;
24 | private TextInputLayout mPortInputLayout;
25 | private EditText mIpAddressEditText;
26 | private EditText mPortEditText;
27 | private Button mConnectButton;
28 | private CheckBox mSaveLoginsCheckBox;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_login);
34 | //assign the views
35 | mIpInputLayout = (TextInputLayout) findViewById(R.id.ipInputLayout);
36 | if(mIpInputLayout != null) mIpInputLayout.setErrorEnabled(true);
37 |
38 | mPortInputLayout = (TextInputLayout) findViewById(R.id.portInputLayout);
39 | if(mPortInputLayout != null) mPortInputLayout.setErrorEnabled(true);
40 |
41 | mIpAddressEditText = (EditText) findViewById(R.id.ipAddressEditText);
42 | mPortEditText = (EditText) findViewById(R.id.portEditText);
43 | mSaveLoginsCheckBox = (CheckBox) findViewById(R.id.saveLoginCheckbox);
44 |
45 | mConnectButton = (Button) findViewById(R.id.connectButton);
46 | if(mConnectButton != null) mConnectButton.setOnClickListener(this);
47 |
48 | //load the configuration - if saved
49 | loadConnectionInfo();
50 | }
51 |
52 | @Override
53 | public void onClick(View v) {
54 | //get the ip and port and set the connection info
55 | if(mIpAddressEditText.getText().toString().isEmpty()) mIpInputLayout.setError(getString(R.string.error_ip_missing));
56 | else if(mPortEditText.getText().toString().isEmpty()) mPortInputLayout.setError(getString(R.string.error_port_missing));
57 | else {
58 | try {
59 | int serverPort = Integer.parseInt(mPortEditText.getText().toString());
60 | if(serverPort < 0) throw new NumberFormatException("Can't be lower than 0");
61 | String serverIp = mIpAddressEditText.getText().toString();
62 |
63 | if(mSaveLoginsCheckBox.isChecked()) saveConnectionInfo(serverIp, serverPort);
64 | ConnectionInfo.setConnectionData(serverIp, serverPort);
65 | Intent data = new Intent(this, MainActivity.class);
66 | startActivityForResult(data, SESSION_END_CODE);
67 | } catch (NumberFormatException nnf) {
68 | mPortInputLayout.setError(getString(R.string.error_port_missing));
69 | }
70 | }
71 | }
72 |
73 | @Override
74 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
75 | // Check which request we're responding to
76 | if (requestCode == SESSION_END_CODE) {
77 | // Make sure the request was successful
78 | if (resultCode == RESULT_OK) {
79 | //FIXME: let the dialog not crash the application due to onSaveInstance
80 | //new Dialog().setContext(this)
81 | // .show(getSupportFragmentManager(), R.string.dialog_connection_closed_title, R.string.dialog_connection_closed_content);
82 | Toast.makeText(this, R.string.dialog_connection_closed_content, Toast.LENGTH_SHORT).show();
83 | }
84 | }
85 | }
86 |
87 | private void loadConnectionInfo() {
88 | //load the saved date (if any)
89 | SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
90 | String hostIp = sharedPreferences.getString(SAVED_HOST_IP, null);
91 | if(hostIp != null) mIpAddressEditText.setText(hostIp);
92 | int hostPort = sharedPreferences.getInt(SAVED_HOST_PORT, -1);
93 | if(hostPort != -1) mPortEditText.setText(""+hostPort);
94 | }
95 |
96 | private void saveConnectionInfo(String hostName, int hostPort) {
97 | SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
98 | sharedPreferences.edit().putString(SAVED_HOST_IP, hostName).putInt(SAVED_HOST_PORT, hostPort).apply();
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt;
2 |
3 | import android.app.Activity;
4 | import android.content.DialogInterface;
5 | import android.os.AsyncTask;
6 | import android.os.Bundle;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.LinearLayoutManager;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.support.v7.widget.Toolbar;
12 | import android.util.Log;
13 | import android.view.MenuItem;
14 | import android.view.View;
15 | import android.widget.Toast;
16 |
17 | import com.mikepenz.fastadapter.FastAdapter;
18 | import com.mikepenz.fastadapter.IAdapter;
19 | import com.mikepenz.fastadapter.IItem;
20 | import com.mikepenz.fastadapter.adapters.FastItemAdapter;
21 | import com.pddstudio.tinyifttt.adapter.TinyActionItem;
22 | import com.pddstudio.tinyifttt.connection.ConnectionInfo;
23 | import com.pddstudio.tinyifttt.connection.SendActionRequest;
24 | import com.pddstudio.tinyifttt.connection.ServerConnection;
25 | import com.pddstudio.tinyifttt.models.TinyAction;
26 | import com.pddstudio.tinyifttt.utils.Dialog;
27 |
28 | public class MainActivity extends AppCompatActivity implements ServerConnection.ConnectionCallback, FastAdapter.OnClickListener, SendActionRequest.Callback {
29 |
30 | private Toolbar mToolbar;
31 |
32 | private RecyclerView recyclerView;
33 | private RecyclerView.LayoutManager layoutManager;
34 | private FastItemAdapter fastAdapter;
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_main);
40 | //assign the views
41 | mToolbar = (Toolbar) findViewById(R.id.toolbar);
42 | setSupportActionBar(mToolbar);
43 | if(getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true);
44 |
45 | //execute the request
46 | ServerConnection serverConnection = new ServerConnection(ConnectionInfo.getConnectionInfo().getmRemoteHost(), ConnectionInfo.getConnectionInfo().getmRemotePort(), this);
47 | serverConnection.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
48 |
49 | recyclerView = (RecyclerView) findViewById(R.id.itemRecyclerView);
50 | layoutManager = new LinearLayoutManager(this);
51 | fastAdapter = new FastItemAdapter<>();
52 | fastAdapter.withOnClickListener(this);
53 | fastAdapter.withSelectable(false);
54 | recyclerView.setHasFixedSize(true);
55 | recyclerView.setLayoutManager(layoutManager);
56 | recyclerView.setAdapter(fastAdapter);
57 | }
58 |
59 | @Override
60 | public boolean onOptionsItemSelected(MenuItem item) {
61 | switch (item.getItemId()) {
62 | // Respond to the action bar's Up/Home button
63 | case android.R.id.home:
64 | onBackPressed();
65 | return true;
66 | }
67 | return super.onOptionsItemSelected(item);
68 | }
69 |
70 | @Override
71 | public boolean onClick(View v, IAdapter adapter, IItem item, int position) {
72 | String serverIp = ConnectionInfo.getConnectionInfo().getmRemoteHost();
73 | int serverPort = ConnectionInfo.getConnectionInfo().getmRemotePort();
74 | new SendActionRequest(serverIp, serverPort, fastAdapter.getAdapterItem(position).getTinyAction()).sendRequest(this);
75 | return true;
76 | }
77 |
78 | @Override
79 | public void onActionSend(boolean success) {
80 | Log.d("MainActivity", "Action Send : " + success);
81 | if(success) showToast(getString(R.string.toast_action_send_success));
82 | else showToast(getString(R.string.toast_action_send_fail));
83 | }
84 |
85 | @Override
86 | public void onConnectingStarted() {
87 | Log.d("MainActivity", "onConnectingStarted()");
88 | }
89 |
90 | @Override
91 | public void onConnectingFailed(@Nullable Throwable throwable) {
92 | Log.d("MainActivity", "onConnectionFailed()");
93 | if(throwable != null) throwable.printStackTrace();
94 | new Dialog().setContext(this)
95 | .setOnClickListener(new DialogInterface.OnClickListener() {
96 | @Override
97 | public void onClick(DialogInterface dialog, int which) {
98 | MainActivity.this.finish();
99 | }
100 | })
101 | .show(getSupportFragmentManager(), getString(R.string.dialog_connection_failed_title), getString(R.string.dialog_connection_failed_content, throwable != null ? throwable.getMessage() : ""));
102 | }
103 |
104 | @Override
105 | public void onConnectingFinished() {
106 | //set the result code and finish the activity
107 | Log.d("MainActivity", "onConnectionFinished() called");
108 | setResult(Activity.RESULT_OK);
109 | finish();
110 | }
111 |
112 | @Override
113 | public void onTinyActionFound(TinyAction tinyAction) {
114 | Log.d("MainActivity", "TinyAction received: " + tinyAction.getActionIdentifier() + " Title: " + tinyAction.getActionTitle() + " Description: " + tinyAction.getActionDescription());
115 | fastAdapter.add(new TinyActionItem(tinyAction));
116 | }
117 |
118 | private void showToast(String message) {
119 | Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/adapter/TinyActionItem.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.View;
5 | import android.widget.TextView;
6 |
7 | import com.mikepenz.fastadapter.items.AbstractItem;
8 | import com.pddstudio.tinyifttt.R;
9 | import com.pddstudio.tinyifttt.models.TinyAction;
10 |
11 | /**
12 | * This Class was created by Patrick J
13 | * on 29.03.16. For more Details and Licensing
14 | * have a look at the README.md
15 | */
16 | public class TinyActionItem extends AbstractItem {
17 |
18 | private final TinyAction mTinyAction;
19 |
20 | public TinyActionItem(TinyAction tinyAction) {
21 | this.mTinyAction = tinyAction;
22 | }
23 |
24 | public TinyAction getTinyAction() {
25 | return mTinyAction;
26 | }
27 |
28 | @Override
29 | public int getType() {
30 | return R.id.tiny_action_item;
31 | }
32 |
33 | @Override
34 | public int getLayoutRes() {
35 | return R.layout.item_tiny_action;
36 | }
37 |
38 | @Override
39 | public void bindView(ViewHolder viewHolder) {
40 | super.bindView(viewHolder);
41 | viewHolder.actionTitle.setText(mTinyAction.getActionTitle());
42 | viewHolder.actionDescription.setText(mTinyAction.getActionDescription());
43 | }
44 |
45 | protected static class ViewHolder extends RecyclerView.ViewHolder {
46 |
47 | TextView actionTitle;
48 | TextView actionDescription;
49 |
50 | public ViewHolder(View itemView) {
51 | super(itemView);
52 | this.actionTitle = (TextView) itemView.findViewById(R.id.actionName);
53 | this.actionDescription = (TextView) itemView.findViewById(R.id.actionDescription);
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/connection/ConnectionInfo.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.connection;
2 |
3 | /**
4 | * This Class was created by Patrick J
5 | * on 30.03.16. For more Details and Licensing
6 | * have a look at the README.md
7 | */
8 | public class ConnectionInfo {
9 |
10 | private static ConnectionInfo mConnectionInfo;
11 |
12 | private String mRemoteHost;
13 | private int mRemotePort;
14 |
15 | private ConnectionInfo(String remoteHost, int remotePort) {
16 | this.mRemoteHost = remoteHost;
17 | this.mRemotePort = remotePort;
18 | }
19 |
20 | public static ConnectionInfo setConnectionData(String remoteHost, int remotePort) {
21 | mConnectionInfo = new ConnectionInfo(remoteHost, remotePort);
22 | return mConnectionInfo;
23 | }
24 |
25 | public static ConnectionInfo getConnectionInfo() {
26 | return mConnectionInfo;
27 | }
28 |
29 | public String getmRemoteHost() {
30 | return mRemoteHost;
31 | }
32 |
33 | public int getmRemotePort() {
34 | return mRemotePort;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/connection/SendActionRequest.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.connection;
2 |
3 | import android.os.AsyncTask;
4 | import android.support.annotation.Nullable;
5 | import android.util.Log;
6 |
7 | import com.google.gson.Gson;
8 | import com.pddstudio.tinyifttt.models.TinyAction;
9 |
10 | import java.io.BufferedWriter;
11 | import java.io.IOException;
12 | import java.io.OutputStream;
13 | import java.io.OutputStreamWriter;
14 | import java.net.Socket;
15 |
16 | /**
17 | * This Class was created by Patrick J
18 | * on 29.03.16. For more Details and Licensing
19 | * have a look at the README.md
20 | */
21 | public class SendActionRequest extends AsyncTask {
22 |
23 | public interface Callback {
24 | void onActionSend(boolean success);
25 | }
26 |
27 | private final String mServerHost;
28 | private final int mServerPort;
29 | private final TinyAction mTinyAction;
30 |
31 | private Callback mCallback;
32 |
33 | public SendActionRequest(String serverHost, int serverPort, TinyAction tinyAction) {
34 | this.mServerHost = serverHost;
35 | this.mServerPort = serverPort;
36 | this.mTinyAction = tinyAction;
37 | }
38 |
39 | public void sendRequest(@Nullable Callback callback) {
40 | Log.d("SendActionRequest", "sendRequest() called. Executing job. [" + mServerHost + ":" + mServerPort +"]");
41 | this.mCallback = callback;
42 | this.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
43 | }
44 |
45 | @Override
46 | protected Void doInBackground(Void... params) {
47 | //get the output stream and send the action we want to be executed
48 | try {
49 | Socket socket = new Socket(mServerHost, mServerPort);
50 | if(!socket.isConnected()) this.cancel(true);
51 | OutputStream outputStream = socket.getOutputStream();
52 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
53 | BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
54 | Gson gson = new Gson();
55 | bufferedWriter.write(gson.toJson(mTinyAction));
56 | bufferedWriter.newLine();
57 | bufferedWriter.flush();
58 | bufferedWriter.close();
59 | socket.close();
60 | } catch (IOException io) {
61 | io.printStackTrace();
62 | this.cancel(true);
63 | }
64 | Log.d("SendActionRequest", "Action Send!");
65 | return null;
66 | }
67 |
68 | @Override
69 | protected void onCancelled() {
70 | //notify the callback if set
71 | if(mCallback != null) mCallback.onActionSend(false);
72 | }
73 |
74 | @Override
75 | public void onPostExecute(Void v) {
76 | //notify the callback if set
77 | if(mCallback != null) mCallback.onActionSend(true);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/connection/ServerConnection.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.connection;
2 |
3 | import android.os.AsyncTask;
4 | import android.support.annotation.Nullable;
5 |
6 | import com.google.gson.Gson;
7 | import com.pddstudio.tinyifttt.models.TinyAction;
8 |
9 | import java.io.BufferedReader;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.InputStreamReader;
13 | import java.io.Serializable;
14 | import java.net.Socket;
15 |
16 | /**
17 | * This Class was created by Patrick J
18 | * on 29.03.16. For more Details and Licensing
19 | * have a look at the README.md
20 | */
21 | public class ServerConnection extends AsyncTask implements Serializable {
22 |
23 | public interface ConnectionCallback {
24 | void onConnectingStarted();
25 | void onConnectingFailed(@Nullable Throwable throwable);
26 | void onConnectingFinished();
27 | void onTinyActionFound(TinyAction tinyAction);
28 | }
29 |
30 | private final String mRemoteHost;
31 | private final int mRemotePort;
32 | private final ConnectionCallback mConnectionCallback;
33 |
34 | private Throwable mErrorThrowable;
35 |
36 | public ServerConnection(String hostName, int port, ConnectionCallback connectionCallback) {
37 | this.mRemoteHost = hostName;
38 | this.mRemotePort = port;
39 | this.mConnectionCallback = connectionCallback;
40 | }
41 |
42 | @Override
43 | public void onPreExecute() {
44 | mConnectionCallback.onConnectingStarted();
45 | }
46 |
47 | @Override
48 | protected Void doInBackground(Void... params) {
49 | //get the input stream and receive the available commands
50 | try {
51 | Socket socket = new Socket(mRemoteHost, mRemotePort);
52 | if(!socket.isConnected()) return null;
53 |
54 | InputStream inputStream = socket.getInputStream();
55 | InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
56 | BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
57 | Gson gson = new Gson();
58 | String response;
59 | while ((response = bufferedReader.readLine()) != null) {
60 | //parse the incoming string and notify the callback if it's not null
61 | TinyAction tinyAction = gson.fromJson(response, TinyAction.class);
62 | if(tinyAction != null) publishProgress(tinyAction);
63 | }
64 |
65 | bufferedReader.close();
66 | socket.close();
67 |
68 | } catch (IOException io) {
69 | this.mErrorThrowable = io;
70 | this.cancel(true);
71 | }
72 |
73 | return null;
74 | }
75 |
76 | @Override
77 | protected void onCancelled() {
78 | //notify the callback that something went wrong
79 | mConnectionCallback.onConnectingFailed(mErrorThrowable);
80 | }
81 |
82 | @Override
83 | protected void onProgressUpdate(TinyAction... values) {
84 | //we can be sure here that the array contains only one item
85 | mConnectionCallback.onTinyActionFound(values[0]);
86 | }
87 |
88 | @Override
89 | public void onPostExecute(Void v) {
90 | //notify the callback that the connection doesn't exist anymore
91 | mConnectionCallback.onConnectingFinished();
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/pddstudio/tinyifttt/utils/Dialog.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.utils;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.os.Bundle;
6 | import android.support.annotation.StringRes;
7 | import android.support.v4.app.DialogFragment;
8 | import android.support.v4.app.FragmentManager;
9 | import android.support.v7.app.AlertDialog;
10 | import android.util.Log;
11 |
12 | /**
13 | * This Class was created by Patrick J
14 | * on 30.03.16. For more Details and Licensing
15 | * have a look at the README.md
16 | */
17 | public class Dialog extends DialogFragment {
18 |
19 | private final String LOG_TAG = getClass().getSimpleName();
20 |
21 | private Context mContext;
22 | @StringRes private int mDialogTitle;
23 | @StringRes private int mDialogContent;
24 | private DialogInterface.OnClickListener mOnClickListener;
25 |
26 | private String mTitle;
27 | private String mContent;
28 |
29 | public Dialog setContext(Context context) {
30 | this.mContext = context;
31 | return this;
32 | }
33 |
34 | public Dialog setOnClickListener(DialogInterface.OnClickListener onClickListener) {
35 | this.mOnClickListener = onClickListener;
36 | return this;
37 | }
38 |
39 | public void show(FragmentManager fragmentManager, @StringRes int dialogTitle, @StringRes int dialogContent) {
40 | this.mDialogContent = dialogContent;
41 | this.mDialogTitle = dialogTitle;
42 | show(fragmentManager, "DIALOG");
43 | }
44 |
45 | public void show(FragmentManager fragmentManager, String dialogTitle, String dialogContent) {
46 | this.mTitle = dialogTitle;
47 | this.mContent = dialogContent;
48 | show(fragmentManager, "DIALOG");
49 | }
50 |
51 | @Override
52 | public android.app.Dialog onCreateDialog(Bundle savedInstance) {
53 | AlertDialog alertDialog;
54 | if(mTitle == null && mContent == null) {
55 | alertDialog = new AlertDialog.Builder(mContext)
56 | .setTitle(mDialogTitle)
57 | .setMessage(mDialogContent)
58 | .setPositiveButton(android.R.string.ok, mOnClickListener == null ? new DialogInterface.OnClickListener() {
59 | @Override
60 | public void onClick(DialogInterface dialog, int which) {
61 | Log.d(LOG_TAG, "onClick() for positive dialog action called");
62 | }
63 | } : mOnClickListener)
64 | .setCancelable(false)
65 | .create();
66 | } else {
67 | alertDialog = new AlertDialog.Builder(mContext)
68 | .setTitle(mTitle)
69 | .setMessage(mContent)
70 | .setPositiveButton(android.R.string.ok, mOnClickListener == null ? new DialogInterface.OnClickListener() {
71 | @Override
72 | public void onClick(DialogInterface dialog, int which) {
73 | Log.d(LOG_TAG, "onClick() for positive dialog action called");
74 | }
75 | } : mOnClickListener)
76 | .setCancelable(false)
77 | .create();
78 | }
79 | return alertDialog;
80 | }
81 |
82 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/drawable/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
25 |
26 |
30 |
31 |
37 |
38 |
39 |
40 |
44 |
45 |
51 |
52 |
53 |
54 |
60 |
61 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_tiny_action.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
28 |
29 |
40 |
41 |
42 |
43 |
48 |
49 |
58 |
59 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v19/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00897B
4 | #00695C
5 | #00897B
6 | #FAFAFA
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 20sp
6 | 14sp
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | tinyIFTTT
3 | tinyIFTTT Server IP-Address
4 | tinyIFTTT Server Port
5 | Remember Server IP-Address and Port
6 | Connect
7 | IP-Address can\'t be empty!
8 | Port can\'t be negative or empty!
9 | Action send successfully!
10 | Send action failed!
11 | Failed to connect!
12 | Unable to connect to tinyIFTTT Server:\n%s
13 | Server connection closed!
14 | The tinyIFTTT Server was shut down or is no longer reachable.
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/test/java/com/pddstudio/tinyifttt/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0-alpha5'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/readme_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/readme_logo.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':tinyifttt-server', ':tinyifttt-model'
2 |
--------------------------------------------------------------------------------
/test-tinyIFTTT.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | java -jar tinyifttt-server/build/libs/tinyifttt-server-full-1.0.jar -p 1337 -c ./tinyifttt-server/tiny-sample.json
3 |
--------------------------------------------------------------------------------
/tinyIFTTT-android-app-sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/tinyIFTTT/62ad6c11f885cac18ecae354c95414bd7d7fad63/tinyIFTTT-android-app-sample.png
--------------------------------------------------------------------------------
/tinyifttt-model/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/tinyifttt-model/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 |
3 | version = '1.0'
4 | sourceCompatibility = 1.7
5 | targetCompatibility = 1.7
6 |
7 | //create a single Jar with all dependencies
8 | task tinyIFTTmodels(type: Jar) {
9 | manifest {
10 | attributes 'Implementation-Title': 'tinyIFTT Model',
11 | 'Implementation-Version': version,
12 | 'Main-Class': 'com.pddstudio.tinyiftt.models.TinyAction'
13 | }
14 | baseName = project.name + '-full'
15 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
16 | with jar
17 | }
18 |
19 | //Get dependencies from Maven central repository
20 | repositories {
21 | mavenCentral()
22 | }
23 | dependencies {
24 | compile fileTree(dir: 'libs', include: ['*.jar'])
25 | }
--------------------------------------------------------------------------------
/tinyifttt-model/src/main/java/com/pddstudio/tinyifttt/models/TinyAction.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.models;
2 |
3 | /**
4 | * This Class was created by Patrick J
5 | * on 29.03.16. For more Details and Licensing
6 | * have a look at the README.md
7 | */
8 | public class TinyAction {
9 |
10 | private int actionIdentifier;
11 | private String actionTitle;
12 | private String actionDescription;
13 | private String[] actionExec;
14 |
15 | public TinyAction() {}
16 |
17 | public int getActionIdentifier() {
18 | return actionIdentifier;
19 | }
20 |
21 | public String getActionTitle() {
22 | return actionTitle;
23 | }
24 |
25 | public String getActionDescription() {
26 | return actionDescription;
27 | }
28 |
29 | public String[] getActionExec() {
30 | return actionExec;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/tinyifttt-model/src/main/java/com/pddstudio/tinyifttt/models/TinyActionReceivedListener.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.models;
2 |
3 | /**
4 | * This Class was created by Patrick J
5 | * on 29.03.16. For more Details and Licensing
6 | * have a look at the README.md
7 | */
8 | public interface TinyActionReceivedListener {
9 | void onTinyActionReceived(TinyAction tinyAction);
10 | }
11 |
--------------------------------------------------------------------------------
/tinyifttt-server/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/tinyifttt-server/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java'
2 |
3 | version = '1.0'
4 | sourceCompatibility = 1.7
5 | targetCompatibility = 1.7
6 |
7 | //create a single Jar with all dependencies
8 | task tinyIFTTTserver(type: Jar) {
9 | manifest {
10 | attributes 'Implementation-Title': 'tinyIFTT Server',
11 | 'Implementation-Version': version,
12 | 'Main-Class': 'com.pddstudio.tinyifttt.server.ServerRunner'
13 | }
14 | baseName = project.name + '-full'
15 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
16 | with jar
17 | }
18 |
19 | //Get dependencies from Maven central repository
20 | repositories {
21 | mavenCentral()
22 | }
23 |
24 | dependencies {
25 | compile fileTree(include: ['*.jar'], dir: 'libs')
26 | compile 'com.google.code.gson:gson:2.6.2'
27 | compile 'io.airlift:airline:0.7'
28 | compile project(':tinyifttt-model')
29 | }
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/ActionExecutor.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server;
2 |
3 | import com.pddstudio.tinyifttt.models.TinyAction;
4 | import com.pddstudio.tinyifttt.server.utils.Logger;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.util.Scanner;
9 |
10 | /**
11 | * This Class was created by Patrick J
12 | * on 29.03.16. For more Details and Licensing
13 | * have a look at the README.md
14 | */
15 | public class ActionExecutor {
16 |
17 | private final TinyAction tinyAction;
18 |
19 | protected ActionExecutor(TinyAction tinyAction) {
20 | this.tinyAction = tinyAction;
21 | }
22 |
23 | protected void execute() {
24 | try {
25 | ProcessBuilder processBuilder = new ProcessBuilder(tinyAction.getActionExec()).redirectErrorStream(true);
26 | Process process = processBuilder.start();
27 | inheritIO(process.getErrorStream());
28 | inheritIO(process.getInputStream());
29 | } catch (IOException io) {
30 | io.printStackTrace();
31 | }
32 | }
33 |
34 | private static void inheritIO(final InputStream src) {
35 | new Thread(new Runnable() {
36 | public void run() {
37 | Scanner sc = new Scanner(src);
38 | while (sc.hasNextLine()) {
39 | Logger.log(ActionExecutor.class, sc.nextLine());
40 | }
41 | }
42 | }).start();
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/ServerRunner.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server;
2 |
3 | import java.io.IOException;
4 |
5 | import javax.inject.Inject;
6 |
7 | import io.airlift.airline.Command;
8 | import io.airlift.airline.HelpOption;
9 | import io.airlift.airline.Option;
10 | import io.airlift.airline.SingleCommand;
11 |
12 | /**
13 | * This Class was created by Patrick J
14 | * on 29.03.16. For more Details and Licensing
15 | * have a look at the README.md
16 | */
17 | @Command(name = "tinyIFTT ServerRunner", description = "Run a tinyIFTTT-Server")
18 | public class ServerRunner {
19 |
20 | @Inject
21 | public HelpOption helpOption;
22 |
23 | @Option(name = { "-c", "--config" }, description = "The location to the tinyIFTTT configuration file.")
24 | public String configFileLocation;
25 |
26 | @Option(name = { "-p", "--port" }, description = "The port the tinyIFTTT server should run on.")
27 | public int configPort = 1337;
28 |
29 | public static void main(String[] args) {
30 | ServerRunner serverRunner = SingleCommand.singleCommand(ServerRunner.class).parse(args);
31 | if(serverRunner.helpOption.showHelpIfRequested()) return;
32 | serverRunner.startService();
33 | }
34 |
35 | public void startService() {
36 | try {
37 | TinyIFTTT tinyIFTTT = new TinyIFTTT(configFileLocation);
38 | tinyIFTTT.start(configPort);
39 | } catch (IOException io) {
40 | io.printStackTrace();
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/TinyIFTTT.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server;
2 |
3 | import com.google.gson.Gson;
4 | import com.pddstudio.tinyifttt.models.TinyAction;
5 | import com.pddstudio.tinyifttt.models.TinyActionReceivedListener;
6 | import com.pddstudio.tinyifttt.server.async.ClientConnectionListener;
7 | import com.pddstudio.tinyifttt.server.utils.Logger;
8 |
9 | import java.io.BufferedReader;
10 | import java.io.BufferedWriter;
11 | import java.io.File;
12 | import java.io.FileReader;
13 | import java.io.IOException;
14 | import java.io.OutputStream;
15 | import java.io.OutputStreamWriter;
16 | import java.net.ServerSocket;
17 | import java.net.Socket;
18 |
19 | /**
20 | * This Class was created by Patrick J
21 | * on 29.03.16. For more Details and Licensing
22 | * have a look at the README.md
23 | */
24 | public class TinyIFTTT implements TinyActionReceivedListener {
25 |
26 | private final String configFile;
27 | private int serverPort;
28 | private ServerSocket serverSocket;
29 | private TinyAction[] tinyActions;
30 |
31 | public TinyIFTTT(String configFilePath) throws IOException {
32 | this.configFile = configFilePath;
33 | loadConfiguration();
34 | Logger.log(this, "tinyIFTTT Server configuration loaded.");
35 | }
36 |
37 | public void start(int serverPort) throws IOException {
38 | this.serverPort = serverPort;
39 | Logger.log(this, "Starting tinyIFTTT Server...");
40 | runTinyServer();
41 | }
42 |
43 | private void loadConfiguration() throws IOException {
44 | //parse all available actions
45 | File actionFile = new File(configFile);
46 | FileReader fileReader = new FileReader(actionFile);
47 | BufferedReader bufferedReader = new BufferedReader(fileReader);
48 | Gson gson = new Gson();
49 | this.tinyActions = gson.fromJson(bufferedReader, TinyAction[].class);
50 | }
51 |
52 | private void runTinyServer() throws IOException {
53 | //start the server on the given port and listen for incoming connections
54 | serverSocket = new ServerSocket(serverPort);
55 | while(true) {
56 | Socket socket = serverSocket.accept();
57 | onSocketConnectionFound(socket);
58 | }
59 | }
60 |
61 | private void onSocketConnectionFound(Socket socket) {
62 | Logger.log(this, "SocketConnection found: " + socket.getInetAddress().getHostAddress());
63 | //run a new asynchronous listener
64 | new ClientConnectionListener(socket, this).startListening();
65 | //send the list of available commands to the client
66 | sendAvailableCommands(socket);
67 | }
68 |
69 | private void sendAvailableCommands(Socket socket) {
70 | try {
71 | //open the output stream
72 | OutputStream outputStream = socket.getOutputStream();
73 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
74 | BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
75 | Gson gson = new Gson();
76 | //send all available commands
77 | for(TinyAction tinyAction : tinyActions) {
78 | bufferedWriter.write(gson.toJson(tinyAction));
79 | bufferedWriter.newLine();
80 | bufferedWriter.flush();
81 | }
82 | } catch (IOException io) {
83 | io.printStackTrace();
84 | }
85 | }
86 |
87 | @Override
88 | public void onTinyActionReceived(TinyAction tinyAction) {
89 | Logger.log(this, "ActionReceived: ID [" + tinyAction.getActionIdentifier() + "] Exec: " + tinyAction.getActionExec()[0]);
90 | //handle the action we received from one of the listeners
91 | for(TinyAction mAction : tinyActions) {
92 | //only execute the action if it's known
93 | if(mAction.getActionIdentifier() == tinyAction.getActionIdentifier()) new ActionExecutor(tinyAction).execute();
94 | }
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/async/ClientConnectionListener.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server.async;
2 |
3 | import com.google.gson.Gson;
4 | import com.pddstudio.tinyifttt.models.TinyAction;
5 | import com.pddstudio.tinyifttt.models.TinyActionReceivedListener;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.InputStreamReader;
11 | import java.net.Socket;
12 |
13 | /**
14 | * This Class was created by Patrick J
15 | * on 29.03.16. For more Details and Licensing
16 | * have a look at the README.md
17 | */
18 | public class ClientConnectionListener extends Thread {
19 |
20 | private final Socket clientSocket;
21 | private final TinyActionReceivedListener tinyActionReceivedListener;
22 |
23 | public ClientConnectionListener(Socket socket, TinyActionReceivedListener tinyActionReceivedListener) {
24 | //assign the client socket we want to communicate with
25 | this.clientSocket = socket;
26 | //assign the interface for the callbacks
27 | this.tinyActionReceivedListener = tinyActionReceivedListener;
28 | }
29 |
30 | public void startListening() {
31 | //start the new Thread
32 | start();
33 | }
34 |
35 | @Override
36 | public void run() {
37 | //read the input from the socket's input stream
38 | try {
39 | InputStream inputStream = clientSocket.getInputStream();
40 | InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
41 | BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
42 | Gson gson = new Gson();
43 | String response;
44 | while((response = bufferedReader.readLine()) != null) {
45 | TinyAction tinyAction = gson.fromJson(response, TinyAction.class);
46 | if(tinyAction != null) tinyActionReceivedListener.onTinyActionReceived(tinyAction);
47 | }
48 |
49 | } catch (IOException io) {
50 | io.printStackTrace();
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/utils/Log.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server.utils;
2 |
3 | /**
4 | * Project : WetterSuite
5 | * Author : pddstudio
6 | * Year : 2016
7 | */
8 | public enum Log {
9 | DEBUG("D"),
10 | INFO("I"),
11 | WARNING("W"),
12 | ERROR("E");
13 |
14 | final String log;
15 |
16 | Log(String log) {
17 | this.log = log;
18 | }
19 |
20 | public String getPrefix() {
21 | return log;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/tinyifttt-server/src/main/java/com/pddstudio/tinyifttt/server/utils/Logger.java:
--------------------------------------------------------------------------------
1 | package com.pddstudio.tinyifttt.server.utils;
2 |
3 | import java.io.File;
4 | import java.util.Calendar;
5 | import java.util.GregorianCalendar;
6 |
7 | /**
8 | * Project : WetterSuite
9 | * Author : pddstudio
10 | * Year : 2016
11 | */
12 | public class Logger {
13 |
14 | private static File LOG_FILE;
15 |
16 | private Logger() {}
17 |
18 | public static void init(String location) {
19 | LOG_FILE = new File(location);
20 | }
21 |
22 | public static void log(Class className, String message) {
23 | log(className.getSimpleName(), message);
24 | }
25 |
26 | public static void log(String logPrefix, String message) {
27 | String logMsg = getSystemTime() + "[" + logPrefix + "::/" + Log.DEBUG.getPrefix() + "] " + message;
28 | printLogMessage(logMsg);
29 | }
30 |
31 | public static void log(Object object, String message) {
32 | log(object, Log.DEBUG, message);
33 | }
34 |
35 | public static void log(Object object, Log logType, String message) {
36 | String logMsg = getSystemTime() + "[" + object.getClass().getSimpleName() + "::/" + logType.getPrefix() + "] " + message;
37 | printLogMessage(logMsg);
38 | }
39 |
40 | private static synchronized void printLogMessage(String logMessage) {
41 | System.out.println(logMessage);
42 | }
43 |
44 | private static String getSystemTime() {
45 | Calendar calendar = GregorianCalendar.getInstance();
46 | int day = calendar.get(Calendar.DAY_OF_MONTH);
47 | String newday;
48 | String newmnth;
49 |
50 | if(day < 10) {
51 | newday = "0" + day;
52 | } else {
53 | newday = "" + day;
54 | }
55 |
56 | int mnth = calendar.get(Calendar.MONTH);
57 | //cuz of stupid month -1 rule
58 | mnth++;
59 |
60 | if(mnth < 10) {
61 | newmnth = "0" + mnth;
62 | } else {
63 | newmnth = "" + mnth;
64 | }
65 |
66 | int year = calendar.get(Calendar.YEAR);
67 | int hr = calendar.get(Calendar.HOUR_OF_DAY);
68 | int min = calendar.get(Calendar.MINUTE);
69 | int sec = calendar.get(Calendar.SECOND);
70 | String secs;
71 | if(sec < 10) {
72 | secs = "0" + sec;
73 | } else {
74 | secs = "" + sec;
75 | }
76 | return "[" + newmnth + "-" + newday + "-" + year + "|" + hr + ":" + min + ":" +secs + "]";
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/tinyifttt-server/tiny-sample.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "actionIdentifier" : 1,
4 | "actionTitle" : "Home PC Shutdown",
5 | "actionDescription" : "Power off my machine upstairs.",
6 | "actionExec" : [ "shutdown", "-h", "now" ]
7 | },
8 | {
9 | "actionIdentifier" : 2,
10 | "actionTitle" : "Home PC Reboot",
11 | "actionDescription" : "Reboot my machine upstairs.",
12 | "actionExec" : [ "reboot" ]
13 | },
14 | {
15 | "actionIdentifier" : 3,
16 | "actionTitle" : "Raspberry Pi Update",
17 | "actionDescription" : "Update the packages on my Pi.",
18 | "actionExec" : [ "apt-get", "update" ]
19 | },
20 | {
21 | "actionIdentifier" : 4,
22 | "actionTitle" : "Raspberry Pi XBMC",
23 | "actionDescription" : "Start XBMC on my Pi.",
24 | "actionExec" : [ "xbmc" ]
25 | },
26 | {
27 | "actionIdentifier" : 5,
28 | "actionTitle" : "Run Backup Script",
29 | "actionDescription" : "Run the backup script to save my data stored on my NAS.",
30 | "actionExec" : [ "sh", "/opt/backup/backup_all.sh" ]
31 | },
32 | {
33 | "actionIdentifier" : 6,
34 | "actionTitle" : "Kitchen Light",
35 | "actionDescription" : "Switch on the Light in the kitchen.",
36 | "actionExec" : [ "python", "/opt/mods/switch_light.py" ]
37 | },
38 | {
39 | "actionIdentifier" : 7,
40 | "actionTitle" : "Android TV",
41 | "actionDescription" : "Power on/off my AndroidTV.",
42 | "actionExec" : [ "sh", "/opt/mods/tv_power.sh" ]
43 | },
44 | {
45 | "actionIdentifier" : 8,
46 | "actionTitle" : "Ping Google.com",
47 | "actionDescription" : "Ping Google's Website to make sure the internet connection is available.",
48 | "actionExec" : [ "ping", "google.com" ]
49 | }
50 | ]
51 |
--------------------------------------------------------------------------------