Added program managment options.. Shuffle, Block Shuffle, Sort, and Remove Dups..
This commit is contained in:
parent
f030b2785c
commit
4ffc036fd2
4
index.js
4
index.js
@ -32,6 +32,9 @@ process.env.HOST = process.env.HOST || "127.0.0.1"
|
||||
if (!fs.existsSync(process.env.DATABASE))
|
||||
fs.mkdirSync(process.env.DATABASE)
|
||||
|
||||
if(!fs.existsSync(path.join(process.env.DATABASE, 'images')))
|
||||
fs.mkdirSync(path.join(process.env.DATABASE, 'images'))
|
||||
|
||||
db.connect(process.env.DATABASE, ['channels', 'plex-servers', 'ffmpeg-settings', 'xmltv-settings', 'hdhr-settings'])
|
||||
|
||||
initDB(db)
|
||||
@ -89,6 +92,7 @@ let hdhr = HDHR(db)
|
||||
let app = express()
|
||||
app.use(bodyParser.json({limit: '50mb'}))
|
||||
app.use(express.static(path.join(__dirname, 'web/public')))
|
||||
app.use('/images', express.static(path.join(process.env.DATABASE, 'images')))
|
||||
app.use(api.router(db, xmltvInterval))
|
||||
app.use(video.router(db))
|
||||
app.use(hdhr.router)
|
||||
|
||||
@ -39,6 +39,107 @@ module.exports = function ($timeout) {
|
||||
scope.$watch('channel.startTime', () => {
|
||||
updateChannelDuration()
|
||||
})
|
||||
scope.sortShows = () => {
|
||||
let shows = {}
|
||||
let movies = []
|
||||
let newProgs = []
|
||||
let progs = scope.channel.programs
|
||||
for (let i = 0, l = progs.length; i < l; i++) {
|
||||
if (progs[i].type === 'movie') {
|
||||
movies.push(progs[i])
|
||||
} else {
|
||||
if (typeof shows[progs[i].showTitle] === 'undefined')
|
||||
shows[progs[i].showTitle] = []
|
||||
shows[progs[i].showTitle].push(progs[i])
|
||||
}
|
||||
}
|
||||
let keys = Object.keys(shows)
|
||||
for (let i = 0, l = keys.length; i < l; i++) {
|
||||
shows[keys[i]].sort((a, b) => {
|
||||
if (a.season === b.season) {
|
||||
if (a.episode > b.episode) {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
} else if (a.season > b.season) {
|
||||
return 1;
|
||||
} else if (b.season > a.season) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
newProgs = newProgs.concat(shows[keys[i]])
|
||||
}
|
||||
scope.channel.programs = newProgs.concat(movies)
|
||||
updateChannelDuration()
|
||||
}
|
||||
scope.removeDuplicates = () => {
|
||||
let tmpProgs = {}
|
||||
let progs = scope.channel.programs
|
||||
for (let i = 0, l = progs.length; i < l; i++) {
|
||||
if (progs[i].type === 'movie') {
|
||||
tmpProgs[progs[i].title + progs[i].durationStr] = progs[i]
|
||||
} else {
|
||||
tmpProgs[progs[i].showTitle + '-' + progs[i].season + '-' + progs[i].episode] = progs[i]
|
||||
}
|
||||
}
|
||||
let newProgs = []
|
||||
let keys = Object.keys(tmpProgs)
|
||||
for (let i = 0, l = keys.length; i < l; i++) {
|
||||
newProgs.push(tmpProgs[keys[i]])
|
||||
}
|
||||
scope.channel.programs = newProgs
|
||||
}
|
||||
scope.blockShuffle = (blockCount) => {
|
||||
if (typeof blockCount === 'undefined' || blockCount == null)
|
||||
return
|
||||
let shows = {}
|
||||
let movies = []
|
||||
let newProgs = []
|
||||
let progs = scope.channel.programs
|
||||
for (let i = 0, l = progs.length; i < l; i++) {
|
||||
if (progs[i].type === 'movie') {
|
||||
movies.push(progs[i])
|
||||
} else {
|
||||
if (typeof shows[progs[i].showTitle] === 'undefined')
|
||||
shows[progs[i].showTitle] = []
|
||||
shows[progs[i].showTitle].push(progs[i])
|
||||
}
|
||||
}
|
||||
let keys = Object.keys(shows)
|
||||
let index = 0
|
||||
while (keys.length > 0) {
|
||||
if (shows[keys[index]].length === 0) {
|
||||
keys.splice(index, 1)
|
||||
if (index >= keys.length)
|
||||
index = 0
|
||||
continue
|
||||
}
|
||||
for (let i = 0, l = blockCount; i < l; i++) {
|
||||
if (shows[keys[index]].length > 0)
|
||||
newProgs.push(shows[keys[index]].shift())
|
||||
}
|
||||
index++
|
||||
if (index >= keys.length)
|
||||
index = 0
|
||||
}
|
||||
|
||||
scope.channel.programs = newProgs.concat(movies)
|
||||
updateChannelDuration()
|
||||
}
|
||||
scope.randomShuffle = () => {
|
||||
randomShuffle(scope.channel.programs)
|
||||
updateChannelDuration()
|
||||
}
|
||||
function randomShuffle(a) {
|
||||
for (let i = a.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[a[i], a[j]] = [a[j], a[i]];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
function updateChannelDuration() {
|
||||
scope.channel.duration = 0
|
||||
for (let i = 0, l = scope.channel.programs.length; i < l; i++) {
|
||||
|
||||
@ -40,40 +40,41 @@ module.exports = function (plex, pseudotv) {
|
||||
scope.$apply(() => {
|
||||
scope.libraries = lib
|
||||
if (play.length > 0)
|
||||
scope.libraries.push({ title: "Playlists", key: "", icon: "", nested: play, collapse: false })
|
||||
scope.libraries.push({ title: "Playlists", key: "", icon: "", nested: play })
|
||||
})
|
||||
})
|
||||
}, (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
scope.getNested = function (list) {
|
||||
if (typeof list.collapse == 'undefined') {
|
||||
plex.getNested(scope.plexServer, list.key).then((res) => {
|
||||
list.nested = res
|
||||
list.collapse = true
|
||||
scope.$apply()
|
||||
}, (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
} else {
|
||||
list.collapse = !list.collapse
|
||||
scope.getNested = async (list) => {
|
||||
let r = false
|
||||
if (typeof list.nested == 'undefined') {
|
||||
list.nested = await plex.getNested(scope.plexServer, list.key)
|
||||
r = true
|
||||
}
|
||||
list.collapse = !list.collapse
|
||||
if (r)
|
||||
scope.$apply()
|
||||
}
|
||||
scope.selectPlaylist = (playlist) => {
|
||||
if (typeof playlist.collapse == 'undefined') {
|
||||
plex.getNested(scope.plexServer, playlist.key).then((res) => {
|
||||
playlist.nested = res
|
||||
for (let i = 0, l = playlist.nested.length; i < l; i++)
|
||||
scope.selectItem(playlist.nested[i])
|
||||
scope.$apply()
|
||||
}, (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
} else {
|
||||
for (let i = 0, l = playlist.nested.length; i < l; i++)
|
||||
scope.selectItem(playlist.nested[i])
|
||||
}
|
||||
|
||||
scope.selectSeason = async (season) => {
|
||||
if (typeof season.nested == 'undefined')
|
||||
season.nested = await plex.getNested(scope.plexServer, season.key)
|
||||
for (let i = 0, l = season.nested.length; i < l; i++)
|
||||
scope.$apply(() => { scope.selectItem(season.nested[i]) })
|
||||
}
|
||||
scope.selectShow = async (show) => {
|
||||
if (typeof show.nested == 'undefined')
|
||||
show.nested = await plex.getNested(scope.plexServer, show.key)
|
||||
for (let i = 0, l = show.nested.length; i < l; i++)
|
||||
await scope.selectSeason(show.nested[i])
|
||||
}
|
||||
scope.selectPlaylist = async (playlist) => {
|
||||
if (typeof playlist.nested == 'undefined')
|
||||
playlist.nested = await plex.getNested(scope.plexServer, playlist.key)
|
||||
for (let i = 0, l = playlist.nested.length; i < l; i++)
|
||||
scope.$apply(() => { scope.selectItem(playlist.nested[i]) })
|
||||
}
|
||||
scope.createShowIdentifier = (season, ep) => {
|
||||
return 'S' + (season.toString().padStart(2, '0')) + 'E' + (ep.toString().padStart(2, '0'))
|
||||
|
||||
@ -37,6 +37,9 @@
|
||||
<div>
|
||||
|
||||
<h6>Programs
|
||||
<button class="btn btn-sm btn-secondary" style="margin-left: 10px" ng-click="showShuffleOptions = !showShuffleOptions" ng-show="channel.programs.length !== 0">
|
||||
Shuffle / Sort
|
||||
</button>
|
||||
<span class="pull-right">
|
||||
<span class="text-danger small">{{error.programs}}</span>
|
||||
<button class="btn btn-sm btn-primary" ng-click="displayPlexLibrary = true">
|
||||
@ -44,7 +47,24 @@
|
||||
</button>
|
||||
</span>
|
||||
</h6>
|
||||
|
||||
<div ng-init="blockCount = 1; showShuffleOptions = false" ng-show="showShuffleOptions">
|
||||
<p class="text-center text-info small">"Block Shuffle" and "Sort TV Shows" will push any movies to the end of the channel.</p>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<button class="btn btn-sm btn-warning" type="button" ng-click="blockShuffle(blockCount)">Block Shuffle</button>
|
||||
</div>
|
||||
<input type="number" class="form-control form-control-sm" placeholder="Desired number of consecutive TV shows." min="1" max="10" ng-model="blockCount">
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="randomShuffle()">Random Shuffle</button>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="sortShows()">Sort TV Shows</button>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<button class="btn btn-sm btn-warning form-control form-control-sm" type="button" ng-click="removeDuplicates()">Remove Duplicates</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="channel.programs.length === 0">
|
||||
<div class="small">Add programs to this channel by selecting media from your Plex library
|
||||
</div>
|
||||
|
||||
@ -54,7 +54,9 @@
|
||||
<span ng-if="b.type === 'playlist'" class="flex-pull-right" ng-click="selectPlaylist(b); $event.stopPropagation()">
|
||||
<span class="fa fa-plus btn"></span>
|
||||
</span>
|
||||
|
||||
<span ng-if="b.type === 'show'" class="flex-pull-right" ng-click="selectShow(b); $event.stopPropagation()">
|
||||
<span class="fa fa-plus btn"></span>
|
||||
</span>
|
||||
</div>
|
||||
<ul ng-if="b.collapse" class="list-group">
|
||||
<li ng-repeat="c in b.nested"
|
||||
@ -76,6 +78,9 @@
|
||||
class="flex-pull-right">
|
||||
{{c.durationStr}}
|
||||
</span>
|
||||
<span ng-if="c.type === 'season'" class="flex-pull-right" ng-click="selectSeason(c); $event.stopPropagation()">
|
||||
<span class="fa fa-plus btn"></span>
|
||||
</span>
|
||||
</div>
|
||||
<ul ng-if="c.collapse" class="list-group">
|
||||
<li class="list-group-item list-group-item-video"
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
<input class="form-control form-control-sm" type="text" ng-model="program.rating"/>
|
||||
<label>Icon</label>
|
||||
<input class="form-control form-control-sm" type="text" ng-model="program.icon"/>
|
||||
<b>Icon Preview</b>
|
||||
<h6>Icon Preview</h6>
|
||||
<div class="text-center">
|
||||
<img class="img" ng-src="{{program.icon}}" style="max-width: 200px;"/>
|
||||
</div>
|
||||
@ -53,9 +53,9 @@
|
||||
<input class="form-control form-control-sm" type="text" ng-model="program.rating"/>
|
||||
<label>Icon</label>
|
||||
<input class="form-control form-control-sm" type="text" ng-model="program.icon"/>
|
||||
<h6>Icon Preview</h6>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<b>Icon Preview</b>
|
||||
<div class="text-center">
|
||||
<img class="img" ng-src="{{program.icon}}" style="max-width: 200px;"/>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user