push latest changes
This commit is contained in:
		
							parent
							
								
									7523a19d1f
								
							
						
					
					
						commit
						cb2b5c2c2b
					
				
					 63 changed files with 3158 additions and 1552 deletions
				
			
		|  | @ -10,21 +10,21 @@ | |||
|                 {{ bootstrap.load_css() }} | ||||
|                 <link rel="stylesheet" href="{{url_for('static', filename='theme.css')}}"> | ||||
|             {% endblock %} | ||||
|             <link rel="shortcut icon" type="image/svg" href="{{url_for('static',filename='icon.svg')}}"/> | ||||
|             <title>MediaDash</title> | ||||
|         {% endblock %} | ||||
|     </head> | ||||
|     <body> | ||||
|         {% block navbar %} | ||||
|         <nav class="navbar sticky-top navbar-expand-lg navbar-dark" style="background-color: #222;"> | ||||
|             <a class="navbar-brand" href="/">MediaDash</a> | ||||
|             <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar_main" aria-controls="navbar_main" aria-expanded="false" aria-label="Toggle navigation"> | ||||
|                 <span class="navbar-toggler-icon"></span> | ||||
|             </button> | ||||
|             {% if request.path!=url_for("login") %} | ||||
|                 <img src="{{url_for('static',filename='icon.svg')}}" width=40 height=40/> | ||||
|             {% endif %} | ||||
|             <div class="collapse navbar-collapse" id="navbar_main"> | ||||
|                 {{nav.left_nav.render(renderer='bootstrap4')}} | ||||
|                 {{nav.right_nav.render(renderer='bootstrap4')}} | ||||
|             </div> | ||||
|             </nav> | ||||
|         </div> | ||||
|         </nav> | ||||
|         {% endblock %} | ||||
|         {% block content %} | ||||
|         <div class={{"container-fluid" if fluid else "container"}}> | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ | |||
|     <h1> | ||||
|         <a href="{{config.APP_CONFIG.portainer_url}}">Portainer</a> | ||||
|     </h1> | ||||
|     <table class="table table-sm"> | ||||
|     <table class="table table-sm table-bordered"> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 <th scope="col">Name</th> | ||||
|  | @ -42,7 +42,7 @@ | |||
|             {% set label = container.Labels["com.docker.compose.service"] %} | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <a href="{{url_for('containers',container_id=container.Id)}}"> | ||||
|                         <a href="{{url_for('containers.details',container_id=container.Id)}}"> | ||||
|                             {{container.Labels["com.docker.compose.project"]}}/{{container.Labels["com.docker.compose.service"]}} | ||||
|                         </a> | ||||
|                     </td> | ||||
|  |  | |||
							
								
								
									
										8
									
								
								templates/error.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								templates/error.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
|     <div class="container" style="max-width: 30% !important;"> | ||||
|         <h1>Oops</h1> | ||||
|     </div> | ||||
| {% endblock %} | ||||
|  | @ -41,62 +41,89 @@ | |||
|     <div class="row"> | ||||
|         <div class="col-lg"> | ||||
|             <h3>Movies</h3> | ||||
|             <table class="table table-sm"> | ||||
|             <table class="table table-sm table-bordered"> | ||||
|                 <tr> | ||||
|                     <th>Title</th> | ||||
|                     <th>Status</th> | ||||
|                     <th>In Cinemas</th> | ||||
|                     <th>Digital Release</th> | ||||
|                 </tr> | ||||
|                 {% for movie in data.calendar.movies %} | ||||
|                     {% if movie.isAvailable and movie.hasFile %} | ||||
|                         {% set row_class = "bg-success" %} | ||||
|                         {% set row_attrs = "bg-success" %} | ||||
|                     {% elif movie.isAvailable and not movie.hasFile %} | ||||
|                         {% set row_class = "bg-danger" %} | ||||
|                         {% set row_attrs = "bg-danger" %} | ||||
|                     {% elif not movie.isAvailable and movie.hasFile %} | ||||
|                         {% set row_class = "bg-primary" %} | ||||
|                         {% set row_attrs = "bg-primary" %} | ||||
|                     {% elif not movie.isAvailable and not movie.hasFile %} | ||||
|                         {% set row_class = "bg-info" %} | ||||
|                         {% set row_attrs = "bg-info" %} | ||||
|                     {% endif %} | ||||
|                     <tr class={{row_class}}> | ||||
|                     <tr class={{row_attrs}}> | ||||
|                         <td> | ||||
|                         <a href="{{urljoin(config.APP_CONFIG.radarr_url,'movie/'+movie.titleSlug)}}" style="color: #eee; text-decoration: underline;"> | ||||
|                         <a title="{{movie.overview}}" href="{{urljoin(config.APP_CONFIG.radarr_url,'movie/'+movie.titleSlug)}}" style="color: #eee; text-decoration: underline;"> | ||||
|                             {{movie.title}} | ||||
|                         </a> | ||||
|                         </td> | ||||
|                         <td>{{movie.status}}</td> | ||||
|                         <td>{{movie.inCinemas|fromiso|ago_dt_utc_human(rnd=0)}}</td> | ||||
|                         <td>{{movie.digitalRelease|fromiso|ago_dt_utc_human(rnd=0)}}</td> | ||||
|                         {% if movie.digitalRelease %} | ||||
|                             <td>{{movie.digitalRelease|fromiso|ago_dt_utc_human(rnd=0)}}</td> | ||||
|                         {% else %} | ||||
|                             <td>Unknown</td> | ||||
|                         {% endif %} | ||||
|                     </tr> | ||||
|                 {% endfor %} | ||||
|             </table> | ||||
|             <h3>Episodes</h3> | ||||
| 
 | ||||
