/* * Copyright (c) 2014-2016 Jan Strauß <jan[at]over9000.eu> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package eu.over9000.skadi.model; import eu.over9000.skadi.remote.data.ChannelMetadata; import eu.over9000.skadi.util.NotificationUtil; import javafx.beans.binding.Bindings; import javafx.beans.property.*; import javafx.collections.FXCollections; import javafx.scene.chart.XYChart; import javafx.scene.image.Image; import java.time.LocalTime; import java.util.Objects; import java.util.concurrent.Callable; import java.util.stream.IntStream; public class Channel { private static final String DEFAULT_CHANNEL_LOGO = "http://static-cdn.jtvnw.net/jtv_user_pictures/xarth/404_user_150x150.png"; private final StringProperty name; private final StringProperty title; private final LongProperty viewer; private final LongProperty uptime; private final ObjectProperty<Boolean> online; private final ObjectProperty<Boolean> wasOnline; private final StringProperty game; private final ListProperty<XYChart.Data<Number, Number>> viewerHistory; private final LongProperty viewerHistoryAverage; private final StringProperty logoURL; private final ObjectProperty<LocalTime> lastUpdated; private final LongProperty followers; private final LongProperty views; private final ObjectProperty<Boolean> partner; private final ObjectProperty<Image> preview; public Channel(final String name) { this.name = new SimpleStringProperty(name); title = new SimpleStringProperty("-"); viewer = new SimpleLongProperty(0); uptime = new SimpleLongProperty(0); online = new SimpleObjectProperty<>(); wasOnline = new SimpleObjectProperty<>(); game = new SimpleStringProperty("-"); viewerHistory = new SimpleListProperty<>(FXCollections.observableArrayList()); viewerHistoryAverage = new SimpleLongProperty(); viewerHistoryAverage.bind(Bindings.createIntegerBinding(buildAvgFunc(), viewerHistory)); logoURL = new SimpleStringProperty(DEFAULT_CHANNEL_LOGO); lastUpdated = new SimpleObjectProperty<>(LocalTime.now()); followers = new SimpleLongProperty(); views = new SimpleLongProperty(); partner = new SimpleObjectProperty<>(); preview = new SimpleObjectProperty<>(); } public void updateFrom(final ChannelMetadata u) { if (u.hasTitle()) { setTitle(u.getTitle()); } if (u.hasOnline()) { updateOnline(u.getOnline()); } if (u.hasViewer()) { updateViewer(u.getViewer()); } if (u.hasGame()) { setGame(u.getGame()); } if (u.hasUptime()) { setUptime(u.getUptime()); } if (u.hasLogoURL()) { setLogoURL(u.getLogoURL()); } if (u.hasFollowers()) { setFollowers(u.getFollowers()); } if (u.hasViews()) { setViews(u.getViews()); } if (u.hasPartner()) { setPartner(u.getPartner()); } setLastUpdated(LocalTime.now()); if (cameOnline()) { NotificationUtil.showOnlineNotification(this); } } private boolean cameOnline() { final boolean wasNotOnline = (getWasOnline() != null) && !getWasOnline(); final boolean isNowOnline = (isOnline() != null) && isOnline(); return wasNotOnline && isNowOnline; } private Callable<Integer> buildAvgFunc() { return () -> viewerHistory.isEmpty() ? 0 : (int) viewerHistory.stream().flatMapToInt(data -> IntStream.of(data.getYValue().intValue())).average().getAsDouble(); } private void updateViewer(final long viewer) { setViewer(viewer); getViewerHistory().add(new XYChart.Data<>(System.currentTimeMillis(), viewer)); } private void updateOnline(final Boolean online) { wasOnline.set(isOnline()); setOnline(online); } @Override public String toString() { return "Channel [name=" + getName() + "]"; } public String buildURL() { return "http://www.twitch.tv/" + getName() + "/"; } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final Channel channel = (Channel) o; return Objects.equals(name, channel.name); } @Override public int hashCode() { return Objects.hash(name); } public final StringProperty nameProperty() { return name; } public final String getName() { return nameProperty().get(); } public final StringProperty titleProperty() { return title; } public final String getTitle() { return titleProperty().get(); } public final void setTitle(final String title) { titleProperty().set(title); } public final LongProperty viewerProperty() { return viewer; } public final long getViewer() { return viewerProperty().get(); } public final void setViewer(final long viewer) { viewerProperty().set(viewer); } public final LongProperty uptimeProperty() { return uptime; } public final long getUptime() { return uptimeProperty().get(); } public final void setUptime(final long uptime) { uptimeProperty().set(uptime); } public final ObjectProperty<Boolean> onlineProperty() { return online; } public final Boolean isOnline() { return onlineProperty().get(); } public final void setOnline(final Boolean online) { onlineProperty().set(online); } public final StringProperty gameProperty() { return game; } public final String getGame() { return gameProperty().get(); } public final void setGame(final String game) { gameProperty().set(game); } public final ListProperty<XYChart.Data<Number, Number>> viewerHistoryProperty() { return viewerHistory; } public final javafx.collections.ObservableList<javafx.scene.chart.XYChart.Data<Number, Number>> getViewerHistory() { return viewerHistoryProperty().get(); } public final LongProperty viewerHistoryAverageProperty() { return viewerHistoryAverage; } public final long getViewerHistoryAverage() { return viewerHistoryAverageProperty().get(); } public final StringProperty logoURLProperty() { return logoURL; } public final String getLogoURL() { return logoURLProperty().get(); } public final void setLogoURL(final String logoURL) { logoURLProperty().set(logoURL); } public final ObjectProperty<LocalTime> lastUpdatedProperty() { return lastUpdated; } public final LocalTime getLastUpdated() { return lastUpdatedProperty().get(); } public final void setLastUpdated(final LocalTime lastUpdated) { lastUpdatedProperty().set(lastUpdated); } public final ObjectProperty<Boolean> wasOnlineProperty() { return wasOnline; } public final Boolean getWasOnline() { return wasOnlineProperty().get(); } public final LongProperty followersProperty() { return followers; } public final long getFollowers() { return followersProperty().get(); } public final void setFollowers(final long followers) { followersProperty().set(followers); } public final LongProperty viewsProperty() { return views; } public final long getViews() { return viewsProperty().get(); } public final void setViews(final long views) { viewsProperty().set(views); } public final ObjectProperty<Boolean> partnerProperty() { return partner; } public final Boolean getPartner() { return partnerProperty().get(); } public final void setPartner(final Boolean partner) { partnerProperty().set(partner); } public Image getPreview() { return preview.get(); } public void setPreview(final Image preview) { this.preview.set(preview); } public ObjectProperty<Image> previewProperty() { return preview; } }