mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
#680 - added auto organize page
This commit is contained in:
parent
fda9b3d93d
commit
9ab4adcd33
10 changed files with 481 additions and 159 deletions
31
ApiClient.js
31
ApiClient.js
|
@ -666,6 +666,37 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getFileOrganizationResults = function (options) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganization", options || {});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.deleteOriginalFileFromOrganizationResult = function (id) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganizations/" + id + "/File");
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.performOrganization = function (id) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Library/FileOrganizations/" + id + "/Organize");
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.getLiveTvSeriesTimer = function (id) {
|
self.getLiveTvSeriesTimer = function (id) {
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
|
|
@ -76,3 +76,10 @@
|
||||||
background-color: #eeeeee; /* non-RGBA fallback */
|
background-color: #eeeeee; /* non-RGBA fallback */
|
||||||
background-color: rgba(0,0,0,.1);
|
background-color: rgba(0,0,0,.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.stripedTable tbody tr:nth-child(odd) td,
|
||||||
|
.stripedTable tbody tr:nth-child(odd) th {
|
||||||
|
background-color: #eeeeee; /* non-RGBA fallback */
|
||||||
|
background-color: rgba(0,0,0,.04);
|
||||||
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.labelPageSize {
|
.labelPageSize {
|
||||||
margin-left: 1em;
|
margin-left: 1em!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -846,3 +846,12 @@ progress {
|
||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.organizerButtonCell {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.organizerButton {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
|
@ -1,153 +1,145 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Media Library</title>
|
<title>Auto-Organize</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="libraryFileOrganizerPage" data-role="page" class="page type-interior mediaLibraryPage">
|
<div id="libraryFileOrganizerPage" data-role="page" class="page type-interior organizePage">
|
||||||
|
|
||||||
<div data-role="content">
|
<div data-role="content">
|
||||||
<div class="content-primary">
|
<div class="content-primary">
|
||||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||||
<a href="library.html" data-role="button">Media Folders</a>
|
<a href="libraryfileorganizerlog.html" data-role="button">Activity Log</a>
|
||||||
<a href="librarysettings.html" data-role="button">Settings</a>
|
<a href="#" data-role="button" class="ui-btn-active">TV Settings</a>
|
||||||
<a href="#" data-role="button" class="ui-btn-active">File Organizer</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="libraryFileOrganizerForm">
|
<form class="libraryFileOrganizerForm">
|
||||||
|
|
||||||
<p>File organizing allows the server to monitor your download folders for new files and move them to your media directories.</p>
|
<p>The file organizer monitors your download folders for new files and moves them to your media directories.</p>
|
||||||
|
|
||||||
<div data-role="controlgroup" data-type="horizontal" data-mini="true" class="sortingTabs" style="display: none;">
|
|
||||||
<input type="radio" name="radioSortingSettingsTab" class="radioSortingSettingsTab" id="radioTvSortingSettings" value="tv" checked="checked">
|
|
||||||
<label for="radioTvSortingSettings">TV Sorting</label>
|
|
||||||
<input type="radio" name="radioSortingSettingsTab" class="radioSortingSettingsTab" id="radioMovieSortingSettings" value="movies">
|
|
||||||
<label for="radioMovieSortingSettings">Movie Sorting</label>
|
|
||||||
</div>
|
|
||||||
<div class="tvTab tab">
|
|
||||||
<p>TV file organizing will only add episodes to existing series. It will not create new series folders.</p>
|
|
||||||
<ul data-role="listview" class="ulForm" style="margin-bottom: 0!important;">
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="chkEnableTvSorting" name="chkEnableTvSorting" />
|
|
||||||
<label for="chkEnableTvSorting">Enable new episode organization</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label for="txtWatchFolder">Watch folder: </label>
|
|
||||||
<div style="display: inline-block; width: 92%;">
|
|
||||||
<input type="text" id="txtWatchFolder" name="txtWatchFolder" />
|
|
||||||
</div>
|
|
||||||
<button id="btnSelectWatchFolder" type="button" data-icon="search" data-iconpos="notext" data-inline="true">Select Directory</button>
|
|
||||||
<div class="fieldDescription">
|
|
||||||
The server will poll this folder during the "Organize new media files" <a href="scheduledtasks.html">scheduled task</a>.
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label for="txtMinFileSize">Minimum file size (MB): </label>
|
|
||||||
<input type="number" id="txtMinFileSize" name="txtMinFileSize" pattern="[0-9]*" required="required" min="0" data-mini="true" />
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label for="txtSeasonFolderPattern">Season folder pattern: </label>
|
|
||||||
<input type="text" id="txtSeasonFolderPattern" name="txtSeasonFolderPattern" required="required" data-mini="true" />
|
|
||||||
<div class="fieldDescription seasonFolderFieldDescription"></div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label for="txtSeasonZeroName">Season zero folder name: </label>
|
|
||||||
<input type="text" id="txtSeasonZeroName" name="txtSeasonZeroName" required="required" data-mini="true" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div data-role="collapsible">
|
|
||||||
<h3>Episode file pattern</h3>
|
|
||||||
<div>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
<label for="txtEpisodePattern">Episode pattern: </label>
|
|
||||||
<input type="text" id="txtEpisodePattern" name="txtEpisodePattern" required="required" data-mini="true" />
|
|
||||||
<div class="fieldDescription episodePatternDescription"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>Supported Patterns</p>
|
|
||||||
|
|
||||||
<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Term</th>
|
|
||||||
<th>Pattern</th>
|
|
||||||
<th>Result</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<th>Series Name</th>
|
|
||||||
<td>%sn</td>
|
|
||||||
<td>Series Name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Series Name</th>
|
|
||||||
<td>%s.n</td>
|
|
||||||
<td>Series.Name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Series Name</th>
|
|
||||||
<td>%s_n</td>
|
|
||||||
<td>Series_Name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Season Number</th>
|
|
||||||
<td>%s</td>
|
|
||||||
<td>1</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Season Number</th>
|
|
||||||
<td>%0s</td>
|
|
||||||
<td>01</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Episode Number</th>
|
|
||||||
<td>%e</td>
|
|
||||||
<td>4</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Episode Number</th>
|
|
||||||
<td>%0e</td>
|
|
||||||
<td>04</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Episode Name</th>
|
|
||||||
<td>%en</td>
|
|
||||||
<td>Episode Name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Episode Name</th>
|
|
||||||
<td>%e.n</td>
|
|
||||||
<td>Episode.Name</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Episode Name</th>
|
|
||||||
<td>%e_n</td>
|
|
||||||
<td>Episode_Name</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
<p>TV file organizing will only add episodes to existing series. It will not create new series folders.</p>
|
||||||
|
<ul data-role="listview" class="ulForm" style="margin-bottom: 0!important;">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="chkEnableTvSorting" name="chkEnableTvSorting" />
|
||||||
|
<label for="chkEnableTvSorting">Enable new episode organization</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="txtWatchFolder">Watch folder: </label>
|
||||||
|
<div style="display: inline-block; width: 92%;">
|
||||||
|
<input type="text" id="txtWatchFolder" name="txtWatchFolder" />
|
||||||
</div>
|
</div>
|
||||||
|
<button id="btnSelectWatchFolder" type="button" data-icon="search" data-iconpos="notext" data-inline="true">Select Directory</button>
|
||||||
|
<div class="fieldDescription">
|
||||||
|
The server will poll this folder during the "Organize new media files" <a href="scheduledtasks.html">scheduled task</a>.
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="txtMinFileSize">Minimum file size (MB): </label>
|
||||||
|
<input type="number" id="txtMinFileSize" name="txtMinFileSize" pattern="[0-9]*" required="required" min="0" data-mini="true" />
|
||||||
|
<div class="fieldDescription">Files under this size will be ignored.</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="txtSeasonFolderPattern">Season folder pattern: </label>
|
||||||
|
<input type="text" id="txtSeasonFolderPattern" name="txtSeasonFolderPattern" required="required" data-mini="true" />
|
||||||
|
<div class="fieldDescription seasonFolderFieldDescription"></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label for="txtSeasonZeroName">Season zero folder name: </label>
|
||||||
|
<input type="text" id="txtSeasonZeroName" name="txtSeasonZeroName" required="required" data-mini="true" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div data-role="collapsible">
|
||||||
|
<h3>Episode file pattern</h3>
|
||||||
|
<div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<label for="txtEpisodePattern">Episode pattern: </label>
|
||||||
|
<input type="text" id="txtEpisodePattern" name="txtEpisodePattern" required="required" data-mini="true" />
|
||||||
|
<div class="fieldDescription episodePatternDescription"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Supported Patterns</p>
|
||||||
|
|
||||||
|
<table data-role="table" id="movie-table" data-mode="reflow" class="ui-responsive">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Term</th>
|
||||||
|
<th>Pattern</th>
|
||||||
|
<th>Result</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Series Name</td>
|
||||||
|
<td>%sn</td>
|
||||||
|
<td>Series Name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Series Name</td>
|
||||||
|
<td>%s.n</td>
|
||||||
|
<td>Series.Name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Series Name</td>
|
||||||
|
<td>%s_n</td>
|
||||||
|
<td>Series_Name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Season Number</td>
|
||||||
|
<td>%s</td>
|
||||||
|
<td>1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Season Number</td>
|
||||||
|
<td>%0s</td>
|
||||||
|
<td>01</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Episode Number</td>
|
||||||
|
<td>%e</td>
|
||||||
|
<td>4</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Episode Number</td>
|
||||||
|
<td>%0e</td>
|
||||||
|
<td>04</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Episode Name</td>
|
||||||
|
<td>%en</td>
|
||||||
|
<td>Episode Name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Episode Name</td>
|
||||||
|
<td>%e.n</td>
|
||||||
|
<td>Episode.Name</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Episode Name</td>
|
||||||
|
<td>%e_n</td>
|
||||||
|
<td>Episode_Name</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<br />
|
|
||||||
<ul data-role="listview" class="ulForm">
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="chkOverwriteExistingEpisodes" name="chkOverwriteExistingEpisodes" />
|
|
||||||
<label for="chkOverwriteExistingEpisodes">Overwrite existing episodes</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="chkDeleteEmptyFolders" name="chkDeleteEmptyFolders" />
|
|
||||||
<label for="chkDeleteEmptyFolders">Delete empty folders after organizing</label>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<input type="checkbox" id="chkEnableTrialMode" name="chkEnableTrialMode" />
|
|
||||||
<label for="chkEnableTrialMode">Enable trial mode</label>
|
|
||||||
<div class="fieldDescription">With trial mode enabled, file organizations will be logged but not executed.</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<ul data-role="listview" class="ulForm">
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="chkOverwriteExistingEpisodes" name="chkOverwriteExistingEpisodes" />
|
||||||
|
<label for="chkOverwriteExistingEpisodes">Overwrite existing episodes</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="chkDeleteEmptyFolders" name="chkDeleteEmptyFolders" />
|
||||||
|
<label for="chkDeleteEmptyFolders">Delete empty folders after organizing</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" id="chkEnableTrialMode" name="chkEnableTrialMode" />
|
||||||
|
<label for="chkEnableTrialMode">Enable trial mode</label>
|
||||||
|
<div class="fieldDescription">With trial mode enabled, file organizations will be logged but not executed.</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<ul data-role="listview" class="ulForm">
|
<ul data-role="listview" class="ulForm">
|
||||||
<li>
|
<li>
|
||||||
|
|
41
dashboard-ui/libraryfileorganizerlog.html
Normal file
41
dashboard-ui/libraryfileorganizerlog.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Auto-Organize</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="libraryFileOrganizerLogPage" data-role="page" class="page type-interior adminPage organizePage">
|
||||||
|
|
||||||
|
<div data-role="content">
|
||||||
|
<div class="content-primary">
|
||||||
|
|
||||||
|
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||||
|
<a href="#" data-role="button" class="ui-btn-active">Activity Log</a>
|
||||||
|
<a href="libraryfileorganizer.html" data-role="button">TV Settings</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin: -15px 0 1em;text-align:left;">
|
||||||
|
<div class="listTopPaging">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table id="movie-table" data-role="table" data-mode="reflow" class="tblOrganizationResults stripedTable ui-responsive table-stroke">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-priority="2">Date</th>
|
||||||
|
<th data-priority="1">Source</th>
|
||||||
|
<th data-priority="3">Destination</th>
|
||||||
|
<th data-priority="1">Result</th>
|
||||||
|
<th data-priority="1"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="resultBody">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
<div class="listBottomPaging">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1426,7 +1426,7 @@
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
||||||
getPagingHtml: function (query, totalRecordCount, updatePageSizeSetting, pageSizes) {
|
getPagingHtml: function (query, totalRecordCount, updatePageSizeSetting, pageSizes, showLimit) {
|
||||||
|
|
||||||
if (query.Limit && updatePageSizeSetting !== false) {
|
if (query.Limit && updatePageSizeSetting !== false) {
|
||||||
localStorage.setItem('pagesize', query.Limit);
|
localStorage.setItem('pagesize', query.Limit);
|
||||||
|
@ -1451,7 +1451,7 @@
|
||||||
var recordsEnd = Math.min(query.StartIndex + query.Limit, totalRecordCount);
|
var recordsEnd = Math.min(query.StartIndex + query.Limit, totalRecordCount);
|
||||||
|
|
||||||
// 20 is the minimum page size
|
// 20 is the minimum page size
|
||||||
var showControls = totalRecordCount > 20;
|
var showControls = totalRecordCount > 20 || query.Limit < totalRecordCount;
|
||||||
|
|
||||||
html += '<div class="listPaging">';
|
html += '<div class="listPaging">';
|
||||||
|
|
||||||
|
@ -1461,39 +1461,44 @@
|
||||||
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
|
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
|
||||||
|
|
||||||
if (showControls) {
|
if (showControls) {
|
||||||
html += ', page ' + dropdownHtml + ' of ' + pageCount;
|
//html += ', page ' + dropdownHtml + ' of ' + pageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '</span>';
|
html += '</span>';
|
||||||
|
|
||||||
if (showControls) {
|
if (showControls) {
|
||||||
|
|
||||||
|
html += '<div data-role="controlgroup" data-type="horizontal" style="display:inline-block;">';
|
||||||
html += '<button data-icon="arrow-l" data-iconpos="notext" data-inline="true" data-mini="true" class="btnPreviousPage" ' + (query.StartIndex ? '' : 'disabled') + '>Previous Page</button>';
|
html += '<button data-icon="arrow-l" data-iconpos="notext" data-inline="true" data-mini="true" class="btnPreviousPage" ' + (query.StartIndex ? '' : 'disabled') + '>Previous Page</button>';
|
||||||
|
|
||||||
html += '<button data-icon="arrow-r" data-iconpos="notext" data-inline="true" data-mini="true" class="btnNextPage" ' + (query.StartIndex + query.Limit > totalRecordCount ? 'disabled' : '') + '>Next Page</button>';
|
html += '<button data-icon="arrow-r" data-iconpos="notext" data-inline="true" data-mini="true" class="btnNextPage" ' + (query.StartIndex + query.Limit > totalRecordCount ? 'disabled' : '') + '>Next Page</button>';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
var id = "selectPageSize" + new Date().getTime();
|
if (showLimit !== false) {
|
||||||
|
var id = "selectPageSize" + new Date().getTime();
|
||||||
|
|
||||||
var options = '';
|
var options = '';
|
||||||
|
|
||||||
function getOption(val) {
|
function getOption(val) {
|
||||||
|
|
||||||
if (query.Limit == val) {
|
if (query.Limit == val) {
|
||||||
|
|
||||||
return '<option value="' + val + '" selected="selected">' + val + '</option>';
|
return '<option value="' + val + '" selected="selected">' + val + '</option>';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return '<option value="' + val + '">' + val + '</option>';
|
return '<option value="' + val + '">' + val + '</option>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pageSizes = pageSizes || [20, 50, 100, 200, 300, 400, 500];
|
||||||
|
|
||||||
|
for (var j = 0, length = pageSizes.length; j < length; j++) {
|
||||||
|
options += getOption(pageSizes[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add styles to defeat jquery mobile
|
||||||
|
html += '<label style="display:inline;font-size:inherit;" class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
||||||
}
|
}
|
||||||
|
|
||||||
pageSizes = pageSizes || [20, 50, 100, 200, 300, 400, 500];
|
|
||||||
|
|
||||||
for (var j = 0, length = pageSizes.length; j < length; j++) {
|
|
||||||
options += getOption(pageSizes[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add styles to defeat jquery mobile
|
|
||||||
html += '<label style="display:inline;font-size:inherit;" class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
|
@ -52,13 +52,13 @@
|
||||||
|
|
||||||
var page = this;
|
var page = this;
|
||||||
|
|
||||||
$('#txtSeasonFolderPattern', page).on('change keypress', function() {
|
$('#txtSeasonFolderPattern', page).on('change keyup', function () {
|
||||||
|
|
||||||
updateSeasonPatternHelp(page, this.value);
|
updateSeasonPatternHelp(page, this.value);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#txtEpisodePattern', page).on('change keypress', function () {
|
$('#txtEpisodePattern', page).on('change keyup', function () {
|
||||||
|
|
||||||
updateEpisodePatternHelp(page, this.value);
|
updateEpisodePatternHelp(page, this.value);
|
||||||
|
|
||||||
|
|
237
dashboard-ui/scripts/libraryfileorganizerlog.js
Normal file
237
dashboard-ui/scripts/libraryfileorganizerlog.js
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
(function ($, document, window) {
|
||||||
|
|
||||||
|
var query = {
|
||||||
|
|
||||||
|
StartIndex: 0,
|
||||||
|
Limit: 50
|
||||||
|
};
|
||||||
|
|
||||||
|
var currentResult;
|
||||||
|
|
||||||
|
function showStatusMessage(id) {
|
||||||
|
|
||||||
|
var item = currentResult.Items.filter(function (i) {
|
||||||
|
return i.Id == id;
|
||||||
|
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
Dashboard.alert({
|
||||||
|
|
||||||
|
title: getStatusText(item, false),
|
||||||
|
message: item.StatusMessage
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteOriginalFile(page, id) {
|
||||||
|
|
||||||
|
var item = currentResult.Items.filter(function (i) {
|
||||||
|
return i.Id == id;
|
||||||
|
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
var message = 'The following file will be deleted:<p>' + item.OriginalPath + '</p><p>Are you sure you wish to proceed?</p>';
|
||||||
|
|
||||||
|
Dashboard.confirm(message, "Delete File", function (confirmResult) {
|
||||||
|
|
||||||
|
if (confirmResult) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
ApiClient.deleteOriginalFileFromOrganizationResult(id).done(function () {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
reloadItems(page);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function organizeFile(page, id) {
|
||||||
|
|
||||||
|
var item = currentResult.Items.filter(function (i) {
|
||||||
|
return i.Id == id;
|
||||||
|
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
var message = 'The following file will be moved from:<p>' + item.OriginalPath + '</p><p>to:</p><p>' + item.TargetPath + '</p><p>Are you sure you wish to proceed?</p>';
|
||||||
|
|
||||||
|
Dashboard.confirm(message, "Organize File", function (confirmResult) {
|
||||||
|
|
||||||
|
if (confirmResult) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
ApiClient.performOrganization(id).done(function () {
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
|
||||||
|
reloadItems(page);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadItems(page) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
ApiClient.getFileOrganizationResults(query).done(function (result) {
|
||||||
|
|
||||||
|
currentResult = result;
|
||||||
|
renderResults(page, result);
|
||||||
|
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStatusText(item, enhance) {
|
||||||
|
|
||||||
|
var status = item.Status;
|
||||||
|
|
||||||
|
var color = null;
|
||||||
|
|
||||||
|
if (status == 'SkippedTrial') {
|
||||||
|
status = 'Trial';
|
||||||
|
}
|
||||||
|
else if (status == 'SkippedExisting') {
|
||||||
|
status = 'Skipped';
|
||||||
|
}
|
||||||
|
else if (status == 'Failure') {
|
||||||
|
color = '#cc0000';
|
||||||
|
status = 'Failed';
|
||||||
|
}
|
||||||
|
if (status == 'Success') {
|
||||||
|
color = 'green';
|
||||||
|
status = 'Success';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enhance && enhance) {
|
||||||
|
|
||||||
|
if (item.StatusMessage) {
|
||||||
|
|
||||||
|
return '<a style="color:' + color + ';" data-resultid="' + item.Id + '" href="#" class="btnShowStatusMessage">' + status + '</a>';
|
||||||
|
} else {
|
||||||
|
return '<span data-resultid="' + item.Id + '" style="color:' + color + ';">' + status + '</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderResults(page, result) {
|
||||||
|
|
||||||
|
var rows = result.Items.map(function (item) {
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
html += '<tr>';
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
|
||||||
|
var date = parseISO8601Date(item.Date, { toLocal: true });
|
||||||
|
html += date.toLocaleDateString();
|
||||||
|
|
||||||
|
html += '</td>';
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
html += item.OriginalFileName || '';
|
||||||
|
html += '</td>';
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
html += item.TargetPath || '';
|
||||||
|
html += '</td>';
|
||||||
|
|
||||||
|
html += '<td>';
|
||||||
|
html += getStatusText(item, true);
|
||||||
|
html += '</td>';
|
||||||
|
|
||||||
|
html += '<td class="organizerButtonCell">';
|
||||||
|
|
||||||
|
|
||||||
|
if (item.Status == 'SkippedTrial' || item.Status == 'SkippedExisting') {
|
||||||
|
html += '<button data-resultid="' + item.Id + '" type="button" data-inline="true" data-icon="action" data-mini="true" data-iconpos="notext" class="btnProcessResult organizerButton" title="Organize File">Process</button>';
|
||||||
|
} else {
|
||||||
|
html += '<button style="visibility:hidden;" type="button" data-inline="true" data-icon="info" data-mini="true" data-iconpos="notext" class="organizerButton"></button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Status != 'Success') {
|
||||||
|
html += '<button data-resultid="' + item.Id + '" type="button" data-inline="true" data-icon="delete" data-mini="true" data-iconpos="notext" class="btnDeleteResult organizerButton" title="Delete">Delete File</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</td>';
|
||||||
|
|
||||||
|
html += '</tr>';
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
var elem = $('.resultBody', page).html(rows).parents('.tblOrganizationResults').table("refresh").trigger('create');
|
||||||
|
|
||||||
|
$('.btnShowStatusMessage', elem).on('click', function () {
|
||||||
|
|
||||||
|
var id = this.getAttribute('data-resultid');
|
||||||
|
|
||||||
|
showStatusMessage(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnProcessResult', elem).on('click', function () {
|
||||||
|
|
||||||
|
var id = this.getAttribute('data-resultid');
|
||||||
|
|
||||||
|
organizeFile(page, id);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnDeleteResult', elem).on('click', function () {
|
||||||
|
|
||||||
|
var id = this.getAttribute('data-resultid');
|
||||||
|
|
||||||
|
deleteOriginalFile(page, id);
|
||||||
|
});
|
||||||
|
|
||||||
|
var pagingHtml = LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, false, [], false);
|
||||||
|
$('.listTopPaging', page).html(pagingHtml).trigger('create');
|
||||||
|
|
||||||
|
if (result.TotalRecordCount > query.Limit && result.TotalRecordCount > 50) {
|
||||||
|
$('.listBottomPaging', page).html(pagingHtml).trigger('create');
|
||||||
|
} else {
|
||||||
|
$('.listBottomPaging', page).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.selectPage', page).on('change', function () {
|
||||||
|
query.StartIndex = (parseInt(this.value) - 1) * query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnNextPage', page).on('click', function () {
|
||||||
|
query.StartIndex += query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnPreviousPage', page).on('click', function () {
|
||||||
|
query.StartIndex -= query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('pageshow', "#libraryFileOrganizerLogPage", function () {
|
||||||
|
|
||||||
|
var page = this;
|
||||||
|
|
||||||
|
reloadItems(page);
|
||||||
|
|
||||||
|
}).on('pagehide', "#libraryFileOrganizerLogPage", function () {
|
||||||
|
|
||||||
|
currentResult = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery, document, window);
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.238" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.240" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Add table
Add a link
Reference in a new issue