fix repair; repair.json, remove arr details from endpoint
This commit is contained in:
@@ -94,7 +94,8 @@ func (a *Arr) GetMedia(mediaId string) ([]Content, error) {
|
|||||||
files = append(files, ContentFile{
|
files = append(files, ContentFile{
|
||||||
FileId: file.Id,
|
FileId: file.Id,
|
||||||
Path: file.Path,
|
Path: file.Path,
|
||||||
Id: eId,
|
Id: d.Id,
|
||||||
|
EpisodeId: eId,
|
||||||
SeasonNumber: file.SeasonNumber,
|
SeasonNumber: file.SeasonNumber,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -179,7 +180,7 @@ func (a *Arr) searchSonarr(files []ContentFile) error {
|
|||||||
errs <- fmt.Errorf("failed to automatic search: %v", err)
|
errs <- fmt.Errorf("failed to automatic search: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if statusOk := strconv.Itoa(resp.StatusCode)[0] == '2'; !statusOk {
|
if resp.StatusCode >= 300 || resp.StatusCode < 200 {
|
||||||
errs <- fmt.Errorf("failed to automatic search. Status Code: %s", resp.Status)
|
errs <- fmt.Errorf("failed to automatic search. Status Code: %s", resp.Status)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type ContentFile struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
|
EpisodeId int `json:"showId"`
|
||||||
FileId int `json:"fileId"`
|
FileId int `json:"fileId"`
|
||||||
TargetPath string `json:"targetPath"`
|
TargetPath string `json:"targetPath"`
|
||||||
IsSymlink bool `json:"isSymlink"`
|
IsSymlink bool `json:"isSymlink"`
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func (q *QBit) handleTorrentsInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
category := ctx.Value("category").(string)
|
category := ctx.Value("category").(string)
|
||||||
filter := strings.Trim(r.URL.Query().Get("filter"), "")
|
filter := strings.Trim(r.URL.Query().Get("filter"), "")
|
||||||
hashes, _ := ctx.Value("hashes").([]string)
|
hashes, _ := ctx.Value("hashes").([]string)
|
||||||
torrents := q.Storage.GetAll(category, filter, hashes)
|
torrents := q.Storage.GetAllSorted(category, filter, hashes, "added_on", false)
|
||||||
request.JSONResponse(w, torrents, http.StatusOK)
|
request.JSONResponse(w, torrents, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const (
|
|||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Arrs []*arr.Arr `json:"arrs"`
|
Arrs []string `json:"arrs"`
|
||||||
MediaIDs []string `json:"media_ids"`
|
MediaIDs []string `json:"media_ids"`
|
||||||
StartedAt time.Time `json:"created_at"`
|
StartedAt time.Time `json:"created_at"`
|
||||||
BrokenItems map[string][]arr.ContentFile `json:"broken_items"`
|
BrokenItems map[string][]arr.ContentFile `json:"broken_items"`
|
||||||
@@ -96,44 +96,34 @@ func (j *Job) discordContext() string {
|
|||||||
**Started At**: %s
|
**Started At**: %s
|
||||||
**Completed At**: %s
|
**Completed At**: %s
|
||||||
`
|
`
|
||||||
arrs := make([]string, 0)
|
|
||||||
for _, a := range j.Arrs {
|
|
||||||
arrs = append(arrs, a.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
dateFmt := "2006-01-02 15:04:05"
|
dateFmt := "2006-01-02 15:04:05"
|
||||||
|
|
||||||
return fmt.Sprintf(format, j.ID, strings.Join(arrs, ","), strings.Join(j.MediaIDs, ", "), j.Status, j.StartedAt.Format(dateFmt), j.CompletedAt.Format(dateFmt))
|
return fmt.Sprintf(format, j.ID, strings.Join(j.Arrs, ","), strings.Join(j.MediaIDs, ", "), j.Status, j.StartedAt.Format(dateFmt), j.CompletedAt.Format(dateFmt))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repair) getArrs(arrNames []string) []*arr.Arr {
|
func (r *Repair) getArrs(arrNames []string) []string {
|
||||||
checkSkip := true // This is useful when user triggers repair with specific arrs
|
arrs := make([]string, 0)
|
||||||
arrs := make([]*arr.Arr, 0)
|
|
||||||
if len(arrNames) == 0 {
|
if len(arrNames) == 0 {
|
||||||
// No specific arrs, get all
|
// No specific arrs, get all
|
||||||
// Also check if any arrs are set to skip repair
|
// Also check if any arrs are set to skip repair
|
||||||
arrs = r.arrs.GetAll()
|
_arrs := r.arrs.GetAll()
|
||||||
|
for _, a := range _arrs {
|
||||||
|
if a.SkipRepair {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
arrs = append(arrs, a.Name)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
checkSkip = false
|
|
||||||
for _, name := range arrNames {
|
for _, name := range arrNames {
|
||||||
a := r.arrs.Get(name)
|
a := r.arrs.Get(name)
|
||||||
if a == nil || a.Host == "" || a.Token == "" {
|
if a == nil || a.Host == "" || a.Token == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
arrs = append(arrs, a)
|
arrs = append(arrs, a.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !checkSkip {
|
return arrs
|
||||||
return arrs
|
|
||||||
}
|
|
||||||
filtered := make([]*arr.Arr, 0)
|
|
||||||
for _, a := range arrs {
|
|
||||||
if a.SkipRepair {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
filtered = append(filtered, a)
|
|
||||||
}
|
|
||||||
return filtered
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func jobKey(arrNames []string, mediaIDs []string) string {
|
func jobKey(arrNames []string, mediaIDs []string) string {
|
||||||
@@ -221,7 +211,7 @@ func (r *Repair) repair(job *Job) error {
|
|||||||
if len(job.MediaIDs) == 0 {
|
if len(job.MediaIDs) == 0 {
|
||||||
items, err = r.repairArr(job, a, "")
|
items, err = r.repairArr(job, a, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Error().Err(err).Msgf("Error repairing %s", a.Name)
|
r.logger.Error().Err(err).Msgf("Error repairing %s", a)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -235,7 +225,7 @@ func (r *Repair) repair(job *Job) error {
|
|||||||
|
|
||||||
someItems, err := r.repairArr(job, a, id)
|
someItems, err := r.repairArr(job, a, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Error().Err(err).Msgf("Error repairing %s with ID %s", a.Name, id)
|
r.logger.Error().Err(err).Msgf("Error repairing %s with ID %s", a, id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
items = append(items, someItems...)
|
items = append(items, someItems...)
|
||||||
@@ -245,7 +235,7 @@ func (r *Repair) repair(job *Job) error {
|
|||||||
// Safely append the found items to the shared slice
|
// Safely append the found items to the shared slice
|
||||||
if len(items) > 0 {
|
if len(items) > 0 {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
brokenItems[a.Name] = items
|
brokenItems[a] = items
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,8 +331,9 @@ func (r *Repair) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repair) repairArr(j *Job, a *arr.Arr, tmdbId string) ([]arr.ContentFile, error) {
|
func (r *Repair) repairArr(j *Job, _arr string, tmdbId string) ([]arr.ContentFile, error) {
|
||||||
brokenItems := make([]arr.ContentFile, 0)
|
brokenItems := make([]arr.ContentFile, 0)
|
||||||
|
a := r.arrs.Get(_arr)
|
||||||
|
|
||||||
r.logger.Info().Msgf("Starting repair for %s", a.Name)
|
r.logger.Info().Msgf("Starting repair for %s", a.Name)
|
||||||
media, err := a.GetMedia(tmdbId)
|
media, err := a.GetMedia(tmdbId)
|
||||||
@@ -665,7 +656,9 @@ func (r *Repair) loadFromFile() {
|
|||||||
jobs := make(map[string]*Job)
|
jobs := make(map[string]*Job)
|
||||||
err = json.Unmarshal(data, &jobs)
|
err = json.Unmarshal(data, &jobs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.Debug().Err(err).Msg("Failed to unmarshal jobs")
|
r.logger.Trace().Err(err).Msg("Failed to unmarshal jobs; resetting")
|
||||||
|
r.Jobs = make(map[string]*Job)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
r.Jobs = jobs
|
r.Jobs = jobs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><a href="#" class="text-link view-job" data-id="${job.id}"><small>${job.id.substring(0, 8)}</small></a></td>
|
<td><a href="#" class="text-link view-job" data-id="${job.id}"><small>${job.id.substring(0, 8)}</small></a></td>
|
||||||
<td>${job.arrs.map(a => a.name).join(', ')}</td>
|
<td>${job.arrs.join(', ')}</td>
|
||||||
<td><small>${formattedDate}</small></td>
|
<td><small>${formattedDate}</small></td>
|
||||||
<td><span class="${statusClass}">${status}</span></td>
|
<td><span class="${statusClass}">${status}</span></td>
|
||||||
<td>${totalItems}</td>
|
<td>${totalItems}</td>
|
||||||
@@ -447,7 +447,10 @@
|
|||||||
async function processJob(jobId) {
|
async function processJob(jobId) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/internal/repair/jobs/${jobId}/process`, {
|
const response = await fetch(`/internal/repair/jobs/${jobId}/process`, {
|
||||||
method: 'POST'
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) throw new Error(await response.text());
|
if (!response.ok) throw new Error(await response.text());
|
||||||
@@ -496,7 +499,7 @@
|
|||||||
document.getElementById('modalJobStatus').innerHTML = `<span class="${statusClass}">${status}</span>`;
|
document.getElementById('modalJobStatus').innerHTML = `<span class="${statusClass}">${status}</span>`;
|
||||||
|
|
||||||
// Set other job details
|
// Set other job details
|
||||||
document.getElementById('modalJobArrs').textContent = job.arrs.map(a => a.name).join(', ');
|
document.getElementById('modalJobArrs').textContent = job.arrs.join(', ');
|
||||||
document.getElementById('modalJobMediaIds').textContent = job.media_ids && job.media_ids.length > 0 ?
|
document.getElementById('modalJobMediaIds').textContent = job.media_ids && job.media_ids.length > 0 ?
|
||||||
job.media_ids.join(', ') : 'All';
|
job.media_ids.join(', ') : 'All';
|
||||||
document.getElementById('modalJobAutoProcess').textContent = job.auto_process ? 'Yes' : 'No';
|
document.getElementById('modalJobAutoProcess').textContent = job.auto_process ? 'Yes' : 'No';
|
||||||
|
|||||||
Reference in New Issue
Block a user