add tvshow syntax to db
basic tvshow api request to show available tvshows limit randompage videos to 3 improve settings object to remove one useless copy
This commit is contained in:
parent
fdcecb0a75
commit
4539147208
@ -15,6 +15,7 @@ const (
|
||||
TagNode = iota
|
||||
SettingsNode = iota
|
||||
ActorNode = iota
|
||||
TVShowNode = iota
|
||||
)
|
||||
|
||||
type actionStruct struct {
|
||||
@ -36,10 +37,11 @@ func AddHandler(action string, apiNode int, n interface{}, h func() []byte) {
|
||||
}
|
||||
|
||||
func ServerInit() {
|
||||
http.Handle(APIPREFIX+"/video", oauth.ValidateToken(videoHandler))
|
||||
http.Handle(APIPREFIX+"/tags", oauth.ValidateToken(tagHandler))
|
||||
http.Handle(APIPREFIX+"/settings", oauth.ValidateToken(settingsHandler))
|
||||
http.Handle(APIPREFIX+"/actor", oauth.ValidateToken(actorHandler))
|
||||
http.Handle(APIPREFIX+"/video", oauth.ValidateToken(handlefunc, VideoNode))
|
||||
http.Handle(APIPREFIX+"/tags", oauth.ValidateToken(handlefunc, TagNode))
|
||||
http.Handle(APIPREFIX+"/settings", oauth.ValidateToken(handlefunc, SettingsNode))
|
||||
http.Handle(APIPREFIX+"/actor", oauth.ValidateToken(handlefunc, ActorNode))
|
||||
http.Handle(APIPREFIX+"/tvshow", oauth.ValidateToken(handlefunc, TVShowNode))
|
||||
|
||||
// initialize oauth service and add corresponding auth routes
|
||||
oauth.InitOAuth()
|
||||
@ -65,22 +67,6 @@ func handleAPICall(action string, requestBody string, apiNode int) []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func actorHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
handlefunc(rw, req, ActorNode)
|
||||
}
|
||||
|
||||
func videoHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
handlefunc(rw, req, VideoNode)
|
||||
}
|
||||
|
||||
func tagHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
handlefunc(rw, req, TagNode)
|
||||
}
|
||||
|
||||
func settingsHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
handlefunc(rw, req, SettingsNode)
|
||||
}
|
||||
|
||||
func handlefunc(rw http.ResponseWriter, req *http.Request, node int) {
|
||||
// only allow post requests
|
||||
if req.Method != "POST" {
|
||||
|
@ -61,6 +61,22 @@ func readActorsFromResultset(rows *sql.Rows) []types.Actor {
|
||||
return result
|
||||
}
|
||||
|
||||
// ID - Name : pay attention to the order!
|
||||
func readTVshowsFromResultset(rows *sql.Rows) []types.TVShow {
|
||||
result := []types.TVShow{}
|
||||
for rows.Next() {
|
||||
var vid types.TVShow
|
||||
err := rows.Scan(&vid.Id, &vid.Name)
|
||||
if err != nil {
|
||||
panic(err.Error()) // proper error handling instead of panic in your app
|
||||
}
|
||||
result = append(result, vid)
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func jsonify(v interface{}) []byte {
|
||||
// jsonify results
|
||||
str, err := json.Marshal(v)
|
||||
|
@ -29,17 +29,21 @@ func getSettingsFromDB() {
|
||||
Pasword bool
|
||||
MediacenterName string
|
||||
VideoPath string
|
||||
TVShowPath string
|
||||
}
|
||||
|
||||
regexMatchUrl := regexp.MustCompile("^http(|s):\\/\\/([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
|
||||
regexMatchUrl := regexp.MustCompile("^http(|s)://([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
|
||||
videoUrl := regexMatchUrl.FindString(sett.VideoPath)
|
||||
tvshowurl := regexMatchUrl.FindString(sett.TVShowPath)
|
||||
serverVideoPath := strings.TrimPrefix(sett.VideoPath, videoUrl)
|
||||
serverTVShowPath := strings.TrimPrefix(sett.TVShowPath, tvshowurl)
|
||||
|
||||
res := InitialDataTypeResponse{
|
||||
DarkMode: sett.DarkMode,
|
||||
Pasword: sett.Pasword != "-1",
|
||||
MediacenterName: sett.Mediacenter_name,
|
||||
MediacenterName: sett.MediacenterName,
|
||||
VideoPath: serverVideoPath,
|
||||
TVShowPath: serverTVShowPath,
|
||||
}
|
||||
|
||||
str, _ := json.Marshal(res)
|
||||
@ -74,6 +78,11 @@ func reIndexHandling() {
|
||||
return database.ManualSuccessResponse(nil)
|
||||
})
|
||||
|
||||
AddHandler("startTVShowReindex", SettingsNode, nil, func() []byte {
|
||||
videoparser.StartTVShowReindex()
|
||||
return database.ManualSuccessResponse(nil)
|
||||
})
|
||||
|
||||
AddHandler("cleanupGravity", SettingsNode, nil, func() []byte {
|
||||
videoparser.StartCleanup()
|
||||
return nil
|
||||
|
15
apiGo/api/TVShows.go
Normal file
15
apiGo/api/TVShows.go
Normal file
@ -0,0 +1,15 @@
|
||||
package api
|
||||
|
||||
import "openmediacenter/apiGo/database"
|
||||
|
||||
func AddTvshowHandlers() {
|
||||
var dT struct {
|
||||
TagId int
|
||||
Force bool
|
||||
}
|
||||
AddHandler("getTVShows", TVShowNode, &dT, func() []byte {
|
||||
query := "SELECT id, name FROM tvshow"
|
||||
rows := database.Query(query)
|
||||
return jsonify(readTVshowsFromResultset(rows))
|
||||
})
|
||||
}
|
@ -37,7 +37,7 @@ func deleteFromDB() {
|
||||
return database.ManualSuccessResponse(err)
|
||||
} else {
|
||||
// check with regex if its the key constraint error
|
||||
r, _ := regexp.Compile("^.*a foreign key constraint fails.*$")
|
||||
r := regexp.MustCompile("^.*a foreign key constraint fails.*$")
|
||||
if r.MatchString(err.Error()) {
|
||||
return []byte(`{"result":"not empty tag"}`)
|
||||
} else {
|
||||
|
@ -48,7 +48,7 @@ func InitOAuth() {
|
||||
})
|
||||
}
|
||||
|
||||
func ValidateToken(f http.HandlerFunc) http.HandlerFunc {
|
||||
func ValidateToken(f func(rw http.ResponseWriter, req *http.Request, node int), node int) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, err := srv.ValidationBearerToken(r)
|
||||
if err != nil {
|
||||
@ -56,6 +56,6 @@ func ValidateToken(f http.HandlerFunc) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
f.ServeHTTP(w, r)
|
||||
f(w, r, node)
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ type VideoUnloadedType struct {
|
||||
|
||||
type FullVideoType struct {
|
||||
MovieName string
|
||||
MovieId int
|
||||
MovieId uint32
|
||||
MovieUrl string
|
||||
Poster string
|
||||
Likes int
|
||||
Quality int
|
||||
Length int
|
||||
Likes uint64
|
||||
Quality uint16
|
||||
Length uint16
|
||||
Tags []Tag
|
||||
SuggestedTag []Tag
|
||||
Actors []Actor
|
||||
@ -20,22 +20,22 @@ type FullVideoType struct {
|
||||
|
||||
type Tag struct {
|
||||
TagName string
|
||||
TagId int
|
||||
TagId uint32
|
||||
}
|
||||
|
||||
type Actor struct {
|
||||
ActorId int
|
||||
ActorId uint32
|
||||
Name string
|
||||
Thumbnail string
|
||||
}
|
||||
|
||||
type StartData struct {
|
||||
VideoNr int
|
||||
FullHdNr int
|
||||
HDNr int
|
||||
SDNr int
|
||||
DifferentTags int
|
||||
Tagged int
|
||||
VideoNr uint32
|
||||
FullHdNr uint32
|
||||
HDNr uint32
|
||||
SDNr uint32
|
||||
DifferentTags uint32
|
||||
Tagged uint32
|
||||
}
|
||||
|
||||
type SettingsType struct {
|
||||
@ -47,10 +47,15 @@ type SettingsType struct {
|
||||
TMDBGrabbing bool
|
||||
DarkMode bool
|
||||
|
||||
VideoNr int
|
||||
VideoNr uint32
|
||||
DBSize float32
|
||||
DifferentTags int
|
||||
TagsAdded int
|
||||
DifferentTags uint32
|
||||
TagsAdded uint32
|
||||
|
||||
PathPrefix string
|
||||
}
|
||||
|
||||
type TVShow struct {
|
||||
Id uint32
|
||||
Name string
|
||||
}
|
||||
|
@ -15,35 +15,24 @@ func GetPassword() *string {
|
||||
}
|
||||
|
||||
type SettingsType struct {
|
||||
DarkMode bool
|
||||
Pasword string
|
||||
Mediacenter_name string
|
||||
VideoPath string
|
||||
DarkMode bool
|
||||
Pasword string
|
||||
MediacenterName string
|
||||
VideoPath string
|
||||
TVShowPath string
|
||||
}
|
||||
|
||||
func LoadSettings() *SettingsType {
|
||||
query := "SELECT DarkMode, password, mediacenter_name, video_path from settings"
|
||||
query := "SELECT DarkMode, password, mediacenter_name, video_path, episode_path from settings"
|
||||
|
||||
type RawSettingsType struct {
|
||||
DarkMode int
|
||||
Pasword string
|
||||
Mediacenter_name string
|
||||
VideoPath string
|
||||
}
|
||||
result := SettingsType{}
|
||||
var darkmode uint8
|
||||
|
||||
result := RawSettingsType{}
|
||||
|
||||
err := database.QueryRow(query).Scan(&result.DarkMode, &result.Pasword, &result.Mediacenter_name, &result.VideoPath)
|
||||
err := database.QueryRow(query).Scan(&darkmode, &result.Pasword, &result.MediacenterName, &result.VideoPath, &result.TVShowPath)
|
||||
if err != nil {
|
||||
fmt.Println("error while parsing db data: " + err.Error())
|
||||
}
|
||||
|
||||
res := SettingsType{
|
||||
DarkMode: result.DarkMode != 0,
|
||||
Pasword: result.Pasword,
|
||||
Mediacenter_name: result.Mediacenter_name,
|
||||
VideoPath: result.VideoPath,
|
||||
}
|
||||
|
||||
return &res
|
||||
result.DarkMode = darkmode != 0
|
||||
return &result
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ func main() {
|
||||
api.AddSettingsHandlers()
|
||||
api.AddTagHandlers()
|
||||
api.AddActorsHandlers()
|
||||
api.AddTvshowHandlers()
|
||||
|
||||
// add the static files
|
||||
static.ServeStaticFiles()
|
||||
|
@ -54,6 +54,11 @@ func StartReindex() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// StartTVShowReindex reindex dir walks for TVShow reindex
|
||||
func StartTVShowReindex() {
|
||||
// todo implement walking through dirs and reindex!
|
||||
}
|
||||
|
||||
func GetStatusMessage() *StatusMessage {
|
||||
msg := StatusMessage{
|
||||
Messages: messageBuffer,
|
||||
|
20
database.sql
20
database.sql
@ -24,6 +24,26 @@ create table if not exists tags
|
||||
tag_name varchar(50) null
|
||||
);
|
||||
|
||||
create table if not exists tvshow
|
||||
(
|
||||
name varchar(100) null,
|
||||
thumbnail mediumblob null,
|
||||
id int auto_increment
|
||||
primary key
|
||||
);
|
||||
|
||||
create table if not exists tvshow_episodes
|
||||
(
|
||||
id int auto_increment
|
||||
primary key,
|
||||
name varchar(100) null,
|
||||
season int null,
|
||||
poster mediumblob null,
|
||||
tvshow_id int null,
|
||||
constraint tvshow_episodes_tvshow_id_fk
|
||||
foreign key (tvshow_id) references tvshow (id)
|
||||
);
|
||||
|
||||
create table if not exists videos
|
||||
(
|
||||
movie_id int auto_increment
|
||||
|
@ -79,7 +79,7 @@ class App extends React.Component<{}, state> {
|
||||
// set theme
|
||||
GlobalInfos.enableDarkTheme(result.DarkMode);
|
||||
|
||||
GlobalInfos.setVideoPath(result.VideoPath);
|
||||
GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
|
||||
|
||||
this.setState({
|
||||
mediacentername: result.MediacenterName
|
||||
|
@ -23,6 +23,8 @@ interface GetRandomMoviesType {
|
||||
* Randompage shuffles random viedeopreviews and provides a shuffle btn
|
||||
*/
|
||||
class RandomPage extends React.Component<{}, state> {
|
||||
readonly LoadNR = 3;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
@ -37,7 +39,7 @@ class RandomPage extends React.Component<{}, state> {
|
||||
componentDidMount(): void {
|
||||
addKeyHandler(this.keypress);
|
||||
|
||||
this.loadShuffledvideos(4);
|
||||
this.loadShuffledvideos(this.LoadNR);
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
@ -75,7 +77,7 @@ class RandomPage extends React.Component<{}, state> {
|
||||
* click handler for shuffle btn
|
||||
*/
|
||||
shuffleclick(): void {
|
||||
this.loadShuffledvideos(4);
|
||||
this.loadShuffledvideos(this.LoadNR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,38 @@
|
||||
import React from 'react';
|
||||
import Preview from '../../elements/Preview/Preview';
|
||||
import {APINode, callAPI} from '../../utils/Api';
|
||||
import {TVShow} from '../../types/ApiTypes';
|
||||
import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer';
|
||||
|
||||
interface State {
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
interface Props {}
|
||||
|
||||
class TVShowPage extends React.Component<Props, State> {
|
||||
state = {
|
||||
loading: true
|
||||
};
|
||||
|
||||
data: TVShow.TVshowType[] = [];
|
||||
|
||||
componentDidMount(): void {
|
||||
callAPI(APINode.TVShow, {action: 'getTVShows'}, (resp: TVShow.TVshowType[]) => {
|
||||
this.data = resp;
|
||||
this.setState({loading: false});
|
||||
});
|
||||
}
|
||||
|
||||
class TVShowPage extends React.Component {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<Preview name='myTestItem' picLoader={(callback): void => callback('')} />
|
||||
<DynamicContentContainer
|
||||
renderElement={(elem): JSX.Element => (
|
||||
<Preview name={elem.Name} picLoader={(callback): void => callback('')} linkPath={'/tvshows/' + elem.Id} />
|
||||
)}
|
||||
data={this.state.loading ? [] : this.data}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ export namespace SettingsTypes {
|
||||
Password: boolean;
|
||||
MediacenterName: string;
|
||||
VideoPath: string;
|
||||
TVShowPath: string;
|
||||
}
|
||||
|
||||
export interface loadGeneralSettingsType {
|
||||
@ -58,6 +59,16 @@ export namespace SettingsTypes {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TVShow {
|
||||
/**
|
||||
* result of actor fetch
|
||||
*/
|
||||
export interface TVshowType {
|
||||
Id: number;
|
||||
Name: string;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ActorTypes {
|
||||
/**
|
||||
* result of actor fetch
|
||||
|
@ -279,5 +279,6 @@ export enum APINode {
|
||||
Settings = 'settings',
|
||||
Tags = 'tags',
|
||||
Actor = 'actor',
|
||||
Video = 'video'
|
||||
Video = 'video',
|
||||
TVShow = 'tvshow'
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import lighttheme from '../AppLightTheme.module.css';
|
||||
class StaticInfos {
|
||||
private darktheme: boolean = true;
|
||||
private videopath: string = '';
|
||||
private tvshowpath: string = '';
|
||||
|
||||
/**
|
||||
* check if the current theme is the dark theme
|
||||
@ -47,8 +48,9 @@ class StaticInfos {
|
||||
* set the current videopath
|
||||
* @param vidpath videopath with beginning and ending slash
|
||||
*/
|
||||
setVideoPath(vidpath: string): void {
|
||||
setVideoPaths(vidpath: string, tvshowpath: string): void {
|
||||
this.videopath = vidpath;
|
||||
this.tvshowpath = tvshowpath;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,6 +60,13 @@ class StaticInfos {
|
||||
return this.videopath;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the current tvshow path
|
||||
*/
|
||||
getTVShowPath(): string {
|
||||
return this.tvshowpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* load the Password page manually
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user