You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	Added toastr, fullcalendar, start of API for Calendar.
Sending headers for DownloadString and DownloadFile in addition to DownloadStream.
This commit is contained in:
		| @@ -1,5 +1,6 @@ | ||||
| using System; | ||||
| using AutoMapper; | ||||
| using NzbDrone.Api.Calendar; | ||||
| using NzbDrone.Api.QualityProfiles; | ||||
| using NzbDrone.Api.QualityType; | ||||
| using NzbDrone.Api.Resolvers; | ||||
| @@ -48,6 +49,12 @@ namespace NzbDrone.Api | ||||
|                   .ForMember(dest => dest.SeriesTitle, opt => opt.MapFrom(src => src.Series.Title)) | ||||
|                   .ForMember(dest => dest.EpisodeTitle, opt => opt.MapFrom(src => src.Title)) | ||||
|                   .ForMember(dest => dest.AirTime, opt => opt.ResolveUsing<AirTimeResolver>()); | ||||
|  | ||||
|             //Calendar | ||||
|             Mapper.CreateMap<Episode, CalendarResource>() | ||||
|                   .ForMember(dest => dest.SeriesTitle, opt => opt.MapFrom(src => src.Series.Title)) | ||||
|                   .ForMember(dest => dest.EpisodeTitle, opt => opt.MapFrom(src => src.Title)) | ||||
|                   .ForMember(dest => dest.AirTime, opt => opt.ResolveUsing<AirTimeResolver>()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										30
									
								
								NzbDrone.Api/Calendar/CalendarModule.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								NzbDrone.Api/Calendar/CalendarModule.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Globalization; | ||||
| using System.Linq; | ||||
| using AutoMapper; | ||||
| using Nancy; | ||||
| using NzbDrone.Api.Extentions; | ||||
| using NzbDrone.Core.Providers; | ||||
| using NzbDrone.Core.Tv; | ||||
|  | ||||
| namespace NzbDrone.Api.Calendar | ||||
| { | ||||
|     public class CalendarModule : NzbDroneApiModule | ||||
|     { | ||||
|         private readonly UpcomingEpisodesProvider _upcomingEpisodesProvider; | ||||
|  | ||||
|         public CalendarModule(UpcomingEpisodesProvider upcomingEpisodesProvider) | ||||
|             : base("/Calendar") | ||||
|         { | ||||
|             _upcomingEpisodesProvider = upcomingEpisodesProvider; | ||||
|             Get["/"] = x => Calendar(); | ||||
|         } | ||||
|  | ||||
|         private Response Calendar() | ||||
|         { | ||||
|             var upcoming = _upcomingEpisodesProvider.UpcomingEpisodes(); | ||||
|             return Mapper.Map<List<Episode>, List<CalendarResource>>(upcoming).AsResponse(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										20
									
								
								NzbDrone.Api/Calendar/CalendarResource.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								NzbDrone.Api/Calendar/CalendarResource.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| namespace NzbDrone.Api.Calendar | ||||
| { | ||||
|     public class CalendarResource | ||||
|     { | ||||
|         public Int32 SeriesId { get; set; } | ||||
|         public String SeriesTitle { get; set; } | ||||
|         public Int32 EpisodeId { get; set; } | ||||
|         public String EpisodeTitle { get; set; } | ||||
|         public Int32 SeasonNumber { get; set; } | ||||
|         public Int32 EpisodeNumber { get; set; } | ||||
|         public DateTime? AirTime { get; set; } | ||||
|         public Int32 Status { get; set; } | ||||
|         public String Overview { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										6
									
								
								NzbDrone.Backbone/Calendar/CalendarCollection.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								NzbDrone.Backbone/Calendar/CalendarCollection.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| define(['app', 'Calendar/CalendarModel'], function () { | ||||
|     NzbDrone.Calendar.CalendarCollection = Backbone.Collection.extend({ | ||||
|         url: NzbDrone.Constants.ApiRoot + '/calendar', | ||||
|         model: NzbDrone.Calendar.CalendarModel | ||||
|     }); | ||||
| }); | ||||
| @@ -0,0 +1 @@ | ||||
| <div id="calendar"></div> | ||||
							
								
								
									
										35
									
								
								NzbDrone.Backbone/Calendar/CalendarCollectionView.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								NzbDrone.Backbone/Calendar/CalendarCollectionView.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| define(['app', 'Calendar/CalendarItemView'], function (app) { | ||||
|     NzbDrone.Calendar.CalendarCollectionView = Backbone.Marionette.CompositeView.extend({ | ||||
|         itemView: NzbDrone.Calendar.CalendarItemView, | ||||
|         template: 'Calendar/CalendarCollectionTemplate', | ||||
|         itemViewContainer: 'table', | ||||
|  | ||||
|         ui: { | ||||
|             calendar: '#calendar' | ||||
|         }, | ||||
|  | ||||
|         initialize: function () { | ||||
|             this.collection = new NzbDrone.Calendar.CalendarCollection(); | ||||
|             this.collection.fetch(); | ||||
|             this.collection.bind('reset', this.addAll); | ||||
|         }, | ||||
|         render: function() { | ||||
|             this.ui.calendar.fullCalendar({ | ||||
|                 header: { | ||||
|                     left: 'prev,next today', | ||||
|                     center: 'title', | ||||
|                     right: 'month,basicWeek,basicDay', | ||||
|                     ignoreTimezone: false | ||||
|                 }, | ||||
|                 selectable: true, | ||||
|                 selectHelper: true, | ||||
|                 editable: true | ||||
|             }); | ||||
|     	}, | ||||
|         addAll: function(){ | ||||
|             this.el.fullCalendar('addEventSource', this.collection.toJSON()); | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										10
									
								
								NzbDrone.Backbone/Calendar/CalendarModel.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								NzbDrone.Backbone/Calendar/CalendarModel.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| define(['app'], function (app) { | ||||
|     NzbDrone.Calendar.CalendarModel = Backbone.Model.extend({ | ||||
|         mutators: { | ||||
|  | ||||
|         }, | ||||
|         defaults: { | ||||
|             status: 0 | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
| @@ -1,174 +1,157 @@ | ||||
| .toast-title | ||||
| { | ||||
| .toast-title { | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| .toast-message | ||||
| { | ||||
| .toast-message { | ||||
|     -ms-word-wrap: break-word; | ||||
|     word-wrap: break-word; | ||||
| } | ||||
|  | ||||
|     .toast-message a, | ||||
|     .toast-message label | ||||
|     { | ||||
|     .toast-message label { | ||||
|         color: #FFF; | ||||
|     } | ||||
|  | ||||
|         .toast-message a:hover | ||||
|         { | ||||
|         .toast-message a:hover { | ||||
|             color: #CCC; | ||||
|             text-decoration: none; | ||||
|         } | ||||
|  | ||||
| .toast-top-left | ||||
| { | ||||
|     left: 12px; | ||||
|     top: 12px; | ||||
|  | ||||
| .toast-top-full-width { | ||||
|     top: 0; | ||||
|     right: 0; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .toast-bottom-right | ||||
| { | ||||
|     bottom: 12px; | ||||
| .toast-bottom-full-width { | ||||
|     bottom: 0; | ||||
|     right: 0; | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .toast-top-left { | ||||
|     top: 12px; | ||||
|     left: 12px; | ||||
| } | ||||
|  | ||||
| .toast-top-right { | ||||
|     top: 12px; | ||||
|     right: 12px; | ||||
| } | ||||
|  | ||||
| .toast-bottom-left | ||||
| { | ||||
| .toast-bottom-right { | ||||
|     right: 12px; | ||||
|     bottom: 12px; | ||||
| } | ||||
|  | ||||
| .toast-bottom-left { | ||||
|     bottom: 12px; | ||||
|     left: 12px; | ||||
| } | ||||
|  | ||||
| #toast-container | ||||
| { | ||||
| #toast-container { | ||||
|     position: fixed; | ||||
|     z-index: 9999; | ||||
|     z-index: 999999; | ||||
| } | ||||
|  | ||||
|     #toast-container > div | ||||
|     { | ||||
|         background-position: 15px center; | ||||
|         background-repeat: no-repeat; | ||||
|     #toast-container > div { | ||||
|         margin: 0 0 6px; | ||||
|         padding: 15px 15px 15px 50px; | ||||
|         width: 300px; | ||||
|         -moz-border-radius: 3px 3px 3px 3px; | ||||
|         -webkit-border-radius: 3px 3px 3px 3px; | ||||
|         border-radius: 3px 3px 3px 3px; | ||||
|         background-position: 15px center; | ||||
|         background-repeat: no-repeat; | ||||
|         -moz-box-shadow: 0 0 12px #999999; | ||||
|         -webkit-box-shadow: 0 0 12px #999999; | ||||
|         box-shadow: 0 0 12px #999999; | ||||
|         color: #FFFFFF; | ||||
|         opacity: 0.8; | ||||
|         -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; | ||||
|         filter: alpha(opacity=80); | ||||
|         margin: 0 0 6px; | ||||
|         opacity: 0.8; | ||||
|         padding: 15px 15px 15px 50px; | ||||
|         width: 300px; | ||||
|     } | ||||
|  | ||||
| .toast | ||||
| { | ||||
| .toast { | ||||
|     background-color: #030303; | ||||
| } | ||||
|  | ||||
| .toast-success | ||||
| { | ||||
| .toast-success { | ||||
|     background-color: #51A351; | ||||
| } | ||||
|  | ||||
| .toast-error | ||||
| { | ||||
| .toast-error { | ||||
|     background-color: #BD362F; | ||||
| } | ||||
|  | ||||
| .toast-info | ||||
| { | ||||
| .toast-info { | ||||
|     background-color: #2F96B4; | ||||
| } | ||||
|  | ||||
| .toast-warning | ||||
| { | ||||
| .toast-warning { | ||||
|     background-color: #F89406; | ||||
| } | ||||
|  | ||||
| .toast-top-right | ||||
| { | ||||
|     right: 12px; | ||||
|     top: 12px; | ||||
| } | ||||
|  | ||||
| #toast-container > :hover | ||||
| { | ||||
| #toast-container > :hover { | ||||
|     -moz-box-shadow: 0 0 12px #000000; | ||||
|     -webkit-box-shadow: 0 0 12px #000000; | ||||
|     box-shadow: 0 0 12px #000000; | ||||
|     cursor: pointer; | ||||
|     opacity: 1; | ||||
|     -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; | ||||
|     filter: alpha(opacity=100); | ||||
|     opacity: 1; | ||||
|     cursor: pointer; | ||||
| } | ||||
|  | ||||
| #toast-container > .toast-info | ||||
| { | ||||
| #toast-container > .toast-info { | ||||
|     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; | ||||
| } | ||||
|  | ||||
| #toast-container > .toast-error | ||||
| { | ||||
| #toast-container > .toast-error { | ||||
|     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; | ||||
| } | ||||
|  | ||||
| #toast-container > .toast-success | ||||
| { | ||||
| #toast-container > .toast-success { | ||||
|     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; | ||||
| } | ||||
|  | ||||
| #toast-container > .toast-warning | ||||
| { | ||||
| #toast-container > .toast-warning { | ||||
|     background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; | ||||
| } | ||||
|  | ||||
| /*Responsive Design*/ | ||||
|  | ||||
| @media all and (max-width: 240px) | ||||
| { | ||||
|     #toast-container > div | ||||
|     { | ||||
| @media all and (max-width: 240px) { | ||||
|     #toast-container > div { | ||||
|         padding: 8px 8px 8px 50px; | ||||
|         width: 108px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media all and (min-width: 241px) and (max-width: 320px) | ||||
| { | ||||
|     #toast-container > div | ||||
|     { | ||||
| @media all and (min-width: 241px) and (max-width: 320px) { | ||||
|     #toast-container > div { | ||||
|         padding: 8px 8px 8px 50px; | ||||
|         width: 128px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media all and (min-width: 321px) and (max-width: 480px) | ||||
| { | ||||
|     #toast-container > div | ||||
|     { | ||||
| @media all and (min-width: 321px) and (max-width: 480px) { | ||||
|     #toast-container > div { | ||||
|         padding: 8px 8px 8px 50px; | ||||
|         width: 192px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media all and (min-width: 481px) and (max-width: 768px) | ||||
| { | ||||
|     #toast-container > div | ||||
|     { | ||||
| @media all and (min-width: 481px) and (max-width: 768px) { | ||||
|     #toast-container > div { | ||||
|         padding: 15px 15px 15px 50px; | ||||
|         width: 300px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @media all and (min-width: 769px) | ||||
| { | ||||
|     #toast-container > div | ||||
|     { | ||||
|         padding: 15px 15px 15px 50px; | ||||
|         width: 300px; | ||||
|     } | ||||
| } | ||||
| /* overrides */ | ||||
| #toast-container.toast-top-full-width > div, | ||||
| #toast-container.toast-bottom-full-width > div { | ||||
|     width: 100%; | ||||
|     margin: 1px 0 1px 0; | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,6 @@ | ||||
| define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView', 'Upcoming/UpcomingCollectionView', 'Shared/NotificationView', 'Shared/NotFoundView'], function (app, modalRegion) { | ||||
| define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView', | ||||
|         'Upcoming/UpcomingCollectionView', 'Calendar/CalendarCollectionView', 'Shared/NotificationView', | ||||
|         'Shared/NotFoundView'], function (app, modalRegion) { | ||||
|  | ||||
|     var controller = Backbone.Marionette.Controller.extend({ | ||||
|  | ||||
| @@ -16,6 +18,11 @@ | ||||
|             this.setTitle('Upcoming'); | ||||
|             NzbDrone.mainRegion.show(new NzbDrone.Upcoming.UpcomingCollectionView(this, action, query)); | ||||
|         }, | ||||
|          | ||||
|         calendar: function (action, query) { | ||||
|             this.setTitle('Calendar'); | ||||
|             NzbDrone.mainRegion.show(new NzbDrone.Calendar.CalendarCollectionView(this, action, query)); | ||||
|         }, | ||||
|  | ||||
|         notFound: function () { | ||||
|             this.setTitle('Not Found'); | ||||
|   | ||||
							
								
								
									
										5220
									
								
								NzbDrone.Backbone/JsLibraries/fullcalendar.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5220
									
								
								NzbDrone.Backbone/JsLibraries/fullcalendar.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										211
									
								
								NzbDrone.Backbone/JsLibraries/toastr-1.1.5.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								NzbDrone.Backbone/JsLibraries/toastr-1.1.5.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | ||||
| /* | ||||
|  * Copyright 2012 John Papa and Hans Fjällemark.   | ||||
|  * All Rights Reserved.   | ||||
|  * Use, reproduction, distribution, and modification of this code is subject to the terms and  | ||||
|  * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php | ||||
|  * | ||||
|  * Author: John Papa and Hans Fjällemark | ||||
|  * Project: https://github.com/CodeSeven/toastr | ||||
|  */ | ||||
| ; (function (define) { | ||||
|     define(['jquery'], function ($) { | ||||
|         var toastr = (function () { | ||||
|             var | ||||
|                 defaults = { | ||||
|                     tapToDismiss: true, | ||||
|                     toastClass: 'toast', | ||||
|                     containerId: 'toast-container', | ||||
|                     debug: false, | ||||
|                     fadeIn: 300, | ||||
|                     fadeOut: 1000, | ||||
|                     extendedTimeOut: 1000, | ||||
|                     iconClasses: { | ||||
|                         error: 'toast-error', | ||||
|                         info: 'toast-info', | ||||
|                         success: 'toast-success', | ||||
|                         warning: 'toast-warning' | ||||
|                     }, | ||||
|                     iconClass: 'toast-info', | ||||
|                     positionClass: 'toast-top-right', | ||||
|                     timeOut: 5000, // Set timeOut to 0 to make it sticky | ||||
|                     titleClass: 'toast-title', | ||||
|                     messageClass: 'toast-message', | ||||
|                     target: $('body') | ||||
|                 }, | ||||
|  | ||||
|                 error = function (message, title, optionsOverride) { | ||||
|                     return notify({ | ||||
|                         iconClass: getOptions().iconClasses.error, | ||||
|                         message: message, | ||||
|                         optionsOverride: optionsOverride, | ||||
|                         title: title | ||||
|                     }); | ||||
|                 }, | ||||
|  | ||||
|                 getContainer = function (options) { | ||||
|                     var $container = $('#' + options.containerId); | ||||
|                     if ($container.length) { | ||||
|                         return $container; | ||||
|                     } | ||||
|                     $container = $('<div/>') | ||||
|                         .attr('id', options.containerId) | ||||
|                         .addClass(options.positionClass); | ||||
|                     $container.appendTo($(options.target)); | ||||
|                     return $container; | ||||
|                 }, | ||||
|  | ||||
|                 getOptions = function () { | ||||
|                     return $.extend({}, defaults, toastr.options); | ||||
|                 }, | ||||
|  | ||||
|                 info = function (message, title, optionsOverride) { | ||||
|                     return notify({ | ||||
|                         iconClass: getOptions().iconClasses.info, | ||||
|                         message: message, | ||||
|                         optionsOverride: optionsOverride, | ||||
|                         title: title | ||||
|                     }); | ||||
|                 }, | ||||
|  | ||||
|                 notify = function (map) { | ||||
|                     var | ||||
|                         options = getOptions(), | ||||
|                         iconClass = map.iconClass || options.iconClass; | ||||
|  | ||||
|                     if (typeof (map.optionsOverride) !== 'undefined') { | ||||
|                         options = $.extend(options, map.optionsOverride); | ||||
|                         iconClass = map.optionsOverride.iconClass || iconClass; | ||||
|                     } | ||||
|  | ||||
|                     var | ||||
|                         intervalId = null, | ||||
|                         $container = getContainer(options), | ||||
|                         $toastElement = $('<div/>'), | ||||
|                         $titleElement = $('<div/>'), | ||||
|                         $messageElement = $('<div/>'), | ||||
|                         response = { options: options, map: map }; | ||||
|  | ||||
|                     if (map.iconClass) { | ||||
|                         $toastElement.addClass(options.toastClass).addClass(iconClass); | ||||
|                     } | ||||
|  | ||||
|                     if (map.title) { | ||||
|                         $titleElement.append(map.title).addClass(options.titleClass); | ||||
|                         $toastElement.append($titleElement); | ||||
|                     } | ||||
|  | ||||
|                     if (map.message) { | ||||
|                         $messageElement.append(map.message).addClass(options.messageClass); | ||||
|                         $toastElement.append($messageElement); | ||||
|                     } | ||||
|  | ||||
|                     var fadeAway = function () { | ||||
|                         if ($(':focus', $toastElement).length > 0) { | ||||
|                             return; | ||||
|                         } | ||||
|                         var fade = function (callback) { | ||||
|                             return $toastElement.fadeOut(options.fadeOut, callback); | ||||
|                         }; | ||||
|                         var removeToast = function () { | ||||
|                             if ($toastElement.is(':visible')) { | ||||
|                                 return; | ||||
|                             } | ||||
|                             $toastElement.remove(); | ||||
|                             if ($container.children().length === 0) { | ||||
|                                 $container.remove(); | ||||
|                             } | ||||
|                         }; | ||||
|                         fade(removeToast); | ||||
|                     }; | ||||
|                     var delayedFadeAway = function () { | ||||
|                         if (options.timeOut > 0 || options.extendedTimeOut > 0) { | ||||
|                             intervalId = setTimeout(fadeAway, options.extendedTimeOut); | ||||
|                         } | ||||
|                     }; | ||||
|                     var stickAround = function () { | ||||
|                         clearTimeout(intervalId); | ||||
|                         $toastElement.stop(true, true).fadeIn(options.fadeIn); | ||||
|                     }; | ||||
|                     $toastElement.hide(); | ||||
|                     $container.prepend($toastElement); | ||||
|                     $toastElement.fadeIn(options.fadeIn); | ||||
|                     if (options.timeOut > 0) { | ||||
|                         intervalId = setTimeout(fadeAway, options.timeOut); | ||||
|                     } | ||||
|  | ||||
|                     $toastElement.hover(stickAround, delayedFadeAway); | ||||
|                     if (!options.onclick && options.tapToDismiss) { | ||||
|                         $toastElement.click(fadeAway); | ||||
|                     } | ||||
|  | ||||
|                     if (options.onclick) { | ||||
|                         $toastElement.click(function () { | ||||
|                             options.onclick() && fadeAway(); | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     if (options.debug && console) { | ||||
|                         console.log(response); | ||||
|                     } | ||||
|                     return $toastElement; | ||||
|                 }, | ||||
|  | ||||
|                 success = function (message, title, optionsOverride) { | ||||
|                     return notify({ | ||||
|                         iconClass: getOptions().iconClasses.success, | ||||
|                         message: message, | ||||
|                         optionsOverride: optionsOverride, | ||||
|                         title: title | ||||
|                     }); | ||||
|                 }, | ||||
|  | ||||
|                 warning = function (message, title, optionsOverride) { | ||||
|                     return notify({ | ||||
|                         iconClass: getOptions().iconClasses.warning, | ||||
|                         message: message, | ||||
|                         optionsOverride: optionsOverride, | ||||
|                         title: title | ||||
|                     }); | ||||
|                 }, | ||||
|  | ||||
|                 clear = function ($toastElement) { | ||||
|                     var options = getOptions(); | ||||
|                     var $container = getContainer(); | ||||
|                     if ($toastElement && $(':focus', $toastElement).length === 0) { | ||||
|                         var removeToast = function () { | ||||
|                             if ($toastElement.is(':visible')) { | ||||
|                                 return; | ||||
|                             } | ||||
|                             $toastElement.remove(); | ||||
|                             if ($container.children().length === 0) { | ||||
|                                 $container.remove(); | ||||
|                             } | ||||
|                         }; | ||||
|                         $toastElement.fadeOut(options.fadeOut, removeToast); | ||||
|                         return; | ||||
|                     } | ||||
|                     if ($container.length) { | ||||
|                         $container.fadeOut(options.fadeOut, function () { | ||||
|                             $container.remove(); | ||||
|                         }); | ||||
|                     } | ||||
|                 }; | ||||
|             return { | ||||
|                 clear: clear, | ||||
|                 error: error, | ||||
|                 info: info, | ||||
|                 options: {}, | ||||
|                 success: success, | ||||
|                 version: '1.1.5', | ||||
|                 warning: warning | ||||
|             }; | ||||
|         })(); | ||||
|         return toastr; | ||||
|     }); | ||||
| }(typeof define === 'function' && define.amd ? define : function (deps, factory) { | ||||
|     if (typeof module !== 'undefined' && module.exports) { //Node | ||||
|         module.exports = factory(require(deps[0])); | ||||
|     } else { | ||||
|         window['toastr'] = factory(window['jQuery']); | ||||
|     } | ||||
| })); | ||||
| @@ -49,6 +49,10 @@ | ||||
|     <Content Include="AddSeries\SearchResultCollection.js" /> | ||||
|     <Content Include="AddSeries\SearchResultModel.js" /> | ||||
|     <Content Include="app.js" /> | ||||
|     <Content Include="Calendar\CalendarCollection.js" /> | ||||
|     <Content Include="Calendar\CalendarCollectionTemplate.html" /> | ||||
|     <Content Include="Calendar\CalendarCollectionView.js" /> | ||||
|     <Content Include="Calendar\CalendarModel.js" /> | ||||
|     <Content Include="Content\base.css" /> | ||||
|     <Content Include="Content\menu.css" /> | ||||
|     <Content Include="Content\fullcalendar.css" /> | ||||
| @@ -92,12 +96,14 @@ | ||||
|     <Content Include="JsLibraries\backbone.mutators.js" /> | ||||
|     <Content Include="JsLibraries\backbone.shortcuts.js" /> | ||||
|     <Content Include="JsLibraries\bootstrap.js" /> | ||||
|     <Content Include="JsLibraries\fullcalendar.js" /> | ||||
|     <Content Include="JsLibraries\handlebars.js" /> | ||||
|     <Content Include="JsLibraries\jquery.js" /> | ||||
|     <Content Include="JsLibraries\jquery.tablesorter.bootstrap.js" /> | ||||
|     <Content Include="JsLibraries\jquery.tablesorter.js" /> | ||||
|     <Content Include="JsLibraries\require.js" /> | ||||
|     <Content Include="JsLibraries\sugar.js" /> | ||||
|     <Content Include="JsLibraries\toastr-1.1.5.js" /> | ||||
|     <Content Include="JsLibraries\underscore.js" /> | ||||
|     <Content Include="Mixins\backbone.ajax.js" /> | ||||
|     <Content Include="Mixins\backbone.marionette.templates.js" /> | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
|             'series/add/:action(/:query)': 'addSeries', | ||||
|             'upcoming': 'upcoming', | ||||
|             'upcoming/index': 'upcoming', | ||||
|             'calendar': 'calendar', | ||||
|             ':whatever': 'notFound' | ||||
|         } | ||||
|     }); | ||||
|   | ||||
| @@ -39,6 +39,7 @@ define('app',  function () { | ||||
|         window.NzbDrone.Quality = {}; | ||||
|         window.NzbDrone.Shared = {}; | ||||
|         window.NzbDrone.Upcoming = {}; | ||||
|         window.NzbDrone.Calendar = {}; | ||||
|  | ||||
|         window.NzbDrone.Events = { | ||||
|             OpenModalDialog :'openModal', | ||||
|   | ||||
| @@ -12,10 +12,12 @@ namespace NzbDrone.Common | ||||
|     { | ||||
|         private readonly EnvironmentProvider _environmentProvider; | ||||
|         private static readonly Logger logger = LogManager.GetCurrentClassLogger(); | ||||
|         private readonly string _userAgent; | ||||
|  | ||||
|         public HttpProvider(EnvironmentProvider environmentProvider) | ||||
|         { | ||||
|             _environmentProvider = environmentProvider; | ||||
|             _userAgent = String.Format("NzbDrone {0}", _environmentProvider.Version); | ||||
|         } | ||||
|  | ||||
|         public HttpProvider() | ||||
| @@ -37,6 +39,7 @@ namespace NzbDrone.Common | ||||
|             try | ||||
|             { | ||||
|                 var client = new WebClient { Credentials = identity }; | ||||
|                 client.Headers.Add(HttpRequestHeader.UserAgent, _userAgent); | ||||
|                 return client.DownloadString(address); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
| @@ -49,7 +52,7 @@ namespace NzbDrone.Common | ||||
|         public virtual Stream DownloadStream(string url, NetworkCredential credential) | ||||
|         { | ||||
|             var request = (HttpWebRequest)WebRequest.Create(url); | ||||
|             request.UserAgent = String.Format("NzbDrone {0}", _environmentProvider.Version); | ||||
|             request.UserAgent = _userAgent; | ||||
|  | ||||
|             request.Credentials = credential; | ||||
|             var response = request.GetResponse(); | ||||
| @@ -71,6 +74,7 @@ namespace NzbDrone.Common | ||||
|  | ||||
|                 var stopWatch = Stopwatch.StartNew(); | ||||
|                 var webClient = new WebClient(); | ||||
|                 webClient.Headers.Add(HttpRequestHeader.UserAgent, _userAgent); | ||||
|                 webClient.DownloadFile(url, fileName); | ||||
|                 stopWatch.Stop(); | ||||
|                 logger.Trace("Downloading Completed. took {0:0}s", stopWatch.Elapsed.Seconds); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user