Skip to content

Commit

Permalink
Merge pull request #576 from arabcoders/dev
Browse files Browse the repository at this point in the history
Implement --dry-run for SyncCommand
  • Loading branch information
arabcoders authored Jan 18, 2025
2 parents fa8af72 + dd195b4 commit a9fa743
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 8 deletions.
80 changes: 78 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Building

on:
# Manual trigger remains available for any branch
workflow_dispatch:
inputs:
logLevel:
Expand All @@ -12,12 +13,16 @@ on:
- info
- warning
- debug

# Only run automatically on pushes to 'master'
push:
branches:
- '*'
- 'master'
paths-ignore:
- '**.md'
- '.github/**'

# Only run automatically for PRs targeting 'master'
pull_request:
branches:
- 'master'
Expand Down Expand Up @@ -66,12 +71,14 @@ jobs:
path: ${{ steps.composer-cache.outputs.COMPOSER_CACHE_DIR }}
key: "${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: ${{ matrix.php }}-composer-

- run: composer install --prefer-dist --no-interaction --no-progress
- run: composer run test

publish_docker_images:
needs: unit-tests
if: github.event_name != 'pull_request'
# This ensures it won't run on pull_request events
if: github.event_name == 'push'
runs-on: "ubuntu-latest"
permissions:
packages: write
Expand Down Expand Up @@ -144,6 +151,7 @@ jobs:
dockerhub-sync-readme:
needs: publish_docker_images
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: Sync README
uses: docker://lsiodev/readme-sync:latest
Expand All @@ -156,3 +164,71 @@ jobs:
with:
entrypoint: node
args: /opt/docker-readme-sync/sync

create_release:
needs: [ publish_docker_images ]
runs-on: ubuntu-latest
# Only run for push events on master
if: github.event_name == 'push'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # so we can git log the full history

- name: Get commits between old and new
id: commits
run: |
PREVIOUS_SHA="${{ github.event.before }}"
CURRENT_SHA="${{ github.event.after }}"
echo "Previous SHA: $PREVIOUS_SHA"
echo "Current SHA: $CURRENT_SHA"
# If "before" is empty or all zeros, log all commits
if [ -z "$PREVIOUS_SHA" ] || [ "$PREVIOUS_SHA" = "0000000000000000000000000000000000000000" ]; then
LOG=$(git log --pretty=format:"- %h %s by %an")
else
LOG=$(git log "$PREVIOUS_SHA".."$CURRENT_SHA" --pretty=format:"- %h %s by %an")
fi
echo "LOG<<EOF" >> "$GITHUB_ENV"
echo "$LOG" >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
- name: Create local tag matching Docker's raw pattern
id: createtag
run: |
# We'll replicate raw format: branch + base_ref + date + short sha
# If base_ref is empty (normal push to master, no PR?), it won't appear.
BRANCH_NAME="${{ github.ref_name }}"
BASE_REF="${{ github.base_ref }}"
CURRENT_SHA="${{ github.event.after }}"
DATE=$(date +%Y%m%d)
SHORT_SHA=$(echo "$CURRENT_SHA" | cut -c1-7)
TAG="${BRANCH_NAME}${BASE_REF}-${DATE}-${SHORT_SHA}"
echo "Using tag: $TAG"
git config user.name "github-actions"
git config user.email "[email protected]"
# Create a lightweight local tag
git tag "$TAG" "$CURRENT_SHA"
# Push the tag back to GitHub
git push origin "$TAG"
# Expose as an output
echo "TAG=$TAG" >> "$GITHUB_OUTPUT"
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.createtag.outputs.TAG }}
name: "Release ${{ steps.createtag.outputs.TAG }}"
body: ${{ env.LOG }}
draft: false
prerelease: false
generate_release_notes: true
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ load on the backends. By default, it will sync once every 3 hours. you can ofc c
> [!NOTE]
> Known issues:

* Currently, state:sync doesn't have a way of syncing plex users that has PIN enabled.
* Currently, `state:sync` doesn't have a way of syncing plex users that has PIN enabled.
* Majority of the command flags aren't working or not implemented yet.

> [!IMPORTANT]
Expand Down
17 changes: 17 additions & 0 deletions src/Backends/Jellyfin/Action/UpdateState.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Backends\Jellyfin\JellyfinClient;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Extends\Date;
use App\Libs\Options;
use App\Libs\QueueRequests;
use Psr\Log\LoggerInterface as iLogger;
use Symfony\Contracts\HttpClient\HttpClientInterface as iHttp;
Expand Down Expand Up @@ -68,6 +69,22 @@ public function __invoke(Context $context, array $entities, QueueRequests $queue
);
}

if (true === (bool)ag($context->options, Options::DRY_RUN, false)) {
$this->logger->notice(
"Would mark '{backend}' {item.type} '{item.title}' as '{item.play_state}'.",
[
'backend' => $context->backendName,
'item' => [
'id' => $itemId,
'title' => $entity->getName(),
'type' => $entity->type == iState::TYPE_EPISODE ? 'episode' : 'movie',
'play_state' => $entity->isWatched() ? 'played' : 'unplayed',
],
]
);
return new Response(status: true);
}