|             <table class="table table-sm"> | ||||
|             <table class="table table-sm table-bordered"> | ||||
|                 <tr> | ||||
|                     <th>Season | Episode Number</th> | ||||
|                     <th>Show</th> | ||||
|                     <th>Title</th> | ||||
|                     <th>Status</th> | ||||
|                     <th>Air Date</th> | ||||
|                 </tr> | ||||
|                 {% for entry in data.calendar.episodes %} | ||||
|                 {% if entry.episode.hasAired and entry.episode.hasFile %} | ||||
|                     {% set row_class = "bg-success" %} | ||||
|                 {% elif entry.episode.hasAired and not entry.episode.hasFile %} | ||||
|                     {% set row_class = "bg-danger" %} | ||||
|                 {% elif not entry.episode.hasAired and entry.episode.hasFile %} | ||||
|                     {% set row_class = "bg-primary" %} | ||||
|                 {% elif not entry.episode.hasAired and not entry.episode.hasFile %} | ||||
|                     {% set row_class = "bg-info" %} | ||||
|                 {% endif %} | ||||
|                 <tr class={{row_class}}> | ||||
|                     <td>{{entry.episode.seasonNumber}} | {{entry.episode.episodeNumber}}</td> | ||||
|                     <td> | ||||
|                         <a href="{{urljoin(config.APP_CONFIG.sonarr_url,'series/'+entry.series.titleSlug)}}" style="color: #eee; text-decoration: underline;"> | ||||
|                             {{entry.series.title}} | ||||
|                         </a> | ||||
|                     </td> | ||||
|                     <td>{{entry.episode.title}}</td> | ||||
|                     <td>{{entry.episode.airDateUtc|fromiso|ago_dt_utc_human(rnd=0)}}</td> | ||||
|                 </tr> | ||||
|                     {% if entry.details %} | ||||
|                             {% set details = entry.details[0] %} | ||||
|                     {% endif %} | ||||
|                     {% if entry.episode.hasAired and entry.episode.hasFile %} | ||||
|                         {% set row_attrs = {"class":"bg-success"} %} | ||||
|                     {% elif entry.episode.hasAired and not entry.episode.hasFile and details %} | ||||
|                         {% set row_attrs = {"style":"background-color: green !important"} %} | ||||
|                     {% elif entry.episode.hasAired and not entry.episode.hasFile %} | ||||
|                         {% set row_attrs = {"class":"bg-danger"} %} | ||||
|                     {% elif not entry.episode.hasAired and entry.episode.hasFile %} | ||||
|                         {% set row_attrs = {"class":"bg-primary"} %} | ||||
|                     {% elif not entry.episode.hasAired and not entry.episode.hasFile %} | ||||
|                         {% set row_attrs = {"class":"bg-info"} %} | ||||
|                     {% endif %} | ||||
|                     <tr {{row_attrs|xmlattr}}> | ||||
|                         <td>{{entry.episode.seasonNumber}} | {{entry.episode.episodeNumber}}</td> | ||||
|                         <td> | ||||
|                             <a href="{{urljoin(config.APP_CONFIG.sonarr_url,'series/'+entry.series.titleSlug)}}" style="color: #eee; text-decoration: underline;"> | ||||
|                                 {{entry.series.title}} | ||||
|                             </a> | ||||
|                         </td> | ||||
|                         <td title="{{entry.episode.overview}}">{{entry.episode.title}}</td> | ||||
|                         <td> | ||||
|                             {% if details %} | ||||
|                                 {% set details = entry.details[0] %} | ||||
|                                 {% set dl_prc =((details.size-details.sizeleft)/details.size)*100|round(2) %} | ||||
|                                 {{details.status}} ({{dl_prc|round(2)}} %) | ||||
|                             {% elif row_attrs.class=="bg-success" %} | ||||
|                                 downloaded | ||||
|                             {% elif row_attrs.class=="bg-danger" %} | ||||
|                                 not downloaded | ||||
|                             {% elif row_attrs.class=="bg-primary" %} | ||||
|                                 leaked? | ||||
|                             {% elif row_attrs.class=="bg-info" %} | ||||
|                                 not aired | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                         <td>{{entry.episode.airDateUtc|fromiso|ago_dt_utc_human(rnd=0)}}</td> | ||||
|                     </tr> | ||||
|                 {% endfor %} | ||||
|             </table> | ||||
|         </div> | ||||
|  | @ -109,7 +136,7 @@ | |||
|         <h2>No Data available!</h2> | ||||
|     {% else %} | ||||
|         {% set tabs = [] %} | ||||
|         {% do tabs.append(("Upcoming",[upcoming(data)])) %} | ||||
|         {% do tabs.append(("Schedule",[upcoming(data)])) %} | ||||
|         {% for row in data.images %} | ||||
|             {% if row[0] is string %} | ||||
|                 {% set title=row[0] %} | ||||
|  |  | |||
							
								
								
									
										20
									
								
								templates/jellyfin/details.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								templates/jellyfin/details.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| {% from 'bootstrap/form.html' import render_form, render_field, render_form_row %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
| 
 | ||||
| <h2><a href={{info.LocalAddress}}>Jellyfin</a> v{{info.Version}}</h2> | ||||
| {% if status.HasUpdateAvailable %} | ||||
|     <h3>Update available</h3> | ||||
| {% endif %} | ||||
| {% if status.HasPendingRestart %} | ||||
|     <h3>Restart pending</h3> | ||||
| {% endif %} | ||||
| 
 | ||||
| <img src={{cfg.jellyfin_url}}/Items/{{item.Id}}/Images/Art> | ||||
| 
 | ||||
| <pre>{{item|pformat}}</pre> | ||||
| 
 | ||||
| {% endblock %} | ||||
|  | @ -3,119 +3,80 @@ | |||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| {% from 'bootstrap/form.html' import render_form, render_field, render_form_row %} | ||||
| 
 | ||||
| {% macro make_row(title,items) %} | ||||
|     <div class="d-flex flex-wrap"> | ||||
|     {% for item in items %} | ||||
|         {{item|safe}} | ||||
|     {% endfor %} | ||||
|     </div> | ||||
| {% endmacro %} | ||||
| 
 | ||||
| {% macro make_tabs(tabs) %} | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist"> | ||||
|                 {% for (label,_) in tabs %} | ||||
|                     {% set slug = (label|slugify) %} | ||||
|                     {% if not (loop.first and loop.last) %} | ||||
|                     <li class="nav-item"> | ||||
|                         <a class="nav-link {{'active' if loop.first}}" id="nav-{{slug}}-tab" data-toggle="pill" href="#pills-{{slug}}" role="tab" aria-controls="pills-{{slug}}" aria-selected="{{loop.first}}"> | ||||
|                             {{label}} | ||||
|                         </a> | ||||
|                     </li> | ||||
|                     {% endif %} | ||||
|                 {% endfor %} | ||||
|             </ul> | ||||
|         </div> | ||||
|     </div> | ||||
|      | ||||
|     <div class="tab-content" id="searchResults"> | ||||
|         {% for (label,items) in tabs %} | ||||
|             {% set slug = (label|slugify) %} | ||||
|             <div class="tab-pane fade {{'show active' if loop.first}}" id="pills-{{slug}}" role="tabpanel" aria-labelledby="nav-{{slug}}-tab"> | ||||
|                 {{make_row(label,items)}} | ||||
|             </div> | ||||
|         {% endfor %} | ||||
|     </div> | ||||
| {% endmacro %} | ||||
| 
 | ||||
| {% macro make_table(items) %} | ||||
|     <table class="table table-sm table-bordered"> | ||||
|         {% for item in items|sort(attribute="Name")%} | ||||
|             <tr> | ||||
|                 <td><a href="{{url_for('jellyfin.details',item_id=item.Id)}}">{{item.Name}}</a> ({{item.ProductionYear}})</td> | ||||
|             </tr> | ||||
|         {% endfor %} | ||||
|     </table> | ||||
| {% endmacro %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
|     <h1><a href={{info.LocalAddress}}>Jellyfin</a> v{{info.Version}}</h1> | ||||
|     {% if status.HasUpdateAvailable %} | ||||
|         <h3>Update available</h3> | ||||
|     {% endif %} | ||||
|     {% if status.HasPendingRestart %} | ||||
|         <h3>Restart pending</h3> | ||||
|     {% endif %} | ||||
| 
 | ||||
| <h2><a href={{jellyfin.info.LocalAddress}}>Jellyfin</a> v{{jellyfin.info.Version}}</h2> | ||||
|     <h3>Library statistics</h3> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col-lg"> | ||||
|         <h4>Active Streams</h4> | ||||
|         <table class="table table-sm"> | ||||
|             <tr> | ||||
|                 <th>Episode</th> | ||||
|                 <th>Show</th> | ||||
|                 <th>Language</th> | ||||
|                 <th>User</th> | ||||
|                 <th>Device</th> | ||||
|                 <th>Mode</th> | ||||
|             </tr> | ||||
|             {% for session in jellyfin.sessions %} | ||||
|                 {% if "NowPlayingItem" in session %} | ||||
|                 {% with np=session.NowPlayingItem, ps=session.PlayState%} | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         {% if session.SupportsMediaControl %} | ||||
|                         <a href="{{url_for('stop_stream',session=session.Id)}}"> | ||||
|                             {{render_icon("stop-circle")}} | ||||
|                         </a> | ||||
|                         {% endif %} | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.Id}}"> | ||||
|                             {{np.Name}} | ||||
|                         </a> | ||||
|                         ({{(ps.PositionTicks/10_000_000)|timedelta(digits=0)}}/{{(np.RunTimeTicks/10_000_000)|timedelta(digits=0)}}) | ||||
|                         {% if ps.IsPaused %} | ||||
|                             (Paused) | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.SeriesId}}"> | ||||
|                             {{np.SeriesName}} | ||||
|                         </a> | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.SeasonId}}"> | ||||
|                             ({{np.SeasonName}}) | ||||
|                         </a> | ||||
|                          | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         {% if ("AudioStreamIndex" in ps) and ("SubtitleStreamIndex" in ps) %} | ||||
|                             {{np.MediaStreams[ps.AudioStreamIndex].Language or "None"}}/{{np.MediaStreams[ps.SubtitleStreamIndex].Language or "None"}} | ||||
|                         {% else %} | ||||
|                             Unk/Unk | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/useredit.html?userId={{session.UserId}}"> | ||||
|                             {{session.UserName}} | ||||
|                         </a> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         {{session.DeviceName}} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         {% if ps.PlayMethod =="Transcode" %} | ||||
|                             <p title="{{session.TranscodingInfo.Bitrate|filesizeformat(binary=False)}}/s | {{session.TranscodingInfo.CompletionPercentage|round(2)}}%"> | ||||
|                                 {{ps.PlayMethod}} | ||||
|                             </p> | ||||
|                         {% else %} | ||||
|                         <p> | ||||
|                             {{ps.PlayMethod}} | ||||
|                         </p> | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                 {% endwith %} | ||||
|             {% endif %} | ||||
|     <table class="table table-sm table-bordered"> | ||||
|             {% for name, value in counts.items() %} | ||||
|                 {% if value != 0 %} | ||||
|                     <tr> | ||||
|                         <td>{{name}}</td> | ||||
|                         <td>{{value}}</td> | ||||
|                     </tr> | ||||
|                 {% endif %} | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|     </div> | ||||
| </div> | ||||
|     </table> | ||||
|     {% if library %} | ||||
|         <h3>{{library|count}} Items</h3> | ||||
|     {% endif %} | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col-lg"> | ||||
|         <h4>Users</h4> | ||||
|         <table class="table table-sm"> | ||||
|             <tr> | ||||
|                 <th>Name</th> | ||||
|                 <th>Last Login</th> | ||||
|                 <th>Last Active</th> | ||||
|                 <th>Bandwidth Limit</th> | ||||
|             </tr> | ||||
|             {% for user in jellyfin.users|sort(attribute="LastLoginDate",reverse=True) %} | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/useredit.html?userId={{user.Id}}"> | ||||
|                             {{user.Name}} | ||||
|                         </a> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                     {% if "LastLoginDate" in user %} | ||||
|                             {{user.LastLoginDate|fromiso|ago_dt_utc(2)}} ago | ||||
|                     {% else %} | ||||
|                         Never | ||||
|                     {% endif %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                     {% if "LastActivityDate" in user %} | ||||
|                             {{user.LastActivityDate|fromiso|ago_dt_utc(2)}} ago | ||||
|                     {% else %} | ||||
|                         Never | ||||
|                     {% endif %} | ||||
|                     </td> | ||||
|                     <td>{{user.Policy.RemoteClientBitrateLimit|filesizeformat(binary=False)}}/s</td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| {% endblock %} | ||||
|     {% set tabs = [] %} | ||||
|     {% for title,group in library.values()|groupby("Type") %} | ||||
|         {% do tabs.append((title,[make_table(group)])) %} | ||||
|     {% endfor %} | ||||
|     {{make_tabs(tabs)}} | ||||
| {% endblock %} | ||||
|  |  | |||
							
								
								
									
										56
									
								
								templates/jellyfin/movie.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								templates/jellyfin/movie.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| {% from 'bootstrap/form.html' import render_form, render_field, render_form_row %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
| 
 | ||||
| <h1><a href={{info.LocalAddress}}>Jellyfin</a> v{{info.Version}}</h1> | ||||
| {% if status.HasUpdateAvailable %} | ||||
|     <h3>Update available</h3> | ||||
| {% endif %} | ||||
| {% if status.HasPendingRestart %} | ||||
|     <h3>Restart pending</h3> | ||||
| {% endif %} | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         {% for ext in item.ExternalUrls %} | ||||
|             <a href={{ext.Url}}><span class="badge badge-secondary">{{ext.Name}}</span></a> | ||||
|         {% endfor %} | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <h2 title="{{item.Id}}"> | ||||
| {{item.Name}} | ||||
| {% if item.IsHD %} | ||||
| <span class="badge badge-primary">HD</span> | ||||
| {% endif %} | ||||
| </h2> | ||||
| <p>{{item.Overview}}</p> | ||||
| 
 | ||||
| <hr> | ||||
| 
 | ||||
| {#  <img src={{info.LocalAddress}}/Items/{{item.Id}}/Images/Primary>  #} | ||||
| 
 | ||||
| {% set data = [ | ||||
|     ("Path", item.Path), | ||||
|     ("Genres", item.Genres|join(", ")), | ||||
| ] %} | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         <table class="table table-sm table-bordered"> | ||||
|         {% for k,v in data %} | ||||
|             <tr> | ||||
|                 <td>{{k}}</td> | ||||
|                 <td>{{v}}</td> | ||||
|             </tr> | ||||
|         {% endfor %} | ||||
|         </table> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <pre>{{item|pformat}}</pre> | ||||
| 
 | ||||
| {% endblock %} | ||||
							
								
								
									
										70
									
								
								templates/jellyfin/series.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								templates/jellyfin/series.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| {% from 'bootstrap/form.html' import render_form, render_field, render_form_row %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
| 
 | ||||
| <h1><a href={{info.LocalAddress}}>Jellyfin</a> v{{info.Version}}</h1> | ||||
| {% if status.HasUpdateAvailable %} | ||||
|     <h3>Update available</h3> | ||||
| {% endif %} | ||||
| {% if status.HasPendingRestart %} | ||||
|     <h3>Restart pending</h3> | ||||
| {% endif %} | ||||
| 
 | ||||
| <h2 title="{{item.Id}}"><a href="{{info.LocalAddress}}/web/index.html#!/details?id={{item.Id}}">{{item.Name}}</a></h2> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         {% for ext in item.ExternalUrls %} | ||||
|             <a href={{ext.Url}}><span class="badge badge-secondary">{{ext.Name}}</span></a> | ||||
|         {% endfor %} | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div class="text-center"> | ||||
|     <img class="rounded" src={{info.LocalAddress}}/Items/{{item.Id}}/Images/Primary> | ||||
| </div> | ||||
| 
 | ||||
| <p>{{item.Overview}}</p> | ||||
| 
 | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         <table class="table table-sm table-bordered"> | ||||
|             <tr> | ||||
|                 <td>Path</td> | ||||
|                 <td>{{item.Path}}</td> | ||||
|             </tr> | ||||
|         </table> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div> | ||||
|     {% for season in item.Seasons %} | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             <h3>{{season.Name}}</h3> | ||||
|             <table class="table table-sm table-bordered"> | ||||
|             {% for episode in season.Episodes %} | ||||
|                 <tr> | ||||
|                     <td>{{episode.Name}}</td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|             </table> | ||||
|         </div> | ||||
|     </div> | ||||
|     {% endfor %} | ||||
| </div> | ||||
| 
 | ||||
| <table class="table table-sm table-bordered"> | ||||
| {% for k,v in item|flatten %} | ||||
|     <tr> | ||||
|         <td>{{k}}</td> | ||||
|         <td>{{v}}</td> | ||||
|     </tr> | ||||
| {% endfor %} | ||||
| </table> | ||||
| 
 | ||||
| {% endblock %} | ||||
							
								
								
									
										16
									
								
								templates/login.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								templates/login.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
|     <img src="{{url_for('static',filename='icon.svg')}}" class="mx-auto d-block" width=150 height=150/> | ||||
|     <div class="container" style="max-width: 30% !important;"> | ||||
|         <h2>Login</h2> | ||||
|         <form method="post" class="form"> | ||||
|             {{form.csrf_token()}} | ||||
|             {{custom_render_form_row([form.username])}} | ||||
|             {{custom_render_form_row([form.password])}} | ||||
|             {{custom_render_form_row([form.remember])}} | ||||
|             {{custom_render_form_row([form.login])}} | ||||
|         </form> | ||||
|     </div> | ||||
| {% endblock %} | ||||
|  | @ -208,9 +208,11 @@ | |||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         <h2>Trackers</h2> | ||||
|         <a href="{{url_for('qbittorent_add_trackers',infohash=qbt.info.hash)}}"> | ||||
|             <span class="badge badge-primary">Add default trackers</span> | ||||
|         </a> | ||||
|         {% if current_user.is_admin %} | ||||
|             <a href="{{url_for('qbittorrent.add_trackers',infohash=qbt.info.hash)}}"> | ||||
|                 <span class="badge badge-primary">Add default trackers</span> | ||||
|             </a> | ||||
|         {% endif %} | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
|     {% set state_label,badge_type = status_map[torrent.state] or (torrent.state,'light') %} | ||||
|      | ||||
|     <li class="list-group-item"> | ||||
|         <a href="{{url_for('qbittorrent_details',infohash=torrent.hash)}}">{{torrent.name|truncate(75)}}</a> | ||||
|         <a href="{{url_for('qbittorrent.details',infohash=torrent.hash)}}">{{torrent.name|truncate(75)}}</a> | ||||
|         (DL: {{torrent.dlspeed|filesizeformat(binary=true)}}/s, UL: {{torrent.upspeed|filesizeformat(binary=true)}}/s) | ||||
|         <span class="badge badge-{{badge_type}}">{{state_label}}</span> | ||||
|         {% if torrent.category %} | ||||
|  | @ -27,12 +27,12 @@ | |||
| 
 | ||||
| {% block app_content %} | ||||
| 
 | ||||
| <h2> | ||||
| <h1> | ||||
|     <a href="{{config.APP_CONFIG.qbt_url}}">QBittorrent</a> | ||||
|     {{qbt.version}} | ||||
|     (DL: {{qbt.server_state.dl_info_speed|filesizeformat(binary=True)}}/s, | ||||
|     UL: {{qbt.server_state.up_info_speed|filesizeformat(binary=True)}}/s) | ||||
| </h2> | ||||
| </h1> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|  | @ -99,7 +99,7 @@ | |||
|     {% set state_label,badge_type = status_map[state] or (state,'light') %} | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             <a href={{url_for("qbittorrent",state=state)}} >{{state_label}}</a> | ||||
|             <a href={{url_for("qbittorrent.index",state=state)}} >{{state_label}}</a> | ||||
|         </div> | ||||
|         <div class="col"> | ||||
|             {{torrents|length}} | ||||
|  | @ -110,7 +110,7 @@ | |||
| {% if state_filter %} | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|         <a href={{url_for("qbittorrent")}}>[Clear filter]</a> | ||||
|         <a href={{url_for("qbittorrent.index")}}>[Clear filter]</a> | ||||
|     </div> | ||||
|     <div class="col"> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -15,10 +15,10 @@ | |||
| {% endmacro %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
| <h2> | ||||
| <h1> | ||||
|     <a href="{{config.APP_CONFIG.radarr_url}}">Radarr</a> | ||||
|     v{{status.version}} ({{movies|count}} Movies) | ||||
| </h2> | ||||
| </h1> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|  |  | |||
|  | @ -6,13 +6,13 @@ | |||
| {% block app_content %} | ||||
| 
 | ||||
| <h1> | ||||
| Remote access <a href={{url_for("remote_add")}}>{{render_icon("person-plus-fill")}}</a> | ||||
| Remote access <a href={{url_for("remote.add")}}>{{render_icon("person-plus-fill")}}</a> | ||||
| </h1> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col-lg"> | ||||
|         <h4>SSH</h4> | ||||
|         <table class="table table-sm"> | ||||
|         <table class="table table-sm table-bordered"> | ||||
|             <tr> | ||||
|                 <th></th> | ||||
|                 <th>Type</th> | ||||
|  | @ -23,9 +23,9 @@ Remote access <a href={{url_for("remote_add")}}>{{render_icon("person-plus-fill" | |||
|                 <tr {{ {"class":"text-muted" if key.disabled else none}|xmlattr }}> | ||||
|                     <td> | ||||
|                         {% if key.disabled %} | ||||
|                             <a href="{{url_for("remote",enabled=True,key=key.key)}}">{{render_icon("person-x-fill",color='danger')}}</a> | ||||
|                             <a href="{{url_for("remote.index",enabled=True,key=key.key)}}">{{render_icon("person-x-fill",color='danger')}}</a> | ||||
|                         {% else %} | ||||
|                             <a href="{{url_for("remote",enabled=False,key=key.key)}}">{{render_icon("person-check-fill",color='success')}}</a> | ||||
|                             <a href="{{url_for("remote.index",enabled=False,key=key.key)}}">{{render_icon("person-check-fill",color='success')}}</a> | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                     <td>{{key.type}}</td> | ||||
|  | @ -37,17 +37,99 @@ Remote access <a href={{url_for("remote_add")}}>{{render_icon("person-plus-fill" | |||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col-lg"> | ||||
|         <h4>Active Streams</h4> | ||||
|         <table class="table table-sm table-bordered"> | ||||
|             <tr> | ||||
|                 <th>Episode</th> | ||||
|                 <th>Show</th> | ||||
|                 <th>Language</th> | ||||
|                 <th>User</th> | ||||
|                 <th>Device</th> | ||||
|                 <th>Mode</th> | ||||
|             </tr> | ||||
|             {% for session in jellyfin.sessions %} | ||||
|                 {% if "NowPlayingItem" in session %} | ||||
|                     {% with np=session.NowPlayingItem, ps=session.PlayState%} | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             {% if session.SupportsMediaControl %} | ||||
|                             <a href="{{url_for('remote.stop',session=session.Id)}}"> | ||||
|                                 {{render_icon("stop-circle")}} | ||||
|                             </a> | ||||
|                             {% endif %} | ||||
|                             <a title="{{ps.MediaSourceId}}" href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.Id}}"> | ||||
|                                 {{np.Name}} | ||||
|                             </a> | ||||
|                             ({{(ps.PositionTicks/10_000_000)|timedelta(digits=0)}}/{{(np.RunTimeTicks/10_000_000)|timedelta(digits=0)}}) | ||||
|                             {% if ps.IsPaused %} | ||||
|                                 (Paused) | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <a href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.SeriesId}}"> | ||||
|                                 {{np.SeriesName}} | ||||
|                             </a> | ||||
|                             <a href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{np.SeasonId}}"> | ||||
|                                 ({{np.SeasonName}}) | ||||
|                             </a> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             {% if ("AudioStreamIndex" in ps) and ("SubtitleStreamIndex" in ps) %} | ||||
|                                 {% if ps.AudioStreamIndex == -1 %} | ||||
|                                     {% set audio_lang = "-" %} | ||||
|                                 {% else %} | ||||
|                                     {% set audio_lang = np.MediaStreams[ps.AudioStreamIndex].Language or "?" %} | ||||
|                                 {% endif %} | ||||
|                                 {% if ps.SubtitleStreamIndex == -1 %} | ||||
|                                     {% set subtitle_lang = "-" %} | ||||
|                                 {% else %} | ||||
|                                     {% set subtitle_lang = np.MediaStreams[ps.AudioStreamIndex].Language or "?" %} | ||||
|                                 {% endif %} | ||||
|                                 {{audio_lang}}/{{subtitle_lang}} | ||||
|                             {% else %} | ||||
|                                 ?/? | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <a href="{{cfg().jellyfin_url}}web/index.html#!/useredit.html?userId={{session.UserId}}"> | ||||
|                                 {{session.UserName}} | ||||
|                             </a> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             {{session.DeviceName}} | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             {% if ps.PlayMethod =="Transcode" %} | ||||
|                                 <p title="{{session.TranscodingInfo.Bitrate|filesizeformat(binary=False)}}/s | {{session.TranscodingInfo.CompletionPercentage|round(2)}}%"> | ||||
|                                     {{ps.PlayMethod}} | ||||
|                                 </p> | ||||
|                             {% else %} | ||||
|                             <p> | ||||
|                                 {{ps.PlayMethod}} | ||||
|                             </p> | ||||
|                             {% endif %} | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                     {% endwith %} | ||||
|                 {% endif %} | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col-lg"> | ||||
|         <h4><a href="{{cfg().jellyfin_url}}web/index.html#!/userprofiles.html">Jellyfin</a></h4> | ||||
|         <table class="table table-sm"> | ||||
|         <table class="table table-sm table-bordered"> | ||||
|             <tr> | ||||
|                 <th>Name</th> | ||||
|                 <th>Last Login</th> | ||||
|                 <th>Last Active</th> | ||||
|                 <th>Bandwidth Limit</th> | ||||
|             </tr> | ||||
|             {% for user in jf|sort(attribute="LastLoginDate",reverse=True) %} | ||||
|             {% for user in jellyfin.users|defaultattr("LastLoginDate","")|sort(attribute="LastLoginDate",reverse=True) %} | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <a href="{{cfg().jellyfin_url}}web/index.html#!/useredit.html?userId={{user.Id}}"> | ||||
|  | @ -55,20 +137,26 @@ Remote access <a href={{url_for("remote_add")}}>{{render_icon("person-plus-fill" | |||
|                         </a> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                     {% if "LastLoginDate" in user %} | ||||
|                     {% if user.LastLoginDate %} | ||||
|                             {{user.LastLoginDate|fromiso|ago_dt_utc(2)}} ago | ||||
|                     {% else %} | ||||
|                         Never | ||||
|                     {% endif %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                     {% if "LastActivityDate" in user %} | ||||
|                     {% if user.LastActivityDate %} | ||||
|                             {{user.LastActivityDate|fromiso|ago_dt_utc(2)}} ago | ||||
|                     {% else %} | ||||
|                         Never | ||||
|                     {% endif %} | ||||
|                     </td> | ||||
|                     <td>{{user.Policy.RemoteClientBitrateLimit|filesizeformat(binary=False)}}/s</td> | ||||
|                     <td> | ||||
|                         {% if user.Policy.RemoteClientBitrateLimit!=0 %} | ||||
|                             {{user.Policy.RemoteClientBitrateLimit|filesizeformat(binary=False)}}/s | ||||
|                         {% else %} | ||||
|                             None | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|  |  | |||
							
								
								
									
										54
									
								
								templates/requests/details.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								templates/requests/details.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
|     <h1>Request details</h1> | ||||
|     {% set data = request.data|fromjson%} | ||||
|     <div class="row"> | ||||
|         <div class="col"> | ||||
|             {% set label = {True:"Approved",False:"Declined",None:"Pending"}[request.approved] %} | ||||
|             {% set class = {True:"bg-success",False:"bg-danger", None: ""}[request.approved] %} | ||||
|             {% if request.approved and jellyfin_id %} | ||||
|             {% set label = "Approved and Downloaded" %} | ||||
|             {% endif %} | ||||
|             {% if data.tvdbId %} | ||||
|                 {% set link="https://www.thetvdb.com/?tab=series&id=%s"|format(data.tvdbId) %} | ||||
|             {% elif data.imdbId %} | ||||
|                 {% set link="https://www.imdb.com/title/%s"|format(data.imdbId) %} | ||||
|             {% endif %} | ||||
|             <p><b>Title</b>: <a href="{{link}}">{{data.title}}</a> ({{data.year}})</p> | ||||
|             <p><b>Type</b>: {{{"sonarr":"TV Show","radarr":"Movie"}.get(request.request_type,"Unknown")}}</p> | ||||
|             <p><b>Added</b>: {{request.added_date|ago_dt(0)}} ago</p> | ||||
|             <p><b>Status</b>: <span class="{{class}}">{{label}}</span></p> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div> | ||||
|         <p>{{data.overview}}</p> | ||||
|         {% if jellyfin_id %} | ||||
|                 <a class="btn btn-success" href="{{cfg().jellyfin_url}}web/index.html#!/details?id={{jellyfin_id}}">Open in Jellyfin</a> | ||||
|         {% endif %} | ||||
|     </div> | ||||
|     {% set downloads = (request.downloads|list) %} | ||||
|     {% if downloads %} | ||||
|         <h3>Downloads</h3> | ||||
|         <table class="table table-sm"> | ||||
|             <tr> | ||||
|                 <th>Name</th> | ||||
|                 <th>Quality</th> | ||||
|                 <th>Progress</th> | ||||
|             </tr> | ||||
|         {% for download in downloads %} | ||||
|             {% set torrent = download.download.info %} | ||||
|             {% set dl_rate = torrent.downloaded / torrent.time_active %} | ||||
|             {% set eta_act = [0, (torrent.size - torrent.downloaded) / dl_rate]|max %} | ||||
|             <tr> | ||||
|                 <td><a href="{{url_for('requests.download_details',request_id=request.id,download_id=torrent.hash)}}">{{download.title}}</a></td> | ||||
|                 <td>{{download.quality.quality.name}}</td> | ||||
|                 <td> | ||||
|                     {{(torrent.progress*100)|round(2)}} % (ETA: {{[torrent.eta,eta_act]|min|round(0)|timedelta(clamp=true)}}) | ||||
|                 </td> | ||||
|             </tr> | ||||
|         {% endfor %} | ||||
|         </table> | ||||
|     {% endif %} | ||||
| {% endblock %} | ||||
							
								
								
									
										116
									
								
								templates/requests/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								templates/requests/index.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,116 @@ | |||
| {% extends "base.html" %} | ||||
| {% from 'utils.html' import custom_render_form_row,make_tabs %} | ||||
| {% from 'bootstrap/utils.html' import render_icon %} | ||||
| {% from 'bootstrap/form.html' import render_form, render_field, render_form_row %} | ||||
| 
 | ||||
| {% macro search_tab() %} | ||||
|     <form method="post" enctype="multipart/form-data"> | ||||
|         {{ form.csrf_token() }} | ||||
|         {{ custom_render_form_row([form.query],render_args={'form_type':'horizontal','horizontal_columns':('lg',1,6)}) }} | ||||
|         {{ custom_render_form_row([form.search_type],render_args={'form_type':'horizontal','horizontal_columns':('lg',1,6)}) }} | ||||
|         {{ custom_render_form_row([form.search]) }} | ||||
|     </form> | ||||
|     {% if results %} | ||||
|     <form method="post"> | ||||
|         {{ form.csrf_token() }} | ||||
|         {% if search_type %} | ||||
|             <input type="hidden" name="search_type" value="{{search_type}}"> | ||||
|         {% endif %} | ||||
|         <table class="table table-sm table-bordered mt-3"> | ||||
|             <tr> | ||||
|                 <th>Title</th> | ||||
|                 <th>In Cinemas</th> | ||||
|                 <th>Digital Release</th> | ||||
|             </tr> | ||||
|             {% for result in results %} | ||||
|                 {% if result.tvdbId %} | ||||
|                     {% set link="https://www.thetvdb.com/?tab=series&id=%s"|format(result.tvdbId) %} | ||||
|                 {% elif result.imdbId %} | ||||
|                     {% set link="https://www.imdb.com/title/%s"|format(result.imdbId) %} | ||||
|                 {% endif %} | ||||
|                 {% if result.path %} | ||||
|                     {% set style="background-color: darkgreen !important;" %} | ||||
|                 {% else %} | ||||
|                     {% set style="" %} | ||||
|                 {% endif %} | ||||
|                 <tr style="{{style}}"> | ||||
|                     <td> | ||||
|                         {% if result.path %} | ||||
|                             <input type="checkbox" disabled> | ||||
|                         {% else %} | ||||
|                             <input type="checkbox" name="selected[]" value="{{result|tojson|base64}}"> | ||||
|                         {% endif %} | ||||
|                         <a href="{{link}}">{{result.title}}</a> ({{result.year}}) | ||||
|                     </td> | ||||
|                     <td> | ||||
|                     {% if result.inCinemas %} | ||||
|                         {{result.inCinemas|fromiso}} | ||||
|                     {% else %} | ||||
|                         None | ||||
|                     {% endif %} | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         {% if result.digitalRelease %} | ||||
|                             {{result.digitalRelease|fromiso}} | ||||
|                         {% else %} | ||||
|                             None | ||||
|                         {% endif %} | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|         <button class="btn btn-success" type="submit">Submit Request</button> | ||||
|     </form> | ||||
|     {% endif %} | ||||
| {% endmacro %} | ||||
| 
 | ||||
| {% macro request_queue() %} | ||||
|     <form method="post"> | ||||
|         {{ form.csrf_token() }} | ||||
|         <table class="table table-sm table-bordered mt-3"> | ||||
|             <tr> | ||||
|                 <th>Title</th> | ||||
|                 <th>Requested at</th> | ||||
|                 {% if current_user.is_admin %} | ||||
|                     <th>Requested by</th> | ||||
|                 {% endif %} | ||||
|             </tr> | ||||
|             {% for request in requests %} | ||||
|                 {% set data = (request.data|fromjson) %} | ||||
|                 {% if request.approved==True %} | ||||
|                     <tr class="bg-success"> | ||||
|                 {% elif request.approved==False %} | ||||
|                     <tr class="bg-danger"> | ||||
|                 {%  else %} | ||||
|                     <tr class=""> | ||||
|                 {% endif %} | ||||
|                         <td> | ||||
|                             {% if current_user.is_admin and request.approved!=True %} | ||||
|                                 <input type="checkbox" name="selected[]" value="{{request.item_id}}"> | ||||
|                             {% endif %} | ||||
|                             <a href="{{url_for('requests.details',request_id=request.id)}}" style="color: #eee; text-decoration: underline;">{{data.title}}</a> ({{data.year}}) | ||||
|                         </td> | ||||
|                         <td>{{request.added_date}}</td> | ||||
|                         {% if current_user.is_admin %} | ||||
|                             <td>{{request.users|join(", ",attribute="user_name")}}</td> | ||||
|                         {% endif %} | ||||
|                     </tr> | ||||
|             {% endfor %} | ||||
|         </table> | ||||
|         {% if current_user.is_admin %} | ||||
|             <button name="approve" value="approve" class="btn btn-success" type="submit">Approve</button> | ||||
|             <button name="decline" value="decline" class="btn btn-danger" type="submit">Decline</button> | ||||
|         {% endif %} | ||||
|     </form> | ||||
| {% endmacro %} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| {% block app_content %} | ||||
|     <h1>Requests</h1> | ||||
|     {% set requests_tabs = [ | ||||
|         ('Queue',request_queue()), | ||||
|         ('Search',search_tab()), | ||||
|     ] %} | ||||
|     {{ make_tabs(requests_tabs) }} | ||||
| {% endblock %} | ||||
|  | @ -2,7 +2,7 @@ | |||
| {% macro tv_show_results(results) -%} | ||||
|     <div class="d-flex flex-wrap"> | ||||
|     {% for result in results %} | ||||
|         <form action="search/details" method="POST"> | ||||
|         <form action="details" method="POST"> | ||||
|             <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> | ||||
|             <input type="hidden" name="type" value="show"/> | ||||
|             <input type="hidden" name="data" value="{{result|tojson|urlencode}}" /> | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ | |||
|             <div class="alert alert-success alert-dismissible fade show" role="alert"> | ||||
|             {% for torrent in session.pop('new_torrents',{}).values() %} | ||||
|                 <p> | ||||
|                     Added <a class="alert-link" href="{{url_for('qbittorrent',infohash=torrent.hash)}}">{{torrent.name}}</a> | ||||
|                     Added <a class="alert-link" href="{{url_for('qbittorrent.details',infohash=torrent.hash)}}">{{torrent.name}}</a> | ||||
|                 </p> | ||||
|             {% endfor %} | ||||
|             </div> | ||||
|  |  | |||
|  | @ -15,10 +15,10 @@ | |||
| {% endmacro %} | ||||
| 
 | ||||
| {% block app_content %} | ||||
| <h2> | ||||
| <h1> | ||||
|     <a href="{{config.APP_CONFIG.sonarr_url}}">Sonarr</a> | ||||
|     v{{status.version}} ({{series|count}} Shows) | ||||
| </h2> | ||||
| </h1> | ||||
| 
 | ||||
| <div class="row"> | ||||
|     <div class="col"> | ||||
|  |  | |||
|  | @ -22,13 +22,15 @@ | |||
|         <div class="col-lg"> | ||||
|             <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist"> | ||||
|             {% for label,tab in tabs if tab %} | ||||
|                 {% set id_name = [loop.index,tabs_id ]|join("-") %} | ||||
|                 {% if not (loop.first and loop.last) %} | ||||
|                     <li class="nav-item"> | ||||
|                         <a class="nav-link {{'active' if loop.first}}" id="nav-{{id_name}}-tab" data-toggle="pill" href="#pills-{{id_name}}" role="tab" aria-controls="pills-{{id_name}}" aria-selected="{{loop.first}}"> | ||||
|                             {{label}} | ||||
|                         </a> | ||||
|                     </li> | ||||
|                 {% if tab %} | ||||
|                     {% set id_name = [loop.index,tabs_id ]|join("-") %} | ||||
|                     {% if not (loop.first and loop.last) %} | ||||
|                         <li class="nav-item"> | ||||
|                             <a class="nav-link {{'active' if loop.first}}" id="nav-{{id_name}}-tab" data-toggle="pill" href="#pills-{{id_name}}" role="tab" aria-controls="pills-{{id_name}}" aria-selected="{{loop.first}}"> | ||||
|                                 {{label}} | ||||
|                             </a> | ||||
|                         </li> | ||||
|                     {% endif %} | ||||
|                 {% endif %} | ||||
|             {% endfor %} | ||||
|             </ul> | ||||
|  | @ -38,10 +40,12 @@ | |||
|         <div class="col-lg"> | ||||
|             <div class="tab-content" id="searchResults"> | ||||
|                 {% for label,tab in tabs if tab %} | ||||
|                     {% set id_name = [loop.index,tabs_id ]|join("-") %} | ||||
|                     <div class="tab-pane fade {{'show active' if loop.first}}" id="pills-{{id_name}}" role="tabpanel" aria-labelledby="nav-{{id_name}}-tab"> | ||||
|                         {{ tab|safe }} | ||||
|                     </div> | ||||
|                     {% if tab %} | ||||
|                         {% set id_name = [loop.index,tabs_id ]|join("-") %} | ||||
|                         <div class="tab-pane fade {{'show active' if loop.first}}" id="pills-{{id_name}}" role="tabpanel" aria-labelledby="nav-{{id_name}}-tab"> | ||||
|                             {{ tab|safe }} | ||||
|                         </div> | ||||
|                     {% endif %} | ||||
|                 {% endfor %} | ||||
|             </div> | ||||
|         </div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue