-
Notifications
You must be signed in to change notification settings - Fork 278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add subtitle search SFC #6727
Add subtitle search SFC #6727
Changes from 11 commits
e0695d1
ce17f32
3afb8e8
754001e
cd8c922
6740348
63642d0
025366d
9be825f
e31e5f0
a77a3b9
3c9abf0
c21052a
6aabce1
1c32bd7
b7dce65
a131dd3
cab1ca5
3c72e89
6193880
7d8adc5
9cda490
8b33d3c
210f456
f6fecd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
<template> | ||
<!-- template for the subtitle-search component --> | ||
<tr class='subtitle-search-wrapper'> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<td colspan='9999' transition="expand"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span v-if="loading" class="loading-message">{{loadingMessage}} <state-switch :theme="config.themeName" state="loading"></state-switch></span> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<div v-if="displayQuestion" class="search-question"> | ||
<div class="question"> | ||
<p>Do you want to manually pick subtitles or let us choose it for you?</p> | ||
</div> | ||
<div class="options"> | ||
<button type="button" class="btn-medusa btn-info" @click="autoSearch">Auto</button> | ||
<button type="button" class="btn-medusa btn-success" @click="manualSearch">Manual</button> | ||
</div> | ||
</div> | ||
|
||
<vue-good-table v-if="subtitles.length" | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
:columns="columns" | ||
:rows="subtitles" | ||
:search-options="{ | ||
enabled: false | ||
}" | ||
:sort-options="{ | ||
enabled: true, | ||
initialSortBy: { field: 'score', type: 'desc' } | ||
}" | ||
styleClass="vgt-table condensed subtitle-table" | ||
> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<template slot="table-column" slot-scope="props"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span v-if="props.column.label == 'Download'"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span>{{props.column.label}}</span> | ||
<span class="btn-medusa btn-xs pull-right" @click="$destroy">hide</span> | ||
</span> | ||
<span v-else> | ||
{{props.column.label}} | ||
</span> | ||
</template> | ||
<template slot="table-row" slot-scope="props"> | ||
<span v-if="props.column.field == 'provider'"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<img :src="`images/subtitles/${props.row.provider}.png`" width="16" height="16"/> | ||
<span :title="props.row.provider">{{props.row.provider}}</span> | ||
</span> | ||
<span v-else-if="props.column.field == 'lang'"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<img :title="props.row.lang" :src="`images/subtitles/flags/${props.row.lang}.png`" width="16" height="11"/> | ||
</span> | ||
<span v-else-if="props.column.field == 'filename'"> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<a :title="`Download ${props.row.hearing_impaired ? 'hearing impaired ' : ' '} subtitle: ${props.row.filename}`" @click="pickSubtitle(props.row.id)"> | ||
<img v-if="props.row.hearing_impaired" src="images/hearing_impaired.png" width="16" height="16"/> | ||
<span class="subtitle-name">{{props.row.filename}}</span> | ||
<img v-if="props.row.sub_score >= props.row.min_score" src="images/save.png" width="16" height="16"/> | ||
</a> | ||
</span> | ||
<span v-else-if="props.column.field == 'download'"> | ||
<a :title="`Download ${props.row.hearing_impaired ? 'hearing impaired ' : ' '} subtitle: ${props.row.filename}`" @click="pickSubtitle(props.row.id)"> | ||
<img src="images/download.png" width="16" height="16"/> | ||
</a> | ||
</span> | ||
<span v-else> | ||
{{props.formattedRow[props.column.field]}} | ||
</span> | ||
</template> | ||
</vue-good-table> | ||
</td> | ||
</tr> | ||
</template> | ||
<script> | ||
|
||
import { mapState } from 'vuex'; | ||
import { VueGoodTable } from 'vue-good-table'; | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export default { | ||
name: 'subtitle-search', | ||
components: { | ||
VueGoodTable | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
props: { | ||
show: { | ||
type: Object, | ||
required: true | ||
}, | ||
season: { | ||
type: [String, Number], | ||
required: true | ||
}, | ||
episode: { | ||
type: [String, Number], | ||
required: true | ||
} | ||
}, | ||
data() { | ||
return { | ||
columns: [{ | ||
label: 'Filename', | ||
field: 'filename' | ||
}, { | ||
label: 'Language', | ||
field: 'lang' | ||
}, { | ||
label: 'Provider', | ||
field: 'provider' | ||
}, { | ||
label: 'Score', | ||
field: 'score', | ||
type: 'number' | ||
}, { | ||
label: 'Sub Score', | ||
field: 'sub_score', | ||
type: 'number' | ||
}, { | ||
label: 'Missing Matches', | ||
field: rowObj => { | ||
if (rowObj.missing_guess) { | ||
return rowObj.missing_guess.join(', '); | ||
} | ||
}, | ||
type: 'array' | ||
}, { | ||
label: 'Download', | ||
field: 'download' | ||
}], | ||
subtitles: [], | ||
displayQuestion: false, | ||
loading: false, | ||
loadingMessage: '' | ||
}; | ||
}, | ||
computed: { | ||
...mapState({ | ||
config: state => state.config | ||
}) | ||
}, | ||
mounted() { | ||
this.displayQuestion = true; | ||
}, | ||
destroyed() { | ||
// Remove the element from the DOM | ||
this.$el.parentNode.removeChild(this.$el); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😬
P.S. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's really needed. I can call $destory() as much as I want. But it won't remove the node. |
||
}, | ||
methods: { | ||
autoSearch() { | ||
const { episode, season, show } = this; | ||
|
||
this.displayQuestion = false; | ||
const url = `home/searchEpisodeSubtitles?indexername=${show.indexer}&seriesid=${show.id[show.indexer]}&season=${season}&episode=${episode}`; | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.loadingMessage = 'Searching for subtitles and downloading if available... '; | ||
this.loading = true; | ||
apiRoute(url) // eslint-disable-line no-undef | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.then(response => { | ||
if (response.data.result !== 'failure') { | ||
// Update the show, as we have new information (subtitles) | ||
// Let's emit an event, telling the displayShow component, to update the show using the api/store. | ||
this.$emit('update', { | ||
reason: 'new subtitles found', | ||
codes: response.data.subtitles, | ||
languages: response.data.languages | ||
}); | ||
} | ||
}) | ||
.catch(error => { | ||
console.log(`Error trying to search for subtitles. Error: ${error}`); | ||
}) | ||
.finally(() => { | ||
// Destroy this component. | ||
this.loadingMessage = ''; | ||
this.loading = false; | ||
this.$destroy(); | ||
}); | ||
}, | ||
manualSearch() { | ||
const { show, season, episode } = this; | ||
|
||
this.displayQuestion = false; | ||
this.loading = true; | ||
this.loadingMessage = 'Searching for subtitles... '; | ||
const url = `home/manualSearchSubtitles?indexername=${show.indexer}&seriesid=${show.id[show.indexer]}&season=${season}&episode=${episode}`; | ||
apiRoute(url) // eslint-disable-line no-undef | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.then(response => { | ||
if (response.data.result === 'success') { | ||
this.subtitles.push(...response.data.subtitles); | ||
} | ||
}).catch(error => { | ||
console.log(`Error trying to search for subtitles. Error: ${error}`); | ||
this.$destroy(); | ||
}).finally(() => { | ||
this.loading = false; | ||
}); | ||
}, | ||
pickSubtitle(subtitleId) { | ||
// Download and save this subtitle with the episode. | ||
const { show, season, episode } = this; | ||
|
||
this.displayQuestion = false; | ||
this.loadingMessage = 'downloading subtitle... '; | ||
this.loading = true; | ||
const url = `home/manualSearchSubtitles?indexername=${show.indexer}&seriesid=${show.id[show.indexer]}&season=${season}&episode=${episode}&picked_id=${subtitleId}`; | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
apiRoute(url) // eslint-disable-line no-undef | ||
.then(response => { | ||
if (response.data.result === 'success') { | ||
// Update the show, as we have new information (subtitles) | ||
// Let's emit an event, telling the displayShow component, to update the show using the api/store. | ||
this.$emit('update', { | ||
reason: 'new subtitles found', | ||
codes: response.data.subtitles, | ||
languages: response.data.languages | ||
}); | ||
} | ||
}) | ||
.catch(error => { | ||
console.log(`Error trying to search for subtitles. Error: ${error}`); | ||
}) | ||
.finally(() => { | ||
// Destroy this component. | ||
this.loadingMessage = ''; | ||
this.loading = false; | ||
this.$destroy(); | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
} | ||
} | ||
}; | ||
</script> | ||
<style> | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.v--modal-overlay .v--modal-box { | ||
p0psicles marked this conversation as resolved.
Show resolved
Hide resolved
|
||
overflow: inherit!important; | ||
} | ||
table.subtitle-table tr { | ||
background-color: rgb(190, 222, 237); | ||
} | ||
.subtitle-search-wrapper { | ||
display: table-row; | ||
column-span: all; | ||
} | ||
tr.subtitle-search-wrapper > td { | ||
padding: 0; | ||
} | ||
/* always present */ | ||
.expand-transition { | ||
transition: all .3s ease; | ||
height: 30px; | ||
padding: 10px; | ||
background-color: #eee; | ||
overflow: hidden; | ||
} | ||
/* .expand-enter defines the starting state for entering */ | ||
/* .expand-leave defines the ending state for leaving */ | ||
.expand-enter, .expand-leave { | ||
height: 0; | ||
padding: 0 10px; | ||
opacity: 0; | ||
} | ||
.search-question, .loading-message { | ||
background-color: rgb(51, 51, 51); | ||
color: rgb(255,255,255); | ||
padding: 10px; | ||
line-height: 55px; | ||
} | ||
span.subtitle-name { | ||
color: rgb(0, 0, 0); | ||
} | ||
</style> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
{ | ||
"plot": "A television anthology series that shows the dark side of life and technology.", | ||
"status": "Continuing", | ||
"network": "Netflix", | ||
"language": "en", | ||
"countries": ["UNITED KINGDOM"], | ||
"seasonCount": { | ||
"0": 2, | ||
"1": 3, | ||
"2": 3, | ||
"3": 6, | ||
"4": 6, | ||
"5": 3 | ||
}, | ||
"allSceneExceptions": { | ||
"-1": [] | ||
}, | ||
"classification": "", | ||
"countryCodes": ["gb"], | ||
"id": { | ||
"trakt": 41793, | ||
"tvdb": 253463, | ||
"imdb": "tt2085059", | ||
"slug": "tvdb253463" | ||
}, | ||
"sceneNumbering": [], | ||
"xemAbsoluteNumbering": [], | ||
"config": { | ||
"locationValid": true, | ||
"sports": false, | ||
"scene": false, | ||
"airdateOffset": 0, | ||
"defaultEpisodeStatus": "Wanted", | ||
"airByDate": false, | ||
"seasonFolders": true, | ||
"dvdOrder": false, | ||
"location": "/Shows/Black Mirror", | ||
"paused": false, | ||
"release": { | ||
"requiredWordsExclude": false, | ||
"requiredWords": [], | ||
"ignoredWordsExclude": false, | ||
"ignoredWords": [] | ||
}, | ||
"anime": false, | ||
"qualities": { | ||
"allowed": [8, 32, 64, 128, 256, 512], | ||
"preferred": [] | ||
}, | ||
"subtitlesEnabled": true, | ||
"aliases": [] | ||
}, | ||
"size": 29281778284, | ||
"nextAirDate": "2019-06-05T09:00:00+02:00", | ||
"type": "Scripted", | ||
"imdbInfo": { | ||
"certificates": "", | ||
"lastUpdate": 737202, | ||
"plot": "An anthology series exploring a twisted, high-tech world where humanity's greatest innovations and darkest instincts collide.", | ||
"rating": "8.9", | ||
"title": "Black Mirror", | ||
"countries": "UNITED KINGDOM", | ||
"votes": 312785, | ||
"imdbId": "tt2085059", | ||
"runtimes": 60, | ||
"genres": "Drama|Sci-Fi|Thriller", | ||
"indexer": 1, | ||
"countryCodes": "gb", | ||
"year": 2011, | ||
"indexerId": 253463, | ||
"imdbInfoId": 28, | ||
"akas": "" | ||
}, | ||
"rating": { | ||
"imdb": { | ||
"votes": 312785, | ||
"rating": "8.9" | ||
} | ||
}, | ||
"showType": "series", | ||
"xemNumbering": [], | ||
"showQueueStatus": [{ | ||
"message": "This show is in the process of being downloaded - the info below is incomplete", | ||
"active": false, | ||
"action": "isBeingAdded" | ||
}, { | ||
"message": "The information on this page is in the process of being updated", | ||
"active": false, | ||
"action": "isBeingUpdated" | ||
}, { | ||
"message": "The episodes below are currently being refreshed from disk", | ||
"active": false, | ||
"action": "isBeingRefreshed" | ||
}, { | ||
"message": "Currently downloading subtitles for this show", | ||
"active": false, | ||
"action": "isBeingSubtitled" | ||
}, { | ||
"message": "This show is queued to be refreshed", | ||
"active": false, | ||
"action": "isInRefreshQueue" | ||
}, { | ||
"message": "This show is queued and awaiting an update", | ||
"active": false, | ||
"action": "isInUpdateQueue" | ||
}, { | ||
"message": "This show is queued and awaiting subtitles download", | ||
"active": false, | ||
"action": "isInSubtitleQueue" | ||
}], | ||
"runtime": 60, | ||
"airs": "Wednesday 3:00 AM", | ||
"cache": { | ||
"poster": "/medusa-data/cache/images/tvdb/253463.poster.jpg", | ||
"banner": "/medusa-data/cache/images/tvdb/253463.poster.jpg" | ||
}, | ||
"sceneAbsoluteNumbering": {}, | ||
"title": "Black Mirror", | ||
"genres": ["Science-Fiction", "Thriller", "Drama"], | ||
"indexer": "tvdb", | ||
"airsFormatValid": true, | ||
"year": { | ||
"start": 2011 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.