Skip to content
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

Basic Multi-User Setup #217

Merged
merged 5 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions app/Http/Controllers/MediaPlayerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ class MediaPlayerController extends Controller
// production
private $apiKey = '0000';
private $apiHost = 'http://jellyfin:8096';
private $enabled = false;

private $jellyfinLanguageCodes = [];

function __construct() {
$this->jellyfinLanguageCodes = config('linguacafe.languages.jellyfin_language_codes');

// retrieve api key and host from database
$setting = Setting::where('name', 'jellyfinEnabled')->firstOrNull();
$this->enabled = $setting->value;
jacovanc marked this conversation as resolved.
Show resolved Hide resolved
$setting = Setting::where('name', 'jellyfinApiKey')->first();
$this->apiKey = json_decode($setting->value);
$setting = Setting::where('name', 'jellyfinHost')->first();
Expand Down Expand Up @@ -56,7 +59,7 @@ private function makeJellyfinRequest ($method, $url) {
public function jellyfinRequest (Request $request) {
return $this->makeJellyfinRequest($request->method, $request->url);
}

/*
Returns a list of subtitles of the media currently being played
on the jellyfin server.
Expand Down Expand Up @@ -90,7 +93,7 @@ public function getJellyfinCurrentlyPlayedSubtitles () {
} else {
$session->movieName = $sessions[$sessionCounter]['NowPlayingItem']['Name'];
}

$session->runTimeTicks = $sessions[$sessionCounter]['NowPlayingItem']['RunTimeTicks'];
$session->nowPlayingItemId = $sessions[$sessionCounter]['NowPlayingItem']['Id'];
$session->sessionId = $sessions[$sessionCounter]['Id'];
Expand All @@ -109,14 +112,14 @@ public function getJellyfinCurrentlyPlayedSubtitles () {
}

$subtitleText = $this->makeJellyfinRequest('GET', '/Videos/' . $session->nowPlayingItemId . '/' . $session->mediaSourceId . '/Subtitles/ ' . $mediaSource['MediaStreams'][$subtitleCounter]['Index'] . '/0/Stream.js');

// add language for subtitles that Jellyfin did not recognise
if (!isset($mediaSource['MediaStreams'][$subtitleCounter]['Language'])) {
$mediaSource['MediaStreams'][$subtitleCounter]['Language'] = 'unrecognised by jellyfin: ' . $mediaSource['MediaStreams'][$subtitleCounter]['Title'];
}

// retrieve language. if not possible, use the jellyfin language code instead,
// so it can be viewed as an error message in the console and added to
// so it can be viewed as an error message in the console and added to
// jellyfinLanguageCodes.
if (array_key_exists($mediaSource['MediaStreams'][$subtitleCounter]['Language'], $this->jellyfinLanguageCodes)) {
$language = $this->jellyfinLanguageCodes[$mediaSource['MediaStreams'][$subtitleCounter]['Language']];
Expand All @@ -125,7 +128,7 @@ public function getJellyfinCurrentlyPlayedSubtitles () {
$language = $mediaSource['MediaStreams'][$subtitleCounter]['Language'];
$supportedLanguage = false;
}

$subtitle = new \stdClass();
$subtitle->language = $language;
$subtitle->supportedLanguage = $supportedLanguage;
Expand Down
8 changes: 4 additions & 4 deletions app/Http/Controllers/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function getGlobalSettingsByName(GetGlobalSettingsByNameRequest $request)
} catch (\Exception $e) {
abort(500, $e->getMessage());
}

return response()->json($settings, 200);
}

Expand All @@ -44,7 +44,7 @@ public function updateGlobalSettings(UpdateGlobalSettingsRequest $request) {
} catch (\Exception $e) {
abort(500, $e->getMessage());
}

return response()->json('Settings have been updated successfully.', 200);
}

Expand All @@ -58,7 +58,7 @@ public function getUserSettingsByName(GetUserSettingsByNameRequest $request) {
} catch (\Exception $e) {
abort(500, $e->getMessage());
}

return response()->json($settings, 200);
}

Expand All @@ -72,7 +72,7 @@ public function updateUserSettings(UpdateUserSettingsRequest $request) {
} catch (\Exception $e) {
abort(500, $e->getMessage());
}

return response()->json('Settings have been updated successfully.', 200);
}
}
8 changes: 8 additions & 0 deletions database/seeders/SettingsSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ public function run()
}

// jellyfin api settings
$setting = Setting::where('name', 'jellyfinEnabled')->first();
if (!$setting) {
DB::table('settings')->insert([
'name' => 'jellyfinEnabled',
'value' => json_encode(false)
]);
}

$setting = Setting::where('name', 'jellyfinApiKey')->first();
if (!$setting) {
DB::table('settings')->insert([
Expand Down
58 changes: 41 additions & 17 deletions resources/js/components/Admin/AdminApiSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
<label class="font-weight-bold"">
DeepL Cache
</label>

<div v-if="characterLimitLoading">
<v-skeleton-loader
id="skeleton-cached-translations"
class="regular-list-height d-block skeleton rounded-pill mt-1"
type="image"
></v-skeleton-loader>
</div>

<div v-if="!characterLimitLoading">
{{ formatNumber(cachedDeeplTranslations).replace('&nbsp;', '') }} cached translations.
</div>

<!-- DeepL API key input -->
<label class="font-weight-bold mt-4">DeepL API key</label>
<v-text-field
<v-text-field
v-model="settings.deeplApiKey"
class="mb-4"
hide-details
Expand All @@ -35,9 +35,9 @@
></v-text-field>

<!-- DeepL API usage -->
<label
<label
v-if="!['error', 'default'].includes(characterLimitStatus)"
class="font-weight-bold mt-4"
class="font-weight-bold mt-4"
>
DeepL character usage
</label>
Expand Down Expand Up @@ -75,9 +75,9 @@
<div class="font-weight-bold mt-2 mb-3" style="font-size: 36px;">
{{ formatNumber(characterUsed).replace('&nbsp;', '') }}
</div>

<div>Out of max.{{ formatNumber(characterLimit) }} characters</div>

<v-progress-linear
color="primary"
height="36"
Expand Down Expand Up @@ -109,7 +109,7 @@
<v-card outlined class="rounded-lg pa-4 pt-0">
<v-card-text id="jellyfin-card-text">
<label class="font-weight-bold">Anki-connect host</label>
<v-text-field
<v-text-field
v-model="settings.ankiConnectHost"
hide-details
filled
Expand All @@ -123,7 +123,7 @@
<!-- Auto add cards label -->
<label class="font-weight-bold mt-4 mb-0">
Auto add cards while reading

<!-- Auto add cards info box -->
<v-menu offset-y nudge-top="-12px">
<template v-slot:activator="{ on, attrs }">
Expand All @@ -148,7 +148,7 @@
<!-- Update existing cards label -->
<label class="font-weight-bold mt-4 mb-0">
Update existing cards

<!-- Update existing cards info box -->
<v-menu offset-y nudge-top="-12px">
<template v-slot:activator="{ on, attrs }">
Expand All @@ -159,7 +159,7 @@
</v-card>
</v-menu>
</label>

<!-- Update existing cards input -->
<v-switch
v-model="settings.ankiUpdateCards"
Expand All @@ -173,7 +173,7 @@
<!-- Show notifications label -->
<label class="font-weight-bold mt-4 mb-0">
Show notifications

<!-- Show notifications info box -->
<v-menu offset-y nudge-top="-12px">
<template v-slot:activator="{ on, attrs }">
Expand Down Expand Up @@ -201,8 +201,30 @@
<div class="subheader subheader-margin-top">Jellyfin</div>
<v-card outlined class="rounded-lg pa-4 pt-0">
<v-card-text id="jellyfin-card-text">
<label clas="font-weight-bold mt-4 mb-0">
Enable Jellyfin

<v-menu offset-y nudge-top="-12px">
<template v-slot:activator="{ on, attrs }">
<v-icon class="ml-1" v-bind="attrs" v-on="on">mdi-help-circle-outline</v-icon>
</template>
<v-card outlined class="rounded-lg pa-4" width="320px">
You may want to disable Jellyfin if hosting LinguaCafe for multiple users.
</v-card>
</v-menu>
</label>

<v-switch
v-model="settings.jellyfinEnabled"
class="mt-0"
color="primary"
hide-hints
dense
label="Enable Jellyfin"
></v-switch>

<label class="font-weight-bold">Jellyfin host address</label>
<v-text-field
<v-text-field
v-model="settings.jellyfinHost"
hide-details
filled
Expand All @@ -213,7 +235,7 @@
></v-text-field>

<label class="font-weight-bold mt-4">Jellyfin API key</label>
<v-text-field
<v-text-field
v-model="settings.jellyfinApiKey"
hide-details
filled
Expand All @@ -240,8 +262,8 @@
<!-- Save button -->
<div class="d-flex">
<v-spacer />
<v-btn
rounded
<v-btn
rounded
:class="{'my-2': saving || saveStatus == '' || saveStatus == 'success'}"
color="primary"
@click="saveSettings"
Expand Down Expand Up @@ -298,6 +320,7 @@
axios.post('/settings/global/get', {
'settingNames': [
'deeplApiKey',
'jellyfinEnabled',
'jellyfinHost',
'jellyfinApiKey',
'ankiConnectHost',
Expand All @@ -312,7 +335,7 @@
},
saveSettings() {
this.saving = true;

this.characterLimitLoading = true;
this.characterUsed = 0;
this.characterLimit = 0;
Expand All @@ -321,6 +344,7 @@
axios.post('/settings/global/update', {
'settings': {
'deeplApiKey': this.settings.deeplApiKey,
'jellyfinEnabled': this.settings.jellyfinEnabled,
'jellyfinHost': this.settings.jellyfinHost,
'jellyfinApiKey': this.settings.jellyfinApiKey,
'ankiConnectHost': this.settings.ankiConnectHost,
Expand Down