Added Youtube module with youtube search. Fixed module template.tags/3.0.0
@@ -7,10 +7,12 @@ | |||
{
 | |||
public override void Initialize()
 | |||
{
 | |||
Bot.CommandReceivedEvent += HandleCommandEvent;
 | |||
} 
 | |||

 | |||
public override void ParseCommand(CommandMessage command)
 | |||
{
 | |||
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command));
 | |||
}
 | |||
}
 | |||
}</s:String> | |||
@@ -24,10 +26,10 @@ | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">getFileNameWithoutExtension()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary> |
@@ -45,6 +45,15 @@ | |||
<WarningLevel>4</WarningLevel> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Reference Include="Google.GData.Client"> | |||
<HintPath>..\packages\Google.GData.Client.2.2.0.0\lib\Google.GData.Client.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Google.GData.Extensions"> | |||
<HintPath>..\packages\Google.GData.Extensions.2.2.0.0\lib\Google.GData.Extensions.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Google.GData.YouTube"> | |||
<HintPath>..\packages\Google.GData.YouTube.2.2.0.0\lib\Google.GData.YouTube.dll</HintPath> | |||
</Reference> | |||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<SpecificVersion>False</SpecificVersion> | |||
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath> | |||
@@ -73,8 +82,10 @@ | |||
<Compile Include="Modules\ModuleClasses\Invite.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Moderation.cs" /> | |||
<Compile Include="Modules\ModuleClasses\PingMe.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Search.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Version.cs" /> | |||
<Compile Include="Modules\ModuleClasses\Weather.cs" /> | |||
<Compile Include="Modules\ModuleClasses\YouTube.cs" /> | |||
<Compile Include="Modules\Option.cs" /> | |||
<Compile Include="Types.cs" /> | |||
<Compile Include="Methods.cs" /> | |||
@@ -86,6 +97,7 @@ | |||
<WCFMetadata Include="Service References\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="app.config" /> | |||
<None Include="packages.config" /> | |||
</ItemGroup> | |||
<ItemGroup> |
@@ -0,0 +1,131 @@ | |||
using System; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Text; | |||
using Google.GData.Client; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
namespace Combot.Modules.ModuleClasses | |||
{ | |||
public class Search : Module | |||
{ | |||
public override void Initialize() | |||
{ | |||
Bot.CommandReceivedEvent += HandleCommandEvent; | |||
} | |||
public override void ParseCommand(CommandMessage command) | |||
{ | |||
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command)); | |||
switch (foundCommand.Name) | |||
{ | |||
case "Google": | |||
GoogleSearch(command); | |||
break; | |||
case "Bing": | |||
break; | |||
} | |||
} | |||
private void GoogleSearch(CommandMessage command) | |||
{ | |||
string urlTemplate = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&safe=off&q={0}"; | |||
Uri searchUrl = new Uri(string.Format(urlTemplate, command.Arguments["Query"])); | |||
WebClient web = new WebClient(); | |||
web.Encoding = Encoding.UTF8; | |||
string page = web.DownloadString(searchUrl); | |||
JObject parsed = (JObject) JsonConvert.DeserializeObject(page); | |||
int responseCode = parsed.Value<int>("responseStatus"); | |||
if (responseCode < 300 && responseCode >= 200) | |||
{ | |||
if (parsed["responseData"]["results"].Any()) | |||
{ | |||
var result = parsed["responseData"]["results"][0]; | |||
string url = result.Value<string>("unescapedUrl"); | |||
string title = HttpUtility.UrlDecode(StripTagsCharArray(result.Value<string>("titleNoFormatting"))); | |||
string content = HttpUtility.UrlDecode(StripTagsCharArray(result.Value<string>("content"))); | |||
string resultMessage = string.Format("[{0}] \u0002{1}\u000F: {2}.", url, title, content); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, resultMessage); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, resultMessage); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, resultMessage); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
string noResults = string.Format("No results found for \u0002{0}\u000F.", command.Arguments["Query"]); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, noResults); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, noResults); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, noResults); | |||
break; | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
string errorCode = string.Format("Unable to search for \u0002{0}\u000F. Google returned status code \u0002{1}\u000F.", command.Arguments["Query"], responseCode); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, errorCode); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, errorCode); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, errorCode); | |||
break; | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// Remove HTML tags from string using char array. | |||
/// </summary> | |||
public static string StripTagsCharArray(string source) | |||
{ | |||
char[] array = new char[source.Length]; | |||
int arrayIndex = 0; | |||
bool inside = false; | |||
for (int i = 0; i < source.Length; i++) | |||
{ | |||
char let = source[i]; | |||
if (let == '<') | |||
{ | |||
inside = true; | |||
continue; | |||
} | |||
if (let == '>') | |||
{ | |||
inside = false; | |||
continue; | |||
} | |||
if (!inside) | |||
{ | |||
array[arrayIndex] = let; | |||
arrayIndex++; | |||
} | |||
} | |||
return new string(array, 0, arrayIndex); | |||
} | |||
} | |||
} |
@@ -0,0 +1,124 @@ | |||
using System; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Text; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
namespace Combot.Modules.ModuleClasses | |||
{ | |||
public class YouTube : Module | |||
{ | |||
public override void Initialize() | |||
{ | |||
Bot.CommandReceivedEvent += HandleCommandEvent; | |||
} | |||
public override void ParseCommand(CommandMessage command) | |||
{ | |||
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command)); | |||
switch (foundCommand.Name) | |||
{ | |||
case "YouTube Search": | |||
YoutubeSearch(command); | |||
break; | |||
} | |||
} | |||
private void YoutubeSearch(CommandMessage command) | |||
{ | |||
string urlTemplate = "http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&max-results=1&q={0}"; | |||
Uri searchUrl = new Uri(string.Format(urlTemplate, command.Arguments["Query"])); | |||
WebClient web = new WebClient(); | |||
web.Encoding = Encoding.UTF8; | |||
string page = web.DownloadString(searchUrl); | |||
JObject parsed = (JObject)JsonConvert.DeserializeObject(page); | |||
if (parsed["data"]["totalItems"].Value<int>() > 0) | |||
{ | |||
string videoID = parsed["data"]["items"].First().Value<string>("id"); | |||
string vidDescription = GetYoutubeDescription(videoID); | |||
string youtubeMessage = string.Format("{0} - {1}.", vidDescription, string.Format("http://youtu.be/{0}", videoID)); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, youtubeMessage); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, youtubeMessage); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, youtubeMessage); | |||
break; | |||
} | |||
} | |||
else | |||
{ | |||
string noResults = string.Format("No results found for \u0002{0}\u000F.", command.Arguments["Query"]); | |||
switch (command.MessageType) | |||
{ | |||
case MessageType.Channel: | |||
Bot.IRC.SendPrivateMessage(command.Location, noResults); | |||
break; | |||
case MessageType.Query: | |||
Bot.IRC.SendPrivateMessage(command.Nick.Nickname, noResults); | |||
break; | |||
case MessageType.Notice: | |||
Bot.IRC.SendNotice(command.Nick.Nickname, noResults); | |||
break; | |||
} | |||
} | |||
} | |||
private string GetYoutubeDescription(string ID) | |||
{ | |||
string description = string.Empty; | |||
string urlTemplate = "http://gdata.youtube.com/feeds/api/videos/{0}?v=2&alt=jsonc"; | |||
Uri searchUrl = new Uri(string.Format(urlTemplate, ID)); | |||
WebClient web = new WebClient(); | |||
web.Encoding = Encoding.UTF8; | |||
string page = web.DownloadString(searchUrl); | |||
JObject parsed = (JObject)JsonConvert.DeserializeObject(page); | |||
var data = parsed["data"]; | |||
description = string.Format("\u0002{0}\u000F", data["title"]); | |||
if (data["duration"] == null) | |||
{ | |||
return description; | |||
} | |||
TimeSpan duration = TimeSpan.FromSeconds(data["duration"].Value<double>()); | |||
description += string.Format(" | Length: \u0002{0}\u000F", duration.ToString("g")); | |||
if (data["ratingCount"] != null) | |||
{ | |||
int likes = data["likeCount"].Value<int>(); | |||
string pluralLikes = (likes > 1) ? "s" : string.Empty; | |||
int dislikes = data["ratingCount"].Value<int>() - likes; | |||
string pluralDislikes = (dislikes > 1) ? "s" : string.Empty; | |||
double percent = 100.0 * ((double)likes / data["ratingCount"].Value<int>()); | |||
description += string.Format(" | Rating: {0} Like{1}, {2} Dislike{3} (\u0002{4}\u000F%)", likes, pluralLikes, dislikes, pluralDislikes, Math.Round(percent, 1)); | |||
} | |||
if (data["viewCount"] != null) | |||
{ | |||
description += string.Format(" | Views: \u0002{0}\u000F", data["viewCount"].Value<int>()); | |||
} | |||
DateTime uploadDate = Convert.ToDateTime(data["uploaded"].Value<string>()); | |||
description += string.Format(" | Uploaded By: \u0002{0}\u000F on \u0002{1}\u000F", data["uploader"].Value<string>(), uploadDate.ToString("R")); | |||
if (data["contentRating"] != null) | |||
{ | |||
description += " | \u0002NSFW\u000F"; | |||
} | |||
return description; | |||
} | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<runtime> | |||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||
<dependentAssembly> | |||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> | |||
</dependentAssembly> | |||
</assemblyBinding> | |||
</runtime> | |||
</configuration> |
@@ -1,4 +1,7 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Google.GData.Client" version="2.2.0.0" targetFramework="net451" /> | |||
<package id="Google.GData.Extensions" version="2.2.0.0" targetFramework="net451" /> | |||
<package id="Google.GData.YouTube" version="2.2.0.0" targetFramework="net451" /> | |||
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net451" /> | |||
</packages> |
@@ -1,6 +1,14 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<startup> | |||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /> | |||
</startup> | |||
<runtime> | |||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||
<dependentAssembly> | |||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" /> | |||
</dependentAssembly> | |||
</assemblyBinding> | |||
</runtime> | |||
</configuration> |
@@ -7,15 +7,18 @@ | |||
{
 | |||
public override void Initialize()
 | |||
{
 | |||
Bot.CommandReceivedEvent += HandleCommandEvent;
 | |||
} 
 | |||

 | |||
public override void ParseCommand(CommandMessage command)
 | |||
{
 | |||
Command foundCommand = Commands.Find(c => c.Triggers.Contains(command.Command));
 | |||
}
 | |||
}
 | |||
}</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Reformat/@EntryValue">True</s:Boolean> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/ShortenQualifiedReferences/@EntryValue">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Categories/=Imported_00201_002F29_002F2015/@EntryIndexedValue">Imported 1/29/2015</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=FileName/@EntryIndexedValue">NewModule</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=Extension/@EntryIndexedValue">cs</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/CustomProperties/=ValidateFileName/@EntryIndexedValue">False</s:String> | |||
@@ -23,10 +26,10 @@ | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Scope/=E8F0594528C33E45BBFEC6CFE851095D/Type/@EntryValue">InCSharpProjectFile</s:String> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">getCurrentNamespace()</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=namespace/Order/@EntryValue">0</s:Int64> | |||
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/@KeyIndexDefined">True</s:Boolean> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">fileDefaultNamespace()</s:String> | |||
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Expression/@EntryValue">getFileNameWithoutExtension()</s:String> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/InitialRange/@EntryValue">-1</s:Int64> | |||
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=25F1155BB4B75B4898E0DB901452883B/Field/=filename/Order/@EntryValue">1</s:Int64></wpf:ResourceDictionary> |