Twatter has been added, Notifications cannot be saved (yet), nor will they send, but the framework for a user to setup Twitter (Authorize NzbDrone) is in place.

This commit is contained in:
Mark McDowall 2011-10-28 00:57:00 -07:00
parent f5b5aea62d
commit a2735d7716
27 changed files with 25605 additions and 4 deletions

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NzbDrone.Core.Model.Twitter
{
public class TwitterAuthorizationModel
{
public string Token { get; set; }
public string Url { get; set; }
}
}

View File

@ -145,6 +145,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.1.9\lib\net40\MvcMiniProfiler.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.3.5.8\lib\35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Ninject, Version=2.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
<HintPath>..\packages\Ninject.2.2.1.4\lib\net40-Full\Ninject.dll</HintPath>
</Reference>
@ -172,6 +175,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libraries\TvdbLib.dll</HintPath>
</Reference>
<Reference Include="Twitterizer2">
<HintPath>..\packages\twitterizer.2.3.3\lib\35\Twitterizer2.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Constants.cs" />
@ -205,6 +211,7 @@
<Compile Include="Model\SabnzbdInfoModel.cs" />
<Compile Include="Model\Search\SearchModel.cs" />
<Compile Include="Model\Search\SearchType.cs" />
<Compile Include="Model\Twitter\TwitterAuthorizationModel.cs" />
<Compile Include="Model\UpdatePackage.cs" />
<Compile Include="Model\Xbmc\ActionType.cs" />
<Compile Include="Model\Xbmc\ActivePlayersResult.cs" />
@ -228,6 +235,7 @@
<Compile Include="Providers\QualityTypeProvider.cs" />
<Compile Include="Providers\SearchProvider.cs" />
<Compile Include="Providers\SmtpProvider.cs" />
<Compile Include="Providers\TwitterProvider.cs" />
<Compile Include="Providers\UpdateProvider.cs" />
<Compile Include="Providers\Xbmc\ResourceManager.cs" />
<Compile Include="Model\Xbmc\TvShowResult.cs" />

View File

