├── app ├── .gitignore ├── src │ └── main │ │ ├── play │ │ └── release-notes │ │ │ └── en-US │ │ │ └── default.txt │ │ ├── ic_launcher-web.png │ │ ├── res │ │ ├── drawable-hdpi │ │ │ ├── ic_check.png │ │ │ └── ic_error.png │ │ ├── drawable-mdpi │ │ │ ├── ic_check.png │ │ │ └── ic_error.png │ │ ├── drawable-xhdpi │ │ │ ├── ic_check.png │ │ │ └── ic_error.png │ │ ├── drawable-xxhdpi │ │ │ ├── ic_check.png │ │ │ └── ic_error.png │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── colors.xml │ │ │ ├── styles.xml │ │ │ └── strings.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ ├── activity_splash.xml │ │ │ └── item_monitor.xml │ │ ├── menu │ │ │ └── menu_main.xml │ │ ├── drawable │ │ │ ├── ic_error.xml │ │ │ ├── ic_check.xml │ │ │ ├── ic_info.xml │ │ │ ├── ic_hourglass.xml │ │ │ ├── bg_emphasis.xml │ │ │ └── ic_history.xml │ │ ├── values-v21 │ │ │ └── styles.xml │ │ ├── values-v23 │ │ │ └── styles.xml │ │ ├── values-v27 │ │ │ └── styles.xml │ │ └── xml │ │ │ └── attribouter.xml │ │ ├── java │ │ └── me │ │ │ └── jfenn │ │ │ └── cronhubclient │ │ │ ├── data │ │ │ ├── request │ │ │ │ ├── MonitorRequest.java │ │ │ │ ├── MonitorListRequest.java │ │ │ │ ├── cronhub │ │ │ │ │ └── Monitor.java │ │ │ │ └── Request.java │ │ │ ├── item │ │ │ │ ├── Item.java │ │ │ │ └── MonitorItem.java │ │ │ └── PreferenceData.java │ │ │ ├── adapters │ │ │ └── ItemAdapter.java │ │ │ ├── jobs │ │ │ └── MonitorJob.java │ │ │ ├── activities │ │ │ ├── MainActivity.java │ │ │ └── SplashActivity.java │ │ │ └── CronHub.java │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── key.jks ├── secrets.tar.enc ├── .github ├── images │ ├── login.png │ ├── interface.png │ └── notification.png └── CONTRIBUTING.md ├── .scripts ├── gen-bintray-descriptor.sh └── deploy.sh ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .meta.yml ├── .gitignore ├── service.json ├── bintray-format.json ├── gradle.properties ├── README.md ├── .travis.yml ├── gradlew.bat ├── gradlew └── LICENSE /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /key.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/key.jks -------------------------------------------------------------------------------- /app/src/main/play/release-notes/en-US/default.txt: -------------------------------------------------------------------------------- 1 | - fixed invalid formatting bug -------------------------------------------------------------------------------- /secrets.tar.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/secrets.tar.enc -------------------------------------------------------------------------------- /.github/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/.github/images/login.png -------------------------------------------------------------------------------- /.github/images/interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/.github/images/interface.png -------------------------------------------------------------------------------- /.github/images/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/.github/images/notification.png -------------------------------------------------------------------------------- /.scripts/gen-bintray-descriptor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | eval "cat << EOF 4 | $( bintray.json -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-hdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-hdpi/ic_error.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-mdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-mdpi/ic_error.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-xhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-xhdpi/ic_error.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-xxhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/drawable-xxhdpi/ic_error.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fennifith/Cronhub-Monitor/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /.meta.yml: -------------------------------------------------------------------------------- 1 | icon: "app/src/main/ic_launcher-web.png" 2 | screenshots: 3 | - ".github/images/login.png" 4 | - ".github/images/interface.png" 5 | - ".github/images/notification.png" -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #4C3DC4 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | wget "https://gist.githubusercontent.com/fennifith/664f534ead7336adf420d5afa72628f9/raw/travis-github-release.sh" -O .scripts/github-release.sh 5 | chmod +x .scripts/github-release.sh && ./.scripts/github-release.sh 6 | 7 | exit 0 -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F5F5F5 4 | #BDBDBD 5 | #4C3DC4 6 | 7 | #45D46A 8 | #FF5D63 9 | 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Mar 10 16:09:37 EDT 2019 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-4.10.1-all.zip 7 | distributionSha256Sum=36bf7ff499223d5139f005822130ccca784c91591b514677fd376eed966c907e 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/data/request/MonitorRequest.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.data.request; 2 | 3 | import me.jfenn.cronhubclient.data.request.cronhub.Monitor; 4 | 5 | public class MonitorRequest extends Request { 6 | 7 | public boolean success; 8 | public Monitor response; 9 | 10 | public MonitorRequest(String code) { 11 | super("https://cronhub.io/api/v1/monitors/" + code); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_hourglass.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-v23/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_emphasis.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /service.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 3 | "token_uri": "https://oauth2.googleapis.com/token", 4 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 5 | "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/blahblahblah.gserviceaccount.com" 6 | "type": "service_account", 7 | "project_id": "$project-id", 8 | "private_key_id": "$private-key-id", 9 | "private_key": "-----BEGIN PRIVATE KEY-----\nblahblahblahblahblah\n----END PRIVATE KEY-----\n", 10 | "client_id": "$client-id", 11 | "client_email": "plsdont@example.com" 12 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-v27/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/data/request/MonitorListRequest.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.data.request; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | import me.jfenn.cronhubclient.data.request.cronhub.Monitor; 8 | 9 | public class MonitorListRequest extends Request { 10 | 11 | public boolean success; 12 | public Monitor[] response; 13 | 14 | public MonitorListRequest() { 15 | super("https://cronhub.io/api/v1/monitors"); 16 | } 17 | 18 | public List getMonitors() { 19 | return new ArrayList<>(Arrays.asList(response)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/data/item/Item.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.data.item; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.LayoutRes; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | public abstract class Item { 9 | 10 | @LayoutRes 11 | private int layout; 12 | 13 | public Item(@LayoutRes int layout) { 14 | this.layout = layout; 15 | } 16 | 17 | @LayoutRes 18 | public final int getLayoutRes() { 19 | return layout; 20 | } 21 | 22 | public abstract T getViewHolder(View v); 23 | 24 | public abstract void bind(T holder); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bintray-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "name": "$(echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2)", 4 | "repo": "builds", 5 | "subject": "18jafenn90", 6 | "vcs_url": "https://github.com/$TRAVIS_REPO_SLUG", 7 | "issue_tracker_url": "https://github.com/$TRAVIS_REPO_SLUG/issues", 8 | "licenses": ["Apache-2.0"] 9 | }, 10 | 11 | "version": { 12 | "name": "$TRAVIS_COMMIT", 13 | "desc": "$TRAVIS_COMMIT_MESSAGE" 14 | }, 15 | 16 | "files": [ 17 | { 18 | "includePattern": "app/build/outputs/apk/(.*)/(.*\\-debug\\.apk)", 19 | "uploadPattern": "/$TRAVIS_COMMIT/\$2", 20 | "matrixParams": { 21 | "override": 1 22 | } 23 | } 24 | ], 25 | "publish": true 26 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | android.enableJetifier=true 10 | android.useAndroidX=true 11 | org.gradle.jvmargs=-Xmx1536m 12 | # When configured, Gradle will run in incubating parallel mode. 13 | # This option should only be used with decoupled projects. More details, visit 14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 15 | # org.gradle.parallel=true 16 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/data/request/cronhub/Monitor.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.data.request.cronhub; 2 | 3 | import com.cronutils.model.Cron; 4 | import com.cronutils.model.CronType; 5 | import com.cronutils.model.definition.CronDefinitionBuilder; 6 | import com.cronutils.parser.CronParser; 7 | 8 | import java.util.Date; 9 | 10 | public class Monitor { 11 | 12 | public String name; 13 | public String code; 14 | public String schedule; 15 | public int grace_period; 16 | public String timezone; 17 | public String status; 18 | public Date last_ping; 19 | public int running_time; 20 | public String running_time_unit; 21 | public Date created_at; 22 | 23 | public Cron getSchedule() { 24 | if (schedule != null) 25 | return new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)).parse(schedule); 26 | else return null; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | As long as your pull request doesn't break the app in any way or conflict with an ongoing change (check the open issues first or send me [an email](mailto:dev@jfenn.me) to make sure this doesn't happen), it will likely be accepted. I have a lot of projects and may not get around to reviewing pull requests right away. If you have contributed to this project before and would like to be added to this repository as a collaborator, feel free to send me [an email](mailto:dev@jfenn.me) and ask. 4 | 5 | ## Branches 6 | 7 | I am using the `develop` branch for all changes that should not be immediately available to actual users. Because of this, most PRs should be made to the `develop` branch. The only reason that a PR should be made to `master` is when there is a typo/inconsistency in the README or a similar issue (in /docs, for example) is present. If you make a PR to `master` that changes something other than a .md file, I will stare at my screen and make irritated zebra noises for approximately 10 minutes before politely asking you to change the branch. Thank you. 8 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/adapters/ItemAdapter.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.adapters; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | 6 | import java.util.List; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.recyclerview.widget.RecyclerView; 10 | import me.jfenn.cronhubclient.data.item.Item; 11 | 12 | public class ItemAdapter extends RecyclerView.Adapter { 13 | 14 | private List infos; 15 | 16 | public ItemAdapter(List infos) { 17 | this.infos = infos; 18 | } 19 | 20 | @NonNull 21 | @Override 22 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 23 | Item info = infos.get(viewType); 24 | return info.getViewHolder(LayoutInflater.from(parent.getContext()).inflate(info.getLayoutRes(), parent, false)); 25 | } 26 | 27 | @Override 28 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { 29 | infos.get(position).bind(holder); 30 | } 31 | 32 | @Override 33 | public int getItemViewType(int position) { 34 | return position; 35 | } 36 | 37 | @Override 38 | public int getItemCount() { 39 | return infos.size(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This app serves as a native Android notification client for [cronhub.io](https://cronhub.io/). Its only purpose is to deliver status notifications at the alert time specified on CronHub, using their [public API](https://docs.cronhub.io/public-api.html). It does not currently allow users to edit CronHub monitors, but that functionality may be added in the future. 2 | 3 | [![Build Status](https://travis-ci.com/fennifith/Cronhub-Monitor.svg?branch=master)](https://travis-ci.com/fennifith/Cronhub-Monitor) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e6685a052a6d4f0681fb7b64f1e26aa2)](https://www.codacy.com/app/fennifith/Cronhub-Monitor) 5 | [![Discord](https://img.shields.io/discord/514625116706177035.svg?logo=discord&colorB=7289da)](https://discord.gg/VgJwGua) 6 | 7 | ## Screenshots 8 | 9 | | Login Screen | Interface | Notification | 10 | |--------------|-----------|--------------| 11 | | ![img](./.github/images/login.png?raw=true) | ![img](./.github/images/interface.png?raw=true) | ![img](./.github/images/notification.png?raw=true) | 12 | 13 | ## Contributing 14 | 15 | See this repository's [CONTRIBUTING.md](./.github/CONTRIBUTING.md) for more information. 16 | 17 | ## Disclaimer 18 | 19 | This app is not endorsed by, related to, or a part of CronHub. It is a third party CronHub client, made by me (me is [James Fenn](https://jfenn.me/) - I am me). It is not an official CronHub app. 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | android: 3 | components: 4 | - tools 5 | - platform-tools 6 | - build-tools-28.0.3 7 | - android-28 8 | - extra-google-google_play_services 9 | - extra-google-m2repository 10 | - extra-android-m2repository 11 | jdk: 12 | - oraclejdk8 13 | before_install: 14 | - openssl aes-256-cbc -K $encrypted_17816c06507f_key -iv $encrypted_17816c06507f_iv -in secrets.tar.enc -out secrets.tar -d 15 | - tar -xvf secrets.tar --overwrite 16 | - chmod +x gradlew 17 | script: 18 | - if [ "$TRAVIS_TAG" != "" ]; then ./gradlew publish; else ./gradlew build; fi 19 | before_deploy: 20 | - export RELEASE_VERSION=$TRAVIS_TAG 21 | - export RELEASE_CHANGELOG=$(cat app/src/main/play/release-notes/en-US/default.txt) 22 | - export RELEASE_FILE="app/build/outputs/apk/*/*.apk" 23 | - if ! [ -e bintray.json ]; then 24 | chmod +x .scripts/gen-bintray-descriptor.sh; 25 | ./.scripts/gen-bintray-descriptor.sh; 26 | fi 27 | deploy: 28 | - provider: bintray 29 | skip_cleanup: true 30 | file: "bintray.json" 31 | user: "18jafenn90" 32 | key: $BINTRAY_KEY 33 | on: 34 | all_branches: true 35 | - provider: script 36 | skip_cleanup: true 37 | script: bash ./.scripts/deploy.sh 38 | on: 39 | branch: master 40 | tags: true 41 | - provider: releases 42 | api_key: "$GITHUB_TOKEN" 43 | skip_cleanup: true 44 | overwrite: true 45 | file_glob: true 46 | file: "$RELEASE_FILE" 47 | tag_name: "$RELEASE_VERSION" 48 | on: 49 | branch: master 50 | tags: true -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/jobs/MonitorJob.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.jobs; 2 | 3 | import com.evernote.android.job.Job; 4 | import com.evernote.android.job.JobRequest; 5 | 6 | import androidx.annotation.NonNull; 7 | import me.jfenn.cronhubclient.CronHub; 8 | import me.jfenn.cronhubclient.data.request.MonitorRequest; 9 | import me.jfenn.cronhubclient.data.request.Request; 10 | 11 | public class MonitorJob extends Job implements Request.OnInitListener { 12 | 13 | private Result state; 14 | 15 | @NonNull 16 | @Override 17 | protected Result onRunJob(@NonNull Params params) { 18 | String monitor = params.getTag(); 19 | if (monitor != null) { 20 | MonitorRequest request = new MonitorRequest(monitor); 21 | request.addOnInitListener(this); 22 | ((CronHub) getContext().getApplicationContext()).addRequest(request); 23 | 24 | while (state == null) { 25 | try { 26 | Thread.sleep(200); 27 | } catch (InterruptedException e) { 28 | return Result.FAILURE; 29 | } 30 | } 31 | 32 | return state; 33 | } 34 | 35 | return Result.FAILURE; 36 | } 37 | 38 | @Override 39 | public void onInit(Request data) { 40 | state = Result.SUCCESS; 41 | } 42 | 43 | @Override 44 | public void onFailure(Request data, String message) { 45 | state = Result.FAILURE; 46 | } 47 | 48 | public static void scheduleJob(String monitor, long triggerTime) { 49 | new JobRequest.Builder(monitor) 50 | .setExact(triggerTime) 51 | .build() 52 | .schedule(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CronHub Monitor 3 | CronHub Monitor needs your CronHub account\'s API key in order to function. To obtain your API key, go to your CronHub dashboard, enter the settings and select \"Public API Access\", then paste the code into the text field below. 4 | API Key 5 | Go 6 | Sign In 7 | Authentication 8 | 9 | Status: %s 10 | @android:string/ok 11 | DOWN 12 | Last Ping (year-month-day) 13 | Next Run Time 14 | About 15 | Notifications 16 | Notify of Successful Runs 17 | CronHub Alerts 18 | 19 | CRON Job Run: \"%s\" 20 | Cron Job Failed: \"%s\" 21 | Your CRON job, \"%1$s\", pinged CronHub\'s servers at %2$s. 22 | Your CRON job, \"%1$S\", has not pinged CronHub\'s servers within %2$s minutes of its scheduled execution. 23 | [none] 24 | Your API key is stored locally and is not shared by this app with any servers other than cronhub.io. 25 | https://cronhub.io/ • Privacy Policy]]> 26 | 27 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.github.triplet.play' 3 | 4 | android { 5 | compileSdkVersion 28 6 | defaultConfig { 7 | applicationId "me.jfenn.cronhubclient" 8 | minSdkVersion 17 9 | targetSdkVersion 28 10 | versionCode 2 11 | versionName "1.1" 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | vectorDrawables.useSupportLibrary = true 14 | } 15 | signingConfigs { 16 | release 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | compileOptions { 25 | targetCompatibility 1.8 26 | sourceCompatibility 1.8 27 | } 28 | 29 | def isRunningOnTravis = System.getenv("CI") == "true" 30 | if (isRunningOnTravis) { 31 | buildTypes.release.signingConfig = signingConfigs.release 32 | signingConfigs.release.storeFile = file("../key.jks") 33 | signingConfigs.release.storePassword = System.getenv("KEYSTORE_PASSWORD") 34 | signingConfigs.release.keyAlias = System.getenv("KEYSTORE_ALIAS") 35 | signingConfigs.release.keyPassword = System.getenv("KEYSTORE_ALIAS_PASSWORD") 36 | } 37 | } 38 | 39 | play { 40 | serviceAccountCredentials = file("../service.json") 41 | track = "alpha" 42 | } 43 | 44 | task printVersionName { 45 | doLast { 46 | println android.defaultConfig.versionName 47 | } 48 | } 49 | 50 | dependencies { 51 | implementation fileTree(dir: 'libs', include: ['*.jar']) 52 | implementation 'androidx.appcompat:appcompat:1.0.1' 53 | implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' 54 | implementation 'com.google.code.gson:gson:2.8.4' 55 | implementation 'me.jfenn:Attribouter:0.1.5' 56 | implementation 'com.cronutils:cron-utils:6.0.6' 57 | implementation 'com.jakewharton.threetenabp:threetenabp:1.0.3' 58 | implementation 'com.evernote:android-job:1.2.6' 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/res/xml/attribouter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 33 | 34 | 41 | 42 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /app/src/main/java/me/jfenn/cronhubclient/activities/MainActivity.java: -------------------------------------------------------------------------------- 1 | package me.jfenn.cronhubclient.activities; 2 | 3 | import android.os.Bundle; 4 | import android.view.Menu; 5 | import android.view.MenuItem; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import androidx.appcompat.app.AppCompatActivity; 11 | import androidx.recyclerview.widget.DividerItemDecoration; 12 | import androidx.recyclerview.widget.LinearLayoutManager; 13 | import androidx.recyclerview.widget.RecyclerView; 14 | import me.jfenn.attribouter.Attribouter; 15 | import me.jfenn.cronhubclient.CronHub; 16 | import me.jfenn.cronhubclient.R; 17 | import me.jfenn.cronhubclient.adapters.ItemAdapter; 18 | import me.jfenn.cronhubclient.data.item.Item; 19 | import me.jfenn.cronhubclient.data.item.MonitorItem; 20 | import me.jfenn.cronhubclient.data.request.MonitorListRequest; 21 | import me.jfenn.cronhubclient.data.request.Request; 22 | import me.jfenn.cronhubclient.data.request.cronhub.Monitor; 23 | 24 | public class MainActivity extends AppCompatActivity implements Request.OnInitListener { 25 | 26 | private RecyclerView recyclerView; 27 | 28 | private CronHub cronHub; 29 | 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_main); 34 | cronHub = (CronHub) getApplicationContext(); 35 | 36 | recyclerView = findViewById(R.id.recycler); 37 | recyclerView.setLayoutManager(new LinearLayoutManager(this)); 38 | recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); 39 | 40 | MonitorListRequest request = new MonitorListRequest(); 41 | request.addOnInitListener(this); 42 | cronHub.addRequest(request); 43 | } 44 | 45 | @Override 46 | public void onInit(Request data) { 47 | if (data instanceof MonitorListRequest) { 48 | List items = new ArrayList<>(); 49 | for (Monitor monitor : ((MonitorListRequest) data).getMonitors()) 50 | items.add(new MonitorItem(monitor)); 51 | 52 | recyclerView.setAdapter(new ItemAdapter(items)); 53 | } 54 | } 55 | 56 | @Override 57 | public void onFailure(Request data, String message) { 58 | finish(); 59 | } 60 | 61 | @Override 62 | public boolean onCreateOptionsMenu(Menu menu) { 63 | getMenuInflater().inflate(R.menu.menu_main, menu); 64 | return super.onCreateOptionsMenu(menu); 65 | } 66 | 67 | @Override 68 | public boolean onOptionsItemSelected(MenuItem item) { 69 | if (item.getItemId() == R.id.about) 70 | Attribouter.from(this).show(); 71 | 72 | return super.onOptionsItemSelected(item); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 26 | 27 | 32 | 33 | 42 | 43 |