$queue->add(
$this->http->request(
method: $entity->isWatched() ? 'POST' : 'DELETE',
Expand Down
9 changes: 7 additions & 2 deletions src/Backends/Jellyfin/JellyfinGuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Libs\Config;
use App\Libs\Exceptions\Backends\InvalidArgumentException;
use App\Libs\Guid;
use App\Libs\Options;
use Psr\Log\LoggerInterface;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
Expand Down Expand Up @@ -242,14 +243,18 @@ protected function ListExternalIds(array $guids, array $context = [], bool $log
}

try {
if (true === isIgnoredId($this->context->backendName, $type, $key, $value, $id)) {
if (null === ($bName = ag($this->context->options, Options::ALT_NAME))) {
$bName = $this->context->backendName;
}

if (true === isIgnoredId($bName, $type, $key, $value, $id)) {
if (true === $log) {
$this->logger->debug(
"{class}: Ignoring '{client}: {backend}' external id '{source}' for {item.type} '{item.id}: {item.title}' as requested.",
[
'class' => afterLast(static::class, '\\'),
'client' => $this->context->clientName,
'backend' => $this->context->backendName,
'backend' => $bName,
'source' => $key . '://' . $value,
'guid' => [
'source' => $key,
Expand Down
17 changes: 17 additions & 0 deletions src/Backends/Plex/Action/UpdateState.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Backends\Common\Context;
use App\Backends\Common\Response;
use App\Libs\Entity\StateInterface as iState;
use App\Libs\Options;
use App\Libs\QueueRequests;
use Psr\Log\LoggerInterface as iLogger;
use Symfony\Contracts\HttpClient\HttpClientInterface as iHttp;
Expand Down Expand Up @@ -53,6 +54,22 @@ public function __invoke(Context $context, array $entities, QueueRequests $queue
continue;
}

if (true === (bool)ag($context->options, Options::DRY_RUN, false)) {
$this->logger->notice(
"Would mark '{backend}' {item.type} '{item.title}' as '{item.play_state}'.",
[
'backend' => $context->backendName,
'item' => [
'id' => $itemId,
'title' => $entity->getName(),
'type' => $entity->type == iState::TYPE_EPISODE ? 'episode' : 'movie',
'play_state' => $entity->isWatched() ? 'played' : 'unplayed',
],
]
);
return new Response(status: true);
}

$url = $context->backendUrl->withPath($entity->isWatched() ? '/:/scrobble' : '/:/unscrobble')
->withQuery(
http_build_query([
Expand Down
9 changes: 7 additions & 2 deletions src/Backends/Plex/PlexGuid.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Libs\Config;
use App\Libs\Exceptions\Backends\InvalidArgumentException;
use App\Libs\Guid;
use App\Libs\Options;
use Psr\Log\LoggerInterface as iLogger;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;
Expand Down Expand Up @@ -371,13 +372,17 @@ private function ListExternalIds(array $guids, array $context = [], bool $log =
continue;
}

if (true === isIgnoredId($this->context->backendName, $type, $key, $value, $id)) {
if (null === ($bName = ag($this->context->options, Options::ALT_NAME))) {
$bName = $this->context->backendName;
}

if (true === isIgnoredId($bName, $type, $key, $value, $id)) {
if (true === $log) {
$this->logger->debug(
"PlexGuid: Ignoring '{client}: {backend}' external id '{source}' for {item.type} '{item.id}: {item.title}' as requested.",
[
'client' => $this->context->clientName,
'backend' => $this->context->backendName,
'backend' => $bName,
'source' => $val,
'guid' => [
'source' => $key,
Expand Down
4 changes: 3 additions & 1 deletion src/Commands/State/SyncCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ protected function process(iInput $input, iOutput $output): int
$info['displayName'] = ag($user, 'name');
$info = ag_delete($info, 'options.' . Options::PLEX_USER_PIN);
$info = ag_delete($info, 'options.' . Options::ADMIN_TOKEN);
$info = ag_set($info, 'options.' . Options::ALT_NAME, ag($backend, 'name'));

unset($info['class']);
$user['backend'] = ag($backend, 'name');
Expand Down Expand Up @@ -312,7 +313,7 @@ protected function process(iInput $input, iOutput $output): int
'results' => arrayToString($this->usersList($users)),
]);

foreach ($users as $user) {
foreach (array_reverse($users) as $user) {
$this->queue->reset();
$this->mapper->reset();

Expand Down Expand Up @@ -378,6 +379,7 @@ protected function process(iInput $input, iOutput $output): int
'peak' => getPeakMemoryUsage(),
],
]);
exit(1);
}

return self::SUCCESS;
Expand Down
1 change: 1 addition & 0 deletions src/Libs/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ final class Options
public const string PLEX_USER_PIN = 'PLEX_USER_PIN';
public const string REQUEST_ID = 'REQUEST_ID';
public const string ONLY_LIBRARY_ID = 'ONLY_LIBRARY_ID';
public const string ALT_NAME = 'ALT_NAME';

private function __construct()
{
Expand Down

0 comments on commit a9fa743

Please sign in to comment.