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

Add Plex Watchlist import #410

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions bin/console.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
$application->add($container->get(Movary\Command\UserRatingExport::class));
$application->add($container->get(Movary\Command\UserUpdate::class));
$application->add($container->get(Movary\Command\UserList::class));
$application->add($container->get(Movary\Command\PlexWatchlistImport::class));
$application->add($container->get(Movary\Command\ProcessJobs::class));
$application->add($container->get(Movary\Command\ImdbSync::class));

Expand Down
24 changes: 24 additions & 0 deletions db/migrations/mysql/20230624094852_AddPlexTokenToUserTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class AddPlexTokenToUserTable extends AbstractMigration
{
public function down() : void
{
$this->execute(
<<<SQL
ALTER TABLE user DROP COLUMN plex_token;
SQL,
);
}

public function up() : void
{
$this->execute(
<<<SQL
ALTER TABLE user ADD COLUMN plex_token VARCHAR(255) DEFAULT NULL AFTER plex_scrobble_ratings;
SQL,
);
}
}
155 changes: 155 additions & 0 deletions db/migrations/sqlite/20230624094852_AddPlexTokenToUserTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class AddPlexTokenToUserTable extends AbstractMigration
{
public function down() : void
{
$this->execute(
<<<SQL
CREATE TABLE `tmp_user` (
`id` INTEGER,
`email` TEXT NOT NULL,
`name` TEXT NOT NULL,
`password` TEXT NOT NULL ,
`is_admin` TINYINT(1) DEFAULT 0,
`dashboard_visible_rows` TEXT,
`dashboard_extended_rows` TEXT,
`dashboard_order_rows` TEXT,
`privacy_level` INTEGER DEFAULT 1,
`date_format_id` INTEGER DEFAULT 0,
`trakt_user_name` TEXT,
`plex_webhook_uuid` TEXT,
`jellyfin_webhook_uuid` TEXT,
`emby_webhook_uuid` TEXT,
`trakt_client_id` TEXT,
`jellyfin_scrobble_views` INTEGER DEFAULT 1,
`emby_scrobble_views` INTEGER DEFAULT 1,
`plex_scrobble_views` INTEGER DEFAULT 1,
`plex_scrobble_ratings` INTEGER DEFAULT 0,
`watchlist_automatic_removal_enabled` INTEGER DEFAULT 0,
`core_account_changes_disabled` INTEGER DEFAULT 0,
`created_at` TEXT NOT NULL,
PRIMARY KEY (`id`),
UNIQUE (`email`),
UNIQUE (`name`)
)
SQL,
);
$this->execute(
'INSERT INTO `tmp_user` (
`id`,
`email`,
`name`,
`password`,
`is_admin`,
`dashboard_visible_rows`,
`dashboard_extended_rows`,
`dashboard_order_rows`,
`privacy_level`,
`date_format_id`,
`trakt_user_name`,
`plex_webhook_uuid`,
`jellyfin_webhook_uuid`,
`emby_webhook_uuid`,
`trakt_client_id`,
`jellyfin_scrobble_views`,
`emby_scrobble_views`,
`plex_scrobble_views`,
`plex_scrobble_ratings`,
`watchlist_automatic_removal_enabled`,
`core_account_changes_disabled`,
`created_at`
) SELECT
`id`,
`email`,
`name`,
`password`,
`is_admin`,
`dashboard_visible_rows`,
`dashboard_extended_rows`,
`dashboard_order_rows`,
`privacy_level`,
`date_format_id`,
`trakt_user_name`,
`plex_webhook_uuid`,
`jellyfin_webhook_uuid`,
`emby_webhook_uuid`,
`trakt_client_id`,
`jellyfin_scrobble_views`,
`emby_scrobble_views`,
`plex_scrobble_views`,
`plex_scrobble_ratings`,
`watchlist_automatic_removal_enabled`,
`core_account_changes_disabled`,
`created_at` FROM user',
);
$this->execute('DROP TABLE `user`');
$this->execute('ALTER TABLE `tmp_user` RENAME TO `user`');
}