@ -312,6 +312,18 @@ namespace NzbDrone.Core.Providers.Core
set { SetValue("SmtpToAddresses", value); }
}
public virtual string TwitterAccessToken
{
get { return GetValue("TwitterAccessToken", String.Empty); }
set { SetValue("TwitterAccessToken", value); }
}
public virtual string TwitterAccessTokenSecret
{
get { return GetValue("TwitterAccessTokenSecret", String.Empty); }
set { SetValue("TwitterAccessTokenSecret", value); }
}
private string GetValue(string key)
{
return GetValue(key, String.Empty);

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using Ninject;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Twitter;
using NzbDrone.Core.Providers.Core;
using Twitterizer;
namespace NzbDrone.Core.Providers
{
public class TwitterProvider
{
private readonly ConfigProvider _configProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private const string ConsumerKey = "umKU6jBWpFbHTuqQbW2VlQ";
private const string ConsumerSecret = "e30OXkI6qrZWS35hbUUnrQQ8J2R9XNpccQNWAVK10";
[Inject]
public TwitterProvider(ConfigProvider configProvider)
{
_configProvider = configProvider;
}
public virtual TwitterAuthorizationModel GetAuthorization()
{
try
{
OAuthTokenResponse requestToken = OAuthUtility.GetRequestToken(ConsumerKey, ConsumerSecret, "oob", null);
Uri authorizationUri = OAuthUtility.BuildAuthorizationUri(requestToken.Token);
return new TwitterAuthorizationModel
{
Token = requestToken.Token,
Url = authorizationUri.ToString()
};
}
catch (Exception ex)
{
Logger.Warn("Failed to get Twitter authorization URL.");
Logger.TraceException(ex.Message, ex);
return null;
}
}
public virtual bool GetAndSaveAccessToken(string authToken, string verifier)
{
try
{
Logger.Debug("Attempting to get the AccessToken from Twitter");
OAuthTokenResponse accessToken = OAuthUtility.GetAccessToken(ConsumerKey, ConsumerSecret, authToken, verifier);
_configProvider.TwitterAccessToken = accessToken.Token;
_configProvider.TwitterAccessTokenSecret = accessToken.TokenSecret;
//Send a tweet to test!
SendTweet("I have just setup tweet notifications for NzbDrone!");
return true;
}
catch (Exception ex)
{
Logger.TraceException(ex.Message, ex);
return false;
}
}
public virtual bool SendTweet(string message)
{
try
{
Logger.Trace("Sending status update to twitter: {0}", message);
var accessToken = _configProvider.TwitterAccessToken;
var accessTokenSecret = _configProvider.TwitterAccessTokenSecret;
//If the access token or access token secret are not configured, log an error and return
if (String.IsNullOrWhiteSpace(accessToken) || String.IsNullOrWhiteSpace(accessTokenSecret))
{
Logger.Warn("Twitter Setup is incomplete, please check your settings");
return false;
}
var token = new OAuthTokens
{
AccessToken = accessToken,
AccessTokenSecret = accessTokenSecret,
ConsumerKey = ConsumerKey,
ConsumerSecret = ConsumerSecret
};
TwitterStatus.Update(token, message + " #NzbDrone");
return true;
}
catch (Exception ex)
{
Logger.DebugException(ex.Message, ex);
return false;
}
}
}
}

View File

@ -2,7 +2,9 @@
<packages>
<package id="DotNetZip" version="1.9.1.8" />
<package id="MiniProfiler" version="1.9" />
<package id="Newtonsoft.Json" version="3.5.8" />
<package id="Ninject" version="2.2.1.4" />
<package id="NLog" version="2.0.0.2000" />
<package id="SqlServerCompact" version="4.0.8482.1" />
<package id="twitterizer" version="2.3.3" />
</packages>

View File

@ -4,6 +4,7 @@ using System.Web;
using System.Web.Mvc;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Twitter;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Jobs;
using NzbDrone.Web.Models;
@ -15,15 +16,17 @@ namespace NzbDrone.Web.Controllers
private readonly JobProvider _jobProvider;
private readonly SabProvider _sabProvider;
private readonly SmtpProvider _smtpProvider;
private readonly TwitterProvider _twitterProvider;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public CommandController(JobProvider jobProvider, SabProvider sabProvider,
SmtpProvider smtpProvider)
SmtpProvider smtpProvider, TwitterProvider twitterProvider)
{
_jobProvider = jobProvider;
_sabProvider = sabProvider;
_smtpProvider = smtpProvider;
_twitterProvider = twitterProvider;
}
public JsonResult RssSync()
@ -78,5 +81,25 @@ namespace NzbDrone.Web.Controllers
return Json(new NotificationResult { Title = "Failed", Text = "Unable to send Email, please check your settings", NotificationType = NotificationType.Error });
}
public JsonResult GetTwitterAuthorization()
{
var result = _twitterProvider.GetAuthorization();
if (result == null)
return Json(new NotificationResult { Title = "Failed", Text = "Unable to get Twitter Authorization", NotificationType = NotificationType.Error }, JsonRequestBehavior.AllowGet);
return new JsonResult { Data = result, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
public JsonResult VerifyTwitterAuthorization(string token, string verifier)
{
var result = _twitterProvider.GetAndSaveAccessToken(token, verifier);
if (!result)
return Json(new NotificationResult { Title = "Failed", Text = "Unable to verify Twitter Authorization", NotificationType = NotificationType.Error }, JsonRequestBehavior.AllowGet);
return Json(new NotificationResult { Title = "Successfully verified Twitter Authorization." }, JsonRequestBehavior.AllowGet);
}
}
}

View File

@ -97,5 +97,18 @@ namespace NzbDrone.Web.Models
[Description("Comma separated list of addresses to email")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string SmtpToAddresses { get; set; }
//Twitter
[DisplayName("Enabled")]
[Description("Enable notifications for Twitter?")]
public bool TwitterEnabled { get; set; }
[DisplayName("Notify on Grab")]
[Description("Send notification when episode is sent to SABnzbd?")]
public bool TwitterNotifyOnGrab { get; set; }
[DisplayName("Notify on Download")]
[Description("Send notification when episode is downloaded?")]
public bool TwitterNotifyOnDownload { get; set; }
}
}

View File

@ -938,6 +938,9 @@
<ItemGroup>
<Content Include="Views\Settings\Smtp.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Settings\Twitter.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -54,9 +54,13 @@
<div id="tabs">
<ul>
<li><a href="#tabs-twitter">Twitter</a></li>
<li><a href="#tabs-xbmc">XBMC</a></li>
<li><a href="#tabs-smtp">SMTP</a></li>
</ul>
<div id="tabs-twitter">
@{Html.RenderPartial("Twitter", Model);}
</div>
<div id="tabs-xbmc">
@{Html.RenderPartial("Xbmc", Model);}
</div>

View File

@ -5,7 +5,7 @@
Layout = null;
}
<div id="xbmc" class="notifier clearfix">
<div id="smtp" class="notifier clearfix">
<label class="labelClass">@Html.LabelFor(m => m.SmtpEnabled)
<span class="small">@Html.DescriptionFor(m => m.SmtpEnabled)</span>
</label>

View File

@ -0,0 +1,76 @@
@using NzbDrone.Web.Helpers
@model NzbDrone.Web.Models.NotificationSettingsModel
@{
Layout = null;
}
<div id="twitter" class="notifier clearfix">
<label class="labelClass">@Html.LabelFor(m => m.TwitterEnabled)
<span class="small">@Html.DescriptionFor(m => m.TwitterEnabled)</span>
</label>
@Html.CheckBoxFor(m => m.TwitterEnabled, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.TwitterNotifyOnGrab)
<span class="small">@Html.DescriptionFor(m => m.TwitterNotifyOnGrab)</span>
</label>
@Html.CheckBoxFor(m => m.TwitterNotifyOnGrab, new { @class = "inputClass checkClass" })
<label class="labelClass">@Html.LabelFor(m => m.TwitterNotifyOnDownload)
<span class="small">@Html.DescriptionFor(m => m.TwitterNotifyOnDownload)</span>
</label>
@Html.CheckBoxFor(m => m.TwitterNotifyOnDownload, new { @class = "inputClass checkClass" })
<label class="labelClass">Request Authorization
<span class="small">Begin Twitter authorization for NzbDrone</span>
</label>
<input type="button" onclick="requestTwitterAuthorization();" value="Requestion Authorization" class="inputClass"/>
<label class="labelClass">Verification PIN
<span class="small">PIN from Twitter to provide authorization to NzbDrone</span>
</label>
@Html.TextBox("twitterVerification", "", new { @class = "inputClass" })
<label class="labelClass">Verify & Test Authorization
<span class="small">Verify & Test Twitter authorization for NzbDrone (Send a test tweet)</span>
</label>
<input type="button" onclick="verifyTwitterAuthorization();" value="Test Authorization" class="inputClass"/>
@Html.Hidden("authorizationRequestToken")
</div>
<script type="text/javascript">
getAuthorizationUrl = '../Command/GetTwitterAuthorization';
verifyAuthorizationUrl = '../Command/VerifyTwitterAuthorization';
function requestTwitterAuthorization() {
$.ajax({
type: "GET",
url: getAuthorizationUrl,
error: function(req, status, error) {
alert("Sorry! We could get Twitter Authorization at this time. " + error);
},
success: function(data, textStatus, jqXHR) {
if (data.IsMessage)
return false;
$('#authorizationRequestToken').val(data.Token);
window.open(data.Url);
}
});
}
function verifyTwitterAuthorization() {
var token = $('#authorizationRequestToken').val();
var verifier = $('#twitterVerification').val();
$.ajax({
type: "GET",
url: verifyAuthorizationUrl,
data: jQuery.param({ token: token, verifier: verifier }),
error: function(req, status, error) {
alert("Sorry! We could verify Twitter Authorization at this time. " + error);
}
});
}
</script>

View File

@ -55,8 +55,8 @@
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,19 @@
Copyright (c) 2010, Patrick "Ricky" Smith
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
- Neither the name Twitterizer nor the names of its contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Binary file not shown.

Binary file not shown.