From 6cbb0444c91173dfa2060e6780593aaaa461dfc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20H=C3=A4hnel?= Date: Tue, 20 Dec 2016 16:20:01 +0100 Subject: [PATCH] Added progress of current show --- app/build.gradle | 1 + .../rbtv/rocketbeanstv/MainActivity.java | 38 ++++++-- .../events/ChannelInfoUpdateEvent.java | 9 +- .../loader/ChannelInfoLoader.java | 23 +++-- .../rocketbeanstv/loader/ScheduleLoader.java | 31 +------ .../objects/schedule/Schedule.java | 8 +- .../rbtv/rocketbeanstv/utils/AuthHelper.java | 40 --------- .../rocketbeanstv/utils/Authentication.java | 30 +++++++ app/src/main/res/layout/activity_main.xml | 86 ++++++++++++------- 9 files changed, 142 insertions(+), 124 deletions(-) delete mode 100644 app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/AuthHelper.java create mode 100644 app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/Authentication.java diff --git a/app/build.gradle b/app/build.gradle index 8ce9b1e..a66d99d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,6 +37,7 @@ dependencies { compile 'com.devbrackets.android:exomedia:3.1.0' compile 'com.google.code.gson:gson:2.8.0' compile 'com.squareup.okhttp3:okhttp:3.4.2' + compile 'net.danlew:android.joda:2.9.5.1' compile 'com.google.firebase:firebase-core:10.0.1' compile 'com.google.firebase:firebase-crash:10.0.1' apt 'org.projectlombok:lombok:1.12.6' diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/MainActivity.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/MainActivity.java index 14834be..d9528c7 100644 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/MainActivity.java +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/MainActivity.java @@ -1,6 +1,7 @@ package de.markhaehnel.rbtv.rocketbeanstv; +import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import butterknife.BindView; import org.greenrobot.eventbus.Subscribe; @@ -18,6 +19,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.animation.DecelerateInterpolator; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; @@ -32,8 +34,12 @@ import com.devbrackets.android.exomedia.ui.widget.EMVideoView; import com.google.firebase.analytics.FirebaseAnalytics; +import net.danlew.android.joda.JodaTimeAndroid; + import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.ThreadMode; +import org.joda.time.DateTime; +import org.joda.time.Duration; import java.util.Arrays; import java.util.List; import butterknife.ButterKnife; @@ -58,11 +64,12 @@ public class MainActivity extends AppCompatActivity { @BindView(R.id.exomediaplayer) EMVideoView mVideoView; @BindView(R.id.textCurrentShow) TextView textCurrentShow; - @BindView(R.id.textViewerCount) TextView textViewerCount; + @BindView(R.id.textCurrentTopic) TextView textCurrentTopic; @BindView(R.id.pauseImage) ImageView pauseView; @BindView(R.id.containerSchedule) ViewGroup containerSchedule; @BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.scheduleProgress) ProgressBar scheduleProgress; + @BindView(R.id.progressCurrentShow) ProgressBar progressCurrentShow; @BindView(R.id.webViewChat) WebView webViewChat; private final String RESOLUTION = "resolution"; @@ -80,7 +87,7 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - + JodaTimeAndroid.init(this); mFirebaseAnalytics = FirebaseAnalytics.getInstance(this); ButterKnife.bind(this); } @@ -116,7 +123,7 @@ public void onInternetChecked(InternetCheckEvent event) { setupListeners(); MediaSessionHandler.setupMediaSession(MainActivity.this); preparePlayer(); - new ChannelInfoLoader().start(); + new ChannelInfoLoader(getString(R.string.RBTVKEY), getString(R.string.RBTVSECRET)).start(); break; case FAILED: showMessage(R.string.error_noInternet); @@ -143,7 +150,6 @@ public void onPageFinished(WebView view, String url) { } }); webViewChat.loadUrl("https://gaming.youtube.com/live_chat?is_popout=1&v=" + videoId); - } } @@ -258,17 +264,31 @@ public void onChannelInfoUpdate(ChannelInfoUpdateEvent event) { switch (event.getStatus()) { case OK: - textViewerCount.setText(String.format("%s %s", String.valueOf(event.getViewerCount()), getString(R.string.viewers))); - if (!event.getCurrentShow().equals(textCurrentShow.getText())) { - textCurrentShow.setText(event.getCurrentShow()); + if (!event.getScheduleItem().getTitle().equals(textCurrentShow.getText())) { + textCurrentShow.setText(event.getScheduleItem().getTitle()); + textCurrentTopic.setText(event.getScheduleItem().getTopic()); + toggleInfoOverlay(true); } + + DateTime startTime = new DateTime(event.getScheduleItem().getTimeStart()); + DateTime now = DateTime.now(); + Duration duration = new Duration(startTime, now); + + progressCurrentShow.setMax(event.getScheduleItem().getLength().intValue()); + + if (duration.getStandardSeconds() < progressCurrentShow.getMax()) { + ObjectAnimator animation = ObjectAnimator.ofInt(progressCurrentShow, "progress", (int) duration.getStandardSeconds()); + animation.setDuration(1000); + animation.setInterpolator(new DecelerateInterpolator()); + animation.start(); + } + break; case FAILED: - textViewerCount.setText(R.string.empty); textCurrentShow.setText(R.string.no_info_available); - new ChannelInfoLoader().start(); + new ChannelInfoLoader(getString(R.string.RBTVKEY), getString(R.string.RBTVSECRET)).start(); break; } Heartbeat.doHeartbeat(mFirebaseAnalytics); diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/events/ChannelInfoUpdateEvent.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/events/ChannelInfoUpdateEvent.java index 7a5ba7a..5024d0f 100644 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/events/ChannelInfoUpdateEvent.java +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/events/ChannelInfoUpdateEvent.java @@ -1,21 +1,20 @@ package de.markhaehnel.rbtv.rocketbeanstv.events; +import de.markhaehnel.rbtv.rocketbeanstv.objects.schedule.ScheduleItem; import de.markhaehnel.rbtv.rocketbeanstv.utils.Enums.EventStatus; import lombok.Getter; @Getter public class ChannelInfoUpdateEvent { - private String currentShow; - private String viewerCount; + private ScheduleItem scheduleItem; private EventStatus status; public ChannelInfoUpdateEvent(EventStatus status) { this.status = status; } - public ChannelInfoUpdateEvent(String currentShow, String viewerCount, EventStatus status) { - this.currentShow = currentShow; - this.viewerCount = viewerCount; + public ChannelInfoUpdateEvent(ScheduleItem scheduleItem, EventStatus status) { + this.scheduleItem = scheduleItem; this.status = status; } } diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ChannelInfoLoader.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ChannelInfoLoader.java index 885303f..67b1b8e 100644 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ChannelInfoLoader.java +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ChannelInfoLoader.java @@ -6,23 +6,32 @@ import org.greenrobot.eventbus.EventBus; import de.markhaehnel.rbtv.rocketbeanstv.events.ChannelInfoUpdateEvent; import de.markhaehnel.rbtv.rocketbeanstv.objects.RBTV; +import de.markhaehnel.rbtv.rocketbeanstv.objects.schedule.ScheduleItem; +import de.markhaehnel.rbtv.rocketbeanstv.utils.Authentication; import de.markhaehnel.rbtv.rocketbeanstv.utils.Enums.EventStatus; import de.markhaehnel.rbtv.rocketbeanstv.utils.NetworkHelper; public class ChannelInfoLoader extends Thread { + private String key, secret; + + public ChannelInfoLoader(String key, String secret) { + this.key = key; + this.secret = secret; + } + public void run() { //noinspection LoopStatementThatDoesntLoop while (true) { try { - String response = NetworkHelper.getContentFromUrl("https://node.markhaehnel.de/rbtv/"); + + String url = "https://api.rocketmgmt.de/schedule/current"; + + String response = NetworkHelper.getContentFromUrl(url, Authentication.getAuthenticationHeaders(key, secret)); + Gson gson = new Gson(); - RBTV data = gson.fromJson(response, RBTV.class); - if (data.getError() == null) { - EventBus.getDefault().post(new ChannelInfoUpdateEvent(data.getTitle(), data.getViewerCount(), EventStatus.OK)); - } else { - EventBus.getDefault().post(EventStatus.FAILED); - } + ScheduleItem scheduleItem = gson.fromJson(response, ScheduleItem.class); + EventBus.getDefault().post(new ChannelInfoUpdateEvent(scheduleItem, EventStatus.OK)); sleep(30000); } catch (Exception e) { FirebaseCrash.report(e); diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ScheduleLoader.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ScheduleLoader.java index 2c9e6b2..123fa52 100644 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ScheduleLoader.java +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/loader/ScheduleLoader.java @@ -1,27 +1,15 @@ package de.markhaehnel.rbtv.rocketbeanstv.loader; -import android.annotation.SuppressLint; -import android.util.Base64; - import com.google.firebase.crash.FirebaseCrash; import com.google.gson.Gson; import org.greenrobot.eventbus.EventBus; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import de.markhaehnel.rbtv.rocketbeanstv.events.ScheduleLoadEvent; import de.markhaehnel.rbtv.rocketbeanstv.objects.schedule.Schedule; -import de.markhaehnel.rbtv.rocketbeanstv.objects.schedule.ScheduleItem; +import de.markhaehnel.rbtv.rocketbeanstv.utils.Authentication; import de.markhaehnel.rbtv.rocketbeanstv.utils.Enums.EventStatus; import de.markhaehnel.rbtv.rocketbeanstv.utils.NetworkHelper; -import de.markhaehnel.rbtv.rocketbeanstv.utils.RandomString; - -import static de.markhaehnel.rbtv.rocketbeanstv.utils.AuthHelper.SHA1; public class ScheduleLoader extends Thread { @@ -36,26 +24,13 @@ public void run() { final String id = "00000000-0000-0000-0000-000000000000"; try { - @SuppressLint("SimpleDateFormat") - String created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZ").format(new Date()); - created = created.substring(0, created.length()-2) + ":" + created.substring(created.length()-2, created.length()); - - String nonce = id + created + RandomString.generate(10); - String sha1 = SHA1(nonce + created + secret); String url = "https://api.rocketmgmt.de/schedule/next/5"; - String b64sha1 = Base64.encodeToString(sha1.getBytes(), Base64.NO_WRAP); - String b64nonce = Base64.encodeToString(nonce.getBytes(), Base64.NO_WRAP); - - Map headers = new HashMap<>(); - headers.put("Accept", "application/json"); - headers.put("Authorization", "WSSE profile=\"UsernameToken\""); - headers.put("X-WSSE", "UsernameToken Username=\"" + key + "\", PasswordDigest=\"" + b64sha1 + "\", Nonce=\"" + b64nonce + "\", Created=\"" + created + "\""); - String data = NetworkHelper.getContentFromUrl(url, headers); + String data = NetworkHelper.getContentFromUrl(url, Authentication.getAuthenticationHeaders(key, secret)); Gson gson = new Gson(); Schedule scheduleData = gson.fromJson(data, Schedule.class); - EventBus.getDefault().post(new ScheduleLoadEvent(scheduleData.getNextShows(5), EventStatus.OK)); + EventBus.getDefault().post(new ScheduleLoadEvent(scheduleData.getSchedule(), EventStatus.OK)); } catch(Exception e) { FirebaseCrash.report(e); e.printStackTrace(); diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/objects/schedule/Schedule.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/objects/schedule/Schedule.java index 65c618c..3f25b63 100644 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/objects/schedule/Schedule.java +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/objects/schedule/Schedule.java @@ -6,14 +6,12 @@ import java.util.ArrayList; import java.util.List; +import lombok.Getter; + +@Getter public class Schedule { @SerializedName("schedule") @Expose private List schedule = new ArrayList(); - - public List getNextShows(int count) { - int howMuch = (count < schedule.size()) ? count : schedule.size(); - return schedule.subList(0, howMuch); - } } diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/AuthHelper.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/AuthHelper.java deleted file mode 100644 index a27a2ac..0000000 --- a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/AuthHelper.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.markhaehnel.rbtv.rocketbeanstv.utils; - -import com.google.firebase.crash.FirebaseCrash; - -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class AuthHelper { - public static String SHA1(String text) { - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] sha1hash = new byte[40]; - md.update(text.getBytes("iso-8859-1"), 0, text.length()); - sha1hash = md.digest(); - return convertToHex(sha1hash); - } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { - FirebaseCrash.report(e); - e.printStackTrace(); - } - return ""; - } - - private static String convertToHex(byte[] data) { - StringBuilder buf = new StringBuilder(); - for (byte aData : data) { - int halfbyte = (aData >>> 4) & 0x0F; - int two_halfs = 0; - do { - if ((0 <= halfbyte) && (halfbyte <= 9)) { - buf.append((char) ('0' + halfbyte)); - } else { - buf.append((char) ('a' + (halfbyte - 10))); - } - halfbyte = aData & 0x0F; - } while (two_halfs++ < 1); - } - return buf.toString(); - } -} diff --git a/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/Authentication.java b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/Authentication.java new file mode 100644 index 0000000..9a22b24 --- /dev/null +++ b/app/src/main/java/de/markhaehnel/rbtv/rocketbeanstv/utils/Authentication.java @@ -0,0 +1,30 @@ +package de.markhaehnel.rbtv.rocketbeanstv.utils; + +import android.util.Base64; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import static de.markhaehnel.rbtv.rocketbeanstv.utils.AuthHelper.SHA1; + +public class Authentication { + public static Map getAuthenticationHeaders(String key, String secret) { + final String id = "00000000-0000-0000-0000-000000000000"; + String created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZ").format(new Date()); + created = created.substring(0, created.length()-2) + ":" + created.substring(created.length()-2, created.length()); + + String nonce = id + created + RandomString.generate(10); + String sha1 = SHA1(nonce + created + secret); + String b64sha1 = Base64.encodeToString(sha1.getBytes(), Base64.NO_WRAP); + String b64nonce = Base64.encodeToString(nonce.getBytes(), Base64.NO_WRAP); + + Map headers = new HashMap<>(); + headers.put("Accept", "application/json"); + headers.put("Authorization", "WSSE profile=\"UsernameToken\""); + headers.put("X-WSSE", "UsernameToken Username=\"" + key + "\", PasswordDigest=\"" + b64sha1 + "\", Nonce=\"" + b64nonce + "\", Created=\"" + created + "\""); + + return headers; + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 274f8e7..d003bf4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -58,48 +58,74 @@ - + - - + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingBottom="8dp"> + + + + + + + + + android:maxLines="1" + android:padding="0dp" + android:textAlignment="textEnd" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="#ffcccccc" + android:textStyle="italic" + android:visibility="visible"/> +