public function up() : void
{
$this->execute(
<<<SQL
CREATE TABLE `tmp_user` (
`id` INTEGER,
`email` TEXT NOT NULL,
`name` TEXT NOT NULL,
`password` TEXT NOT NULL ,
`is_admin` TINYINT(1) DEFAULT 0,
`dashboard_visible_rows` TEXT,
`dashboard_extended_rows` TEXT,
`dashboard_order_rows` TEXT,
`privacy_level` INTEGER DEFAULT 1,
`date_format_id` INTEGER DEFAULT 0,
`trakt_user_name` TEXT,
`plex_webhook_uuid` TEXT,
`jellyfin_webhook_uuid` TEXT,
`emby_webhook_uuid` TEXT,
`trakt_client_id` TEXT,
`jellyfin_scrobble_views` INTEGER DEFAULT 1,
`emby_scrobble_views` INTEGER DEFAULT 1,
`plex_scrobble_views` INTEGER DEFAULT 1,
`plex_scrobble_ratings` INTEGER DEFAULT 0,
`plex_token` TEXT,
`watchlist_automatic_removal_enabled` INTEGER DEFAULT 0,
`core_account_changes_disabled` INTEGER DEFAULT 0,
`created_at` TEXT NOT NULL,
PRIMARY KEY (`id`),
UNIQUE (`email`),
UNIQUE (`name`)
)
SQL,
);
$this->execute(
'INSERT INTO `tmp_user` (
`id`,
`email`,
`name`,
`password`,
`is_admin`,
`dashboard_visible_rows`,
`dashboard_extended_rows`,
`dashboard_order_rows`,
`privacy_level`,
`date_format_id`,
`trakt_user_name`,
`plex_webhook_uuid`,
`jellyfin_webhook_uuid`,
`emby_webhook_uuid`,
`trakt_client_id`,
`jellyfin_scrobble_views`,
`emby_scrobble_views`,
`plex_scrobble_views`,
`plex_scrobble_ratings`,
`watchlist_automatic_removal_enabled`,
`core_account_changes_disabled`,
`created_at`
) SELECT * FROM user',
);
$this->execute('DROP TABLE `user`');
$this->execute('ALTER TABLE `tmp_user` RENAME TO `user`');
}
}
3 changes: 3 additions & 0 deletions public/js/job-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ function setJobModalTitle(jobType) {
case 'letterboxd_import_history':
title = 'History imports';
break;
case 'plex_import_watchlist':
title = 'Watchlist imports';
break;
default:
throw new Error('Not supported job type: ' + jobType);
}
Expand Down
45 changes: 45 additions & 0 deletions public/js/settings-integration-plex.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
const plexTokenInput = document.getElementById('plexTokenInput');
toggleWatchlistImportButtonState()
plexTokenInput.addEventListener('input', toggleWatchlistImportButtonState);

function toggleWatchlistImportButtonState() {
document.getElementById('plexWatchlistImportButton').disabled = plexTokenInput.value === ''
}

async function importPlexWatchlist() {
const response = await fetch('/jobs/schedule/plex-watchlist-sync', {'method': 'get'})

if (!response.ok) {
addAlert('alertPlexWatchlistImportDiv', 'Watchlist import could not be scheduled', 'danger')

throw new Error(`HTTP error! status: ${response.status}`)
}

addAlert('alertPlexWatchlistImportDiv', 'Watchlist import scheduled', 'success')
}

function regeneratePlexWebhook() {
if (confirm('Do you really want to regenerate the webhook url?') === false) {
return
Expand Down Expand Up @@ -91,3 +111,28 @@ async function updateScrobbleOptions() {
addAlert('alertWebhookOptionsDiv', 'Could not update scrobble options', 'danger')
});
}

async function updatePlexToken() {
removeAlert('alertPlexWatchlistImportDiv')

await fetch('/settings/plex-token', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
'plexToken': plexTokenInput.value,
})
}).then(response => {
if (!response.ok) {
addAlert('alertPlexWatchlistImportDiv', 'Could not update plex token', 'danger')

return
}

addAlert('alertPlexWatchlistImportDiv', 'Plex token was updated', 'success')
}).catch(function (error) {
console.log(error)
addAlert('alertPlexWatchlistImportDiv', 'Could not update plex token', 'danger')
});
}
12 changes: 11 additions & 1 deletion settings/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
'/jobs/schedule/letterboxd-ratings-sync',
[\Movary\HttpController\JobController::class, 'scheduleLetterboxdRatingsImport'],
);
$routeCollector->addRoute(
'GET',
'/jobs/schedule/plex-watchlist-sync',
[\Movary\HttpController\JobController::class, 'schedulePlexWatchlistImport'],
);

############
# Settings #
Expand Down Expand Up @@ -226,7 +231,12 @@
$routeCollector->addRoute(
'POST',
'/settings/plex',
[\Movary\HttpController\SettingsController::class, 'updatePlex'],
[\Movary\HttpController\SettingsController::class, 'updatePlexScrobbleOptions'],
);
$routeCollector->addRoute(
'POST',
'/settings/plex-token',
[\Movary\HttpController\SettingsController::class, 'updatePlexToken'],
);
$routeCollector->addRoute(
'PUT',
Expand Down
11 changes: 11 additions & 0 deletions src/Api/Plex/Exception/PlexAuthorizationError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php declare(strict_types=1);

namespace Movary\Api\Plex\Exception;

class PlexAuthorizationError extends \RuntimeException
{
public static function create() : self
{
return new self('Plex token is probably not set or invalid.');
}
}
Loading