subscriptions.html
| 1 | {{define "subscriptions"}} |
| 2 | <div class="page-header"> |
| 3 | <h2>Subscriptions</h2> |
| 4 | </div> |
| 5 | |
| 6 | <div class="settings-layout"> |
| 7 | <article> |
| 8 | <h3>Your Subscriptions</h3> |
| 9 | <div class="subscriptions-list"> |
| 10 | {{range .Data.Subscriptions}} |
| 11 | {{$sub := .}} |
| 12 | <article> |
| 13 | <div class="preset-header"> |
| 14 | <h4> |
| 15 | {{.Name}} |
| 16 | {{if .Enabled}}<span class="badge">active</span>{{else}}<span class="badge">paused</span>{{end}} |
| 17 | </h4> |
| 18 | <details class="delete-overlay"> |
| 19 | <summary role="button" class="small danger">Delete</summary> |
| 20 | <div class="overlay-panel"> |
| 21 | <p>Delete subscription <strong>{{.Name}}</strong>? (Downloaded files are kept.)</p> |
| 22 | <form method="post" action="/subscriptions/{{.ID}}/delete" class="form-actions"> |
| 23 | <button type="submit" class="danger">Yes, Delete</button> |
| 24 | </form> |
| 25 | </div> |
| 26 | </details> |
| 27 | </div> |
| 28 | |
| 29 | <p class="preset-description"> |
| 30 | <code>{{.URL}}</code><br> |
| 31 | Folder: <code>{{.OutputDir}}</code> · |
| 32 | Mode: <strong>{{.RefreshMode}}</strong> · |
| 33 | Schedule: <strong>{{.ScheduleKind}}</strong> (<code>{{.CronExpr}}</code>) |
| 34 | {{if .PruneRemoved}} · prunes removed{{end}} |
| 35 | </p> |
| 36 | <p class="preset-description"> |
| 37 | Next run: {{if .NextRunAt.Valid}}{{.NextRunAt.Time.Format "2006-01-02 15:04"}}{{else}}—{{end}} |
| 38 | · Last run: {{if .LastRunAt.Valid}}{{.LastRunAt.Time.Format "2006-01-02 15:04"}}{{else}}never{{end}} |
| 39 | {{if .LastStatus.Valid}} ({{.LastStatus.String}}){{end}} |
| 40 | </p> |
| 41 | |
| 42 | <div class="preset-actions"> |
| 43 | <form method="post" action="/subscriptions/{{.ID}}/run" class="inline"> |
| 44 | <button type="submit" class="small">Run now</button> |
| 45 | </form> |
| 46 | <form method="post" action="/subscriptions/{{.ID}}/toggle" class="inline"> |
| 47 | <button type="submit" class="small secondary">{{if .Enabled}}Pause{{else}}Resume{{end}}</button> |
| 48 | </form> |
| 49 | <details> |
| 50 | <summary role="button" class="small"><span class="edit-text">Edit</span><span class="cancel-text">Cancel</span></summary> |
| 51 | <form method="post" action="/subscriptions/{{.ID}}" class="edit-form"> |
| 52 | <div class="form-group"> |
| 53 | <label>Name *</label> |
| 54 | <input type="text" name="name" required value="{{$sub.Name}}"> |
| 55 | </div> |
| 56 | <div class="form-group"> |
| 57 | <label>URL *</label> |
| 58 | <input type="text" name="url" required value="{{$sub.URL}}"> |
| 59 | </div> |
| 60 | <div class="form-group"> |
| 61 | <label>Library folder *</label> |
| 62 | <input type="text" name="output_dir" required value="{{$sub.OutputDir}}"> |
| 63 | <small>This subscription owns this folder — don't download into it manually. May be nested, e.g. <code>subscriptions/news</code>.</small> |
| 64 | </div> |
| 65 | |
| 66 | <div class="form-group"> |
| 67 | <label>Refresh mode</label> |
| 68 | <div class="radio-group"> |
| 69 | <label><input type="radio" name="refresh_mode" value="overwrite" {{if eq $sub.RefreshMode "overwrite"}}checked{{end}}> Overwrite (re-download & replace)</label> |
| 70 | <label><input type="radio" name="refresh_mode" value="skip" {{if eq $sub.RefreshMode "skip"}}checked{{end}}> Skip existing (add new only)</label> |
| 71 | <label><input type="radio" name="refresh_mode" value="metadata" {{if eq $sub.RefreshMode "metadata"}}checked{{end}}> Metadata refresh (update existing, add new)</label> |
| 72 | </div> |
| 73 | </div> |
| 74 | |
| 75 | <div class="form-row"> |
| 76 | <div class="form-group"> |
| 77 | <label>Schedule</label> |
| 78 | <select name="schedule_kind"> |
| 79 | <option value="hourly" {{if eq $sub.ScheduleKind "hourly"}}selected{{end}}>Hourly</option> |
| 80 | <option value="daily" {{if eq $sub.ScheduleKind "daily"}}selected{{end}}>Daily</option> |
| 81 | <option value="weekly" {{if eq $sub.ScheduleKind "weekly"}}selected{{end}}>Weekly</option> |
| 82 | <option value="monthly" {{if eq $sub.ScheduleKind "monthly"}}selected{{end}}>Monthly</option> |
| 83 | <option value="cron" {{if eq $sub.ScheduleKind "cron"}}selected{{end}}>Custom (cron)</option> |
| 84 | </select> |
| 85 | </div> |
| 86 | <div class="form-group"> |
| 87 | <label>Cron expression</label> |
| 88 | <input type="text" name="cron_expr" value="{{$sub.CronExpr}}" placeholder="0 3 * * *"> |
| 89 | <small>Used when schedule is "Custom". Standard 5-field cron.</small> |
| 90 | </div> |
| 91 | </div> |
| 92 | |
| 93 | <div class="form-group"> |
| 94 | <label>Preset</label> |
| 95 | <select name="preset_id"> |
| 96 | <option value="">Default preset</option> |
| 97 | {{range $.Data.Presets}} |
| 98 | <option value="{{.ID}}" {{if and $sub.PresetID.Valid (eq $sub.PresetID.Int64 .ID)}}selected{{end}}>{{.Name}}</option> |
| 99 | {{end}} |
| 100 | </select> |
| 101 | </div> |
| 102 | |
| 103 | <div class="form-group"> |
| 104 | <label>Format override</label> |
| 105 | <input type="text" name="format_override" value="{{$sub.FormatOverride}}" placeholder="e.g., bestvideo+bestaudio/best or format ID like 22"> |
| 106 | </div> |
| 107 | <div class="form-group"> |
| 108 | <label>Custom flags</label> |
| 109 | <textarea name="custom_flags" rows="2">{{$sub.CustomFlags}}</textarea> |
| 110 | {{template "ytdlp_notes" true}} |
| 111 | </div> |
| 112 | <div class="form-group"> |
| 113 | <label> |
| 114 | <input type="checkbox" name="prune_removed" value="1" {{if $sub.PruneRemoved}}checked{{end}}> |
| 115 | Delete items removed from the source (prune) |
| 116 | </label> |
| 117 | </div> |
| 118 | |
| 119 | <div class="form-actions"> |
| 120 | <button type="submit" class="primary">Update Subscription</button> |
| 121 | </div> |
| 122 | </form> |
| 123 | </details> |
| 124 | </div> |
| 125 | </article> |
| 126 | {{else}} |
| 127 | <p>No subscriptions yet. Create one below.</p> |
| 128 | {{end}} |
| 129 | </div> |
| 130 | </article> |
| 131 | |
| 132 | <article> |
| 133 | <h3>Create Subscription</h3> |
| 134 | <form method="post" action="/subscriptions"> |
| 135 | <div class="form-group"> |
| 136 | <label>Name *</label> |
| 137 | <input type="text" name="name" required placeholder="A name for this subscription"> |
| 138 | </div> |
| 139 | <div class="form-group"> |
| 140 | <label>URL *</label> |
| 141 | <input type="text" name="url" required placeholder="https://youtube.com/watch?v=..."> |
| 142 | </div> |
| 143 | <div class="form-group"> |
| 144 | <label>Library folder *</label> |
| 145 | <input type="text" name="output_dir" required placeholder="e.g., videos/music (relative to library folder)"> |
| 146 | <small>This subscription owns this folder — don't download into it manually. May be nested.</small> |
| 147 | </div> |
| 148 | |
| 149 | <div class="form-group"> |
| 150 | <label>Refresh mode</label> |
| 151 | <div class="radio-group"> |
| 152 | <label><input type="radio" name="refresh_mode" value="overwrite" checked> Overwrite (re-download & replace)</label> |
| 153 | <label><input type="radio" name="refresh_mode" value="skip"> Skip existing (add new only)</label> |
| 154 | <label><input type="radio" name="refresh_mode" value="metadata"> Metadata refresh (update existing, add new)</label> |
| 155 | </div> |
| 156 | </div> |
| 157 | |
| 158 | <div class="form-row"> |
| 159 | <div class="form-group"> |
| 160 | <label>Schedule</label> |
| 161 | <select name="schedule_kind"> |
| 162 | <option value="hourly">Hourly</option> |
| 163 | <option value="daily" selected>Daily</option> |
| 164 | <option value="weekly">Weekly</option> |
| 165 | <option value="monthly">Monthly</option> |
| 166 | <option value="cron">Custom (cron)</option> |
| 167 | </select> |
| 168 | </div> |
| 169 | <div class="form-group"> |
| 170 | <label>Cron expression</label> |
| 171 | <input type="text" name="cron_expr" placeholder="0 3 * * *"> |
| 172 | <small>Used when schedule is "Custom". Standard 5-field cron.</small> |
| 173 | </div> |
| 174 | </div> |
| 175 | |
| 176 | <div class="form-group"> |
| 177 | <label>Preset</label> |
| 178 | <select name="preset_id"> |
| 179 | <option value="">Default preset</option> |
| 180 | {{range .Data.Presets}} |
| 181 | <option value="{{.ID}}">{{.Name}}</option> |
| 182 | {{end}} |
| 183 | </select> |
| 184 | </div> |
| 185 | |
| 186 | <div class="form-group"> |
| 187 | <label>Format override</label> |
| 188 | <input type="text" name="format_override" placeholder="e.g., bestvideo+bestaudio/best or format ID like 22"> |
| 189 | </div> |
| 190 | <div class="form-group"> |
| 191 | <label>Custom flags</label> |
| 192 | <textarea name="custom_flags" rows="2" placeholder="Any additional yt-dlp flags..."></textarea> |
| 193 | {{template "ytdlp_notes" true}} |
| 194 | </div> |
| 195 | <div class="form-group"> |
| 196 | <label> |
| 197 | <input type="checkbox" name="prune_removed" value="1"> |
| 198 | Delete items removed from the source (prune) |
| 199 | </label> |
| 200 | </div> |
| 201 | |
| 202 | <div class="form-actions"> |
| 203 | <button type="submit" class="primary">Create Subscription</button> |
| 204 | </div> |
| 205 | </form> |
| 206 | </article> |
| 207 | </div> |
| 208 | {{end}} |
| 209 |