Skip to content

Commit

Permalink
Implement custom Vodcast filtering
Browse files Browse the repository at this point in the history
As an addition to d10813d (#478)
  • Loading branch information
bastimeyer committed Nov 16, 2017
1 parent bd77cc3 commit 9859acd
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/app/components/list/StreamItemComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ export default ListItemComponent.extend({


fadeVodcast: computed( "content.isVodcast", "settings.streams.filter_vodcast", function() {
return get( this, "content.isVodcast" )
&& get( this, "settings.streams.filter_vodcast" );
return get( this, "settings.streams.filter_vodcast" )
&& get( this, "content.isVodcast" );
}),


Expand Down
6 changes: 5 additions & 1 deletion src/app/controllers/SettingsListsController.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Controller } from "ember";
import SettingsStreams from "models/localstorage/Settings/streams";
import {
default as SettingsStreams,
DEFAULT_VODCAST_REGEXP
} from "models/localstorage/Settings/streams";
import { isDarwin } from "utils/node/platform";


export default Controller.extend({
SettingsStreams,
DEFAULT_VODCAST_REGEXP,
isDarwin
});
5 changes: 5 additions & 0 deletions src/app/models/localstorage/Settings/streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export const ATTR_STREAMS_CLICK_CHAT = 2;
export const ATTR_STREAMS_CLICK_CHANNEL = 3;
export const ATTR_STREAMS_CLICK_SETTINGS = 4;

// eslint-disable-next-line max-len
export const DEFAULT_VODCAST_REGEXP = "\\b(not live|re-?(run|streaming)|(vod-?|re-?broad)cast(ing)?)\\b";


export default Fragment.extend({
name: attr( "number", { defaultValue: ATTR_STREAMS_NAME_BOTH } ),
Expand All @@ -30,6 +33,8 @@ export default Fragment.extend({
twitchemotes: attr( "boolean", { defaultValue: false } ),

filter_vodcast: attr( "boolean", { defaultValue: true } ),
vodcast_regexp: attr( "string", { defaultValue: "" } ),

filter_languages: attr( "boolean", { defaultValue: false } ),
languages: fragment( "settingsStreamsLanguages", { defaultValue: {} } ),

Expand Down
63 changes: 50 additions & 13 deletions src/app/models/twitch/Stream.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import {
get,
computed
computed,
inject
} from "ember";
import {
attr,
belongsTo,
Model
} from "ember-data";
import Moment from "moment";
import { DEFAULT_VODCAST_REGEXP } from "models/localstorage/Settings/streams";


const { and } = computed;
const { service } = inject;


/**
* @typedef {Object} FPSRange
* @property {Number} target
* @property {Number} min
* @property {Number} max
*/

/**
* Try to fix the weird fps numbers received from twitch...
Expand All @@ -32,13 +43,6 @@ const fpsRanges = [
{ target: 144, min: 142, max: 146 }
];

/**
* @typedef {Object} FPSRange
* @property {Number} target
* @property {Number} min
* @property {Number} max
*/


export default Model.extend({
average_fps: attr( "number" ),
Expand All @@ -54,15 +58,48 @@ export default Model.extend({
video_height: attr( "number" ),
viewers: attr( "number" ),

hasFormatInfo: and( "video_height", "average_fps" ),

settings: service(),

// both properties are not documented in the v5 API
isVodcast: computed( "broadcast_platform", "stream_type", function() {
return get( this, "broadcast_platform" ) === "watch_party"
|| get( this, "stream_type" ) === "watch_party";

reVodcast: computed( "settings.streams.vodcast_regexp", function() {
const vodcast_regexp = get( this, "settings.streams.vodcast_regexp" );
if ( vodcast_regexp.length && !vodcast_regexp.trim().length ) {
return null;
}
try {
return new RegExp( vodcast_regexp || DEFAULT_VODCAST_REGEXP, "i" );
} catch ( e ) {
return null;
}
}),

// both properties are not documented in the v5 API
isVodcast: computed(
"broadcast_platform",
"stream_type",
"reVodcast",
"channel.status",
function() {
if (
get( this, "broadcast_platform" ) === "watch_party"
|| get( this, "stream_type" ) === "watch_party"
) {
return true;
}

const reVodcast = get( this, "reVodcast" );
const status = get( this, "channel.status" );

return reVodcast && status
? reVodcast.test( status )
: false;
}
),


hasFormatInfo: and( "video_height", "average_fps" ),


titleCreatedAt: computed( "created_at", function() {
const created_at = get( this, "created_at" );
Expand Down
17 changes: 17 additions & 0 deletions src/templates/settings/SettingsLists.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@
{{check-box "Fade out Vodcasts" checked=model.streams.filter_vodcast}}
{{/settings-row}}

{{#if model.advanced}}
{{#settings-row
"Custom Vodcast filtering"
"Find untagged Vodcasts/Rebroadcasts."
icon="fa-search"
notes="A JavaScript compliant regular expression (case-insensitive), applied to the stream title. To disable filtering, enter an empty string or an invalid regular expression."
}}
{{input
type="text"
value=model.streams.vodcast_regexp
placeholder=DEFAULT_VODCAST_REGEXP
class="col-xs-12"
}}
{{/settings-row}}
{{/if}}


{{#settings-row
"Info bar"
"Bottom bar inside the stream preview."
Expand Down
50 changes: 50 additions & 0 deletions src/test/tests/models/localstorage/Settings/streams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
module,
test
} from "qunit";
import { DEFAULT_VODCAST_REGEXP } from "models/localstorage/Settings/streams";


module( "models/localstorage/Settings/streams" );


test( "Default Vodcast RegExp", assert => {

const re = new RegExp( DEFAULT_VODCAST_REGEXP, "i" );

const shouldMatch = [
"I'M NOT LIVE!!!",
"RERUN: Title",
"This is a re-run of yesterday's stream",
"Restreaming yesterday's stream",
"I'm just re-streaming",
"vodcast",
"vod-cast",
"vodcasting",
"vod-casting",
"rebroadcast",
"re-broadcast",
"rebroadcasting",
"re-broadcasting"
];

const shouldNotMatch = [
"rerunning",
"re-running",
"restream",
"re-stream",
"This broadcast is presented by",
"Fear not. Live your life!"
];

assert.ok(
shouldMatch.every( str => re.test( str ) ),
"All strings expected to match match"
);
assert.ok(
!shouldNotMatch.some( str => re.test( str ) ),
"All strings expected not to match don't match"
);

});

39 changes: 31 additions & 8 deletions src/test/tests/models/twitch/Stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ module( "models/twitch/Stream", {
beforeEach() {
owner = buildOwner();

owner.register( "service:auth", Service.extend() );
owner.register( "model:twitch-stream", Stream );
owner.register( "adapter:twitch-stream", StreamAdapter );
owner.register( "serializer:twitch-stream", StreamSerializer );
Expand All @@ -50,6 +49,13 @@ module( "models/twitch/Stream", {
owner.register( "model:twitch-image", TwitchImage );
owner.register( "serializer:twitch-image", ImageSerializer );

owner.register( "service:auth", Service.extend() );
owner.register( "service:settings", Service.extend({
streams: {
vodcast_regexp: ""
}
}) );

env = setupStore( owner );
},

Expand Down Expand Up @@ -180,31 +186,48 @@ test( "Adapter and Serializer (many)", assert => {

test( "Computed properties", assert => {

const record = env.store.createRecord( "twitchStream", {} );
const channel = env.store.createRecord( "twitchChannel", {
status: ""
});
const record = env.store.createRecord( "twitchStream", { channel } );


// vodcast

assert.ok( get( record, "reVodcast" ) instanceof RegExp, "Has a default vodcast RegExp" );

set( record, "settings.streams.vodcast_regexp", " " );
assert.strictEqual( get( record, "reVodcast" ), null, "Returns null on empty RegExp" );

set( record, "settings.streams.vodcast_regexp", "(" );
assert.strictEqual( get( record, "reVodcast" ), null, "Returns null on invalid RegExp" );

set( record, "settings.streams.vodcast_regexp", "I'm a vodcast" );
assert.ok( get( record, "reVodcast" ).test( "I'M A VODCAST" ), "Has a custom vodcast RegExp" );

assert.notOk( get( record, "isVodcast" ), "Not a vodcast" );

run( () => setProperties( record, {
setProperties( record, {
broadcast_platform: "watch_party",
stream_type: "live"
}) );
});
assert.ok( get( record, "isVodcast" ), "Is a vodcast now" );

run( () => setProperties( record, {
setProperties( record, {
broadcast_platform: "live",
stream_type: "watch_party"
}) );
});
assert.ok( get( record, "isVodcast" ), "Is still a vodcast" );

run( () => setProperties( record, {
setProperties( record, {
broadcast_platform: "live",
stream_type: "live"
}) );
});
assert.notOk( get( record, "isVodcast" ), "Not a vodcast anymore" );

set( record, "channel.status", "I'm a vodcast" );
assert.ok( get( record, "isVodcast" ), "Is a vodcast because of its title" );


// titleCreatedAt

Expand Down

0 comments on commit 9859acd

Please sign in to comment.