Skip to content
Browse files

Initial commit

  • Loading branch information...
0 parents commit 843ed82aa498993e6655002c97d87d5dc560e80e Waseem Sadiq committed Oct 7, 2011
Showing with 43,471 additions and 0 deletions.
  1. +28 −0 .gitignore
  2. +57 −0 Code/Channels/AOL/AolConfiguration.cs
  3. +187 −0 Code/Channels/AOL/Inbox2.Channels.AOL.csproj
  4. +36 −0 Code/Channels/AOL/Properties/AssemblyInfo.cs
  5. BIN Code/Channels/AOL/Resources/icon-10.png
  6. BIN Code/Channels/AOL/Resources/icon-13.png
  7. BIN Code/Channels/AOL/Resources/icon-64.png
  8. +27 −0 Code/Channels/Exchange/ChannelHelper.cs
  9. +547 −0 Code/Channels/Exchange/ExchangeClient.cs
  10. +415 −0 Code/Channels/Exchange/ExchangeClientChannel.cs
  11. +52 −0 Code/Channels/Exchange/ExchangeConfiguration.cs
  12. +23,747 −0 Code/Channels/Exchange/ExchangeWebService.cs
  13. +193 −0 Code/Channels/Exchange/Inbox2.Channels.Exchange.csproj
  14. +36 −0 Code/Channels/Exchange/Properties/AssemblyInfo.cs
  15. BIN Code/Channels/Exchange/Resources/icon-10.png
  16. BIN Code/Channels/Exchange/Resources/icon-13.png
  17. BIN Code/Channels/Exchange/Resources/icon-64.png
  18. +37 −0 Code/Channels/Facebook/ChannelHelper.cs
  19. +340 −0 Code/Channels/Facebook/FacebookClientChannel.cs
  20. +70 −0 Code/Channels/Facebook/FacebookConfiguration.cs
  21. +32 −0 Code/Channels/Facebook/FacebookProfileInfoBuilder.cs
  22. +87 −0 Code/Channels/Facebook/FacebookRedirectBuilder.cs
  23. +209 −0 Code/Channels/Facebook/Inbox2.Channels.Facebook.csproj
  24. +36 −0 Code/Channels/Facebook/Properties/AssemblyInfo.cs
  25. +18 −0 Code/Channels/Facebook/REST/DataContracts/FbAttachment.cs
  26. +14 −0 Code/Channels/Facebook/REST/DataContracts/FbAuth.cs
  27. +16 −0 Code/Channels/Facebook/REST/DataContracts/FbContact.cs
  28. +14 −0 Code/Channels/Facebook/REST/DataContracts/FbMediaType.cs
  29. +23 −0 Code/Channels/Facebook/REST/DataContracts/FbMessage.cs
  30. +14 −0 Code/Channels/Facebook/REST/DataContracts/FbMessageFolder.cs
  31. +19 −0 Code/Channels/Facebook/REST/DataContracts/FbNotifications.cs
  32. +14 −0 Code/Channels/Facebook/REST/DataContracts/FbPermissions.cs
  33. +40 −0 Code/Channels/Facebook/REST/DataContracts/FbStatus.cs
  34. +21 −0 Code/Channels/Facebook/REST/FacebookApiKeys.cs
  35. +611 −0 Code/Channels/Facebook/REST/FacebookRESTClient.cs
  36. +110 −0 Code/Channels/Facebook/REST/IFacebookClient.cs
  37. BIN Code/Channels/Facebook/Resources/icon-10.png
  38. BIN Code/Channels/Facebook/Resources/icon-13.png
  39. BIN Code/Channels/Facebook/Resources/icon-64.png
  40. +60 −0 Code/Channels/GMail/GMailConfiguration.cs
  41. +123 −0 Code/Channels/GMail/GoogleCalendarChannel.cs
  42. +132 −0 Code/Channels/GMail/GoogleContactsChannel.cs
  43. +225 −0 Code/Channels/GMail/Inbox2.Channels.GMail.csproj
  44. +36 −0 Code/Channels/GMail/Properties/AssemblyInfo.cs
  45. +25 −0 Code/Channels/GMail/RawMapper.cs
  46. BIN Code/Channels/GMail/Resources/icon-10.png
  47. BIN Code/Channels/GMail/Resources/icon-13.png
  48. BIN Code/Channels/GMail/Resources/icon-64.png
  49. +53 −0 Code/Channels/Hotmail/HotmailConfiguration.cs
  50. +171 −0 Code/Channels/Hotmail/HotmailContactsChannel.cs
  51. +200 −0 Code/Channels/Hotmail/Inbox2.Channels.Hotmail.csproj
  52. +36 −0 Code/Channels/Hotmail/Properties/AssemblyInfo.cs
  53. +18 −0 Code/Channels/Hotmail/REST/ContactsAuthentication.cs
  54. +22 −0 Code/Channels/Hotmail/REST/ILiveContacts.cs
  55. +2,304 −0 Code/Channels/Hotmail/REST/WindowsLiveLogin.cs
  56. BIN Code/Channels/Hotmail/Resources/icon-10.png
  57. BIN Code/Channels/Hotmail/Resources/icon-13.png
  58. BIN Code/Channels/Hotmail/Resources/icon-64.png
  59. +46 −0 Code/Channels/Hyves/HyvesApiRequest.cs
  60. +273 −0 Code/Channels/Hyves/HyvesClientChannel.cs
  61. +63 −0 Code/Channels/Hyves/HyvesConfiguration.cs
  62. +100 −0 Code/Channels/Hyves/HyvesRedirectBuilder.cs
  63. +183 −0 Code/Channels/Hyves/Inbox2.Channels.Hyves.csproj
  64. +36 −0 Code/Channels/Hyves/Properties/AssemblyInfo.cs
  65. BIN Code/Channels/Hyves/Resources/icon-10.png
  66. BIN Code/Channels/Hyves/Resources/icon-13.png
  67. BIN Code/Channels/Hyves/Resources/icon-64.png
  68. +55 −0 Code/Channels/Imap2/FolderHelper.cs
  69. +309 −0 Code/Channels/Imap2/Imap2ClientChannel.cs
  70. +115 −0 Code/Channels/Imap2/Imap2Connection.cs
  71. +170 −0 Code/Channels/Imap2/Inbox2.Channels.Imap2.csproj
  72. +36 −0 Code/Channels/Imap2/Properties/AssemblyInfo.cs
  73. +24 −0 Code/Channels/LinkedIn/ChannelHelper.cs
  74. +184 −0 Code/Channels/LinkedIn/Inbox2.Channels.LinkedIn.csproj
  75. +342 −0 Code/Channels/LinkedIn/LinkedInClientChannel.cs
  76. +71 −0 Code/Channels/LinkedIn/LinkedInConfiguration.cs
  77. +27 −0 Code/Channels/LinkedIn/LinkedInProfileInfoBuilder.cs
  78. +91 −0 Code/Channels/LinkedIn/LinkedInRedirectBuilder.cs
  79. +28 −0 Code/Channels/LinkedIn/LinkedInUpdateType.cs
  80. +138 −0 Code/Channels/LinkedIn/LinkedInWebRequest.cs
  81. +36 −0 Code/Channels/LinkedIn/Properties/AssemblyInfo.cs
  82. BIN Code/Channels/LinkedIn/Resources/icon-10.png
  83. BIN Code/Channels/LinkedIn/Resources/icon-13.png
  84. BIN Code/Channels/LinkedIn/Resources/icon-64.png
  85. +91 −0 Code/Channels/Other/Inbox2.Channels.Other.csproj
  86. +54 −0 Code/Channels/Other/OtherConfiguration.cs
  87. +36 −0 Code/Channels/Other/Properties/AssemblyInfo.cs
  88. BIN Code/Channels/Other/Resources/icon-10.png
  89. BIN Code/Channels/Other/Resources/icon-13.png
  90. BIN Code/Channels/Other/Resources/icon-64.png
  91. +177 −0 Code/Channels/Pop3/Inbox2.Channels.Pop3.csproj
  92. +147 −0 Code/Channels/Pop3/Pop3ClientChannel.cs
  93. +112 −0 Code/Channels/Pop3/Pop3Connection.cs
  94. +36 −0 Code/Channels/Pop3/Properties/AssemblyInfo.cs
  95. +159 −0 Code/Channels/Smtp/Inbox2.Channels.Smtp.csproj
  96. +36 −0 Code/Channels/Smtp/Properties/AssemblyInfo.cs
  97. +227 −0 Code/Channels/Smtp/SmtpClientChannel.cs
  98. +27 −0 Code/Channels/Smtp/SourceAddressExtensions.cs
  99. +28 −0 Code/Channels/Twitter/ChannelHelper.cs
  100. +210 −0 Code/Channels/Twitter/Inbox2.Channels.Twitter.csproj
  101. +36 −0 Code/Channels/Twitter/Properties/AssemblyInfo.cs
  102. BIN Code/Channels/Twitter/Resources/icon-10.png
  103. BIN Code/Channels/Twitter/Resources/icon-13.png
  104. BIN Code/Channels/Twitter/Resources/icon-64.png
  105. +299 −0 Code/Channels/Twitter/TwitterClientChannel.cs
  106. +72 −0 Code/Channels/Twitter/TwitterConfiguration.cs
  107. +27 −0 Code/Channels/Twitter/TwitterProfileInfoBuilder.cs
  108. +84 −0 Code/Channels/Twitter/TwitterRedirectBuilder.cs
  109. +158 −0 Code/Channels/Twitter/TwitterWebRequest.cs
  110. +187 −0 Code/Channels/Yahoo/Inbox2.Channels.Yahoo.csproj
  111. +36 −0 Code/Channels/Yahoo/Properties/AssemblyInfo.cs
  112. BIN Code/Channels/Yahoo/Resources/icon-10.png
  113. BIN Code/Channels/Yahoo/Resources/icon-13.png
  114. BIN Code/Channels/Yahoo/Resources/icon-64.png
  115. +58 −0 Code/Channels/Yahoo/YahooConfiguration.cs
  116. +24 −0 Code/Channels/Yammer/ChannelHelper.cs
  117. +142 −0 Code/Channels/Yammer/Inbox2.Channels.Yammer.csproj
  118. +36 −0 Code/Channels/Yammer/Properties/AssemblyInfo.cs
  119. BIN Code/Channels/Yammer/Resources/icon-10.png
  120. BIN Code/Channels/Yammer/Resources/icon-13.png
  121. BIN Code/Channels/Yammer/Resources/icon-64.png
  122. +300 −0 Code/Channels/Yammer/YammerClientChannel.cs
  123. +66 −0 Code/Channels/Yammer/YammerConfiguration.cs
  124. +24 −0 Code/Channels/Yammer/YammerContact.cs
  125. +27 −0 Code/Channels/Yammer/YammerProfileInfoBuilder.cs
  126. +81 −0 Code/Channels/Yammer/YammerRedirectBuilder.cs
  127. +112 −0 Code/Channels/Yammer/YammerWebRequest.cs
  128. +41 −0 Code/Client/AssemblyInfo.cs
  129. +36 −0 Code/Client/Inbox2/App.config
  130. +7 −0 Code/Client/Inbox2/App.xaml
  131. +272 −0 Code/Client/Inbox2/App.xaml.cs
  132. +51 −0 Code/Client/Inbox2/AppManager.cs
  133. +64 −0 Code/Client/Inbox2/Core/ClientContext.cs
  134. +82 −0 Code/Client/Inbox2/Core/Configuration/AppConfiguration.cs
  135. +31 −0 Code/Client/Inbox2/Core/Configuration/Channels/ChannelLoadHelper.cs
  136. +11 −0 Code/Client/Inbox2/Core/Configuration/Client.cs
  137. +177 −0 Code/Client/Inbox2/Core/Configuration/ClientSettings.cs
  138. +33 −0 Code/Client/Inbox2/Core/Configuration/CloudApi.cs
  139. +78 −0 Code/Client/Inbox2/Core/Configuration/DebugKeys.cs
  140. +206 −0 Code/Client/Inbox2/Core/Configuration/Inbox2.Core.Configuration.csproj
  141. +59 −0 Code/Client/Inbox2/Core/Configuration/PreChannels.cs
  142. +26 −0 Code/Client/Inbox2/Core/Configuration/ReceiveConfiguration.cs
  143. +92 −0 Code/Client/Inbox2/Core/Configuration/SerializableDictionary.cs
  144. +82 −0 Code/Client/Inbox2/Core/Configuration/SettingsManager.cs
  145. +107 −0 Code/Client/Inbox2/Core/Configuration/WindowSettings.cs
  146. +21 −0 Code/Client/Inbox2/Core/DataAccess/DatabaseUtil.cs
  147. +206 −0 Code/Client/Inbox2/Core/DataAccess/Inbox2.Core.DataAccess - x64.csproj
  148. +184 −0 Code/Client/Inbox2/Core/DataAccess/Inbox2.Core.DataAccess.csproj
  149. +60 −0 Code/Client/Inbox2/Core/DataAccess/Migrate.cs
  150. +253 −0 Code/Client/Inbox2/Core/DataAccess/Query/QueryGenerator.cs
  151. +23 −0 Code/Client/Inbox2/Core/DataAccess/Reflection/PropertyToken.cs
  152. +125 −0 Code/Client/Inbox2/Core/DataAccess/Reflection/Reflector.cs
  153. +16 −0 Code/Client/Inbox2/Core/DataAccess/Reflection/TableMap.cs
  154. +458 −0 Code/Client/Inbox2/Core/DataAccess/SQLiteDataService.cs
  155. +255 −0 Code/Client/Inbox2/Core/Inbox2.Core - x64.csproj
  156. +279 −0 Code/Client/Inbox2/Core/Inbox2.Core.csproj
  157. +32 −0 Code/Client/Inbox2/Core/LauncherCommands/AddToFavsCommand.cs
  158. +29 −0 Code/Client/Inbox2/Core/LauncherCommands/AnnotateThisFile.cs
  159. +36 −0 Code/Client/Inbox2/Core/LauncherCommands/FindAPersonCommand.cs
  160. +203 −0 Code/Client/Inbox2/Core/LauncherCommands/Inbox2.Core.LauncherCommands.csproj
  161. +31 −0 Code/Client/Inbox2/Core/LauncherCommands/MakeANoteCommand.cs
  162. +31 −0 Code/Client/Inbox2/Core/LauncherCommands/PutThisFileInMyDocuments.cs
  163. +36 −0 Code/Client/Inbox2/Core/LauncherCommands/SearchForCommand.cs
  164. +38 −0 Code/Client/Inbox2/Core/LauncherCommands/SendAMessageToCommand.cs
  165. +43 −0 Code/Client/Inbox2/Core/LauncherCommands/SendThisFileToCommand.cs
  166. +43 −0 Code/Client/Inbox2/Core/LauncherCommands/SendUrlToCommand.cs
  167. +36 −0 Code/Client/Inbox2/Core/LauncherCommands/TagThisFile.cs
  168. +198 −0 Code/Client/Inbox2/Core/Search/Inbox2.Core.Search.csproj
  169. +34 −0 Code/Client/Inbox2/Core/Search/IndexHelper.cs
  170. +157 −0 Code/Client/Inbox2/Core/Search/Indexer/Clustering.cs
  171. +52 −0 Code/Client/Inbox2/Core/Search/Indexer/WordVector.cs
  172. +18 −0 Code/Client/Inbox2/Core/Search/Reflection/PropertyToken.cs
  173. +118 −0 Code/Client/Inbox2/Core/Search/Reflection/Reflector.cs
  174. +173 −0 Code/Client/Inbox2/Core/Search/Search.cs
  175. +65 −0 Code/Client/Inbox2/Core/Search/SearchHelper.cs
  176. +26 −0 Code/Client/Inbox2/Core/Search/SearchUtil.cs
  177. +95 −0 Code/Client/Inbox2/Core/Shutdown.cs
  178. +288 −0 Code/Client/Inbox2/Core/Startup.cs
  179. +188 −0 Code/Client/Inbox2/Core/Storage/Inbox2.Core.Storage.csproj
  180. +140 −0 Code/Client/Inbox2/Core/Storage/OpenFileStorage.cs
  181. +78 −0 Code/Client/Inbox2/Core/Threading/Commands/CommandFactory.cs
  182. +233 −0 Code/Client/Inbox2/Core/Threading/Commands/SendMessageCommand.cs
  183. +91 −0 Code/Client/Inbox2/Core/Threading/Commands/SendStatusUpdateCommand.cs
  184. +57 −0 Code/Client/Inbox2/Core/Threading/Commands/SyncEntityCommand.cs
  185. +37 −0 Code/Client/Inbox2/Core/Threading/ExceptionHelper.cs
  186. +28 −0 Code/Client/Inbox2/Core/Threading/Handlers/ContactsHandler.cs
  187. +101 −0 Code/Client/Inbox2/Core/Threading/Handlers/DocumentsHandler.cs
  188. +234 −0 Code/Client/Inbox2/Core/Threading/Handlers/Matchers/ContactMatcher.cs
  189. +350 −0 Code/Client/Inbox2/Core/Threading/Handlers/Matchers/MessageMatcher.cs
  190. +192 −0 Code/Client/Inbox2/Core/Threading/Handlers/Matchers/ProfileMatcher.cs
  191. +33 −0 Code/Client/Inbox2/Core/Threading/Handlers/MessagesHandler.cs
  192. +25 −0 Code/Client/Inbox2/Core/Threading/Handlers/UserStatusHandler.cs
  193. +289 −0 Code/Client/Inbox2/Core/Threading/Inbox2.Core.Threading.csproj
  194. +185 −0 Code/Client/Inbox2/Core/Threading/ProcessingPool.cs
  195. +58 −0 Code/Client/Inbox2/Core/Threading/Repeat/Repeat.cs
  196. +37 −0 Code/Client/Inbox2/Core/Threading/Repeat/Run.cs
  197. +54 −0 Code/Client/Inbox2/Core/Threading/Repeat/ScheduledItem.cs
  198. +53 −0 Code/Client/Inbox2/Core/Threading/Repeat/ScheduledTaskRunner.cs
Sorry, we could not display the entire diff because too many files (2,394) changed.
28 .gitignore
@@ -0,0 +1,28 @@
+.bundle
+db/*.sqlite3*
+log/*.log
+*.log
+*.log.*
+tmp/**/*
+tmp/*
+doc/api
+doc/app
+*.swp
+*~
+.DS_Store
+bin/
+obj/
+debug
+*.suo
+*.resharper
+*.user
+*ReSharper*
+*ReSharper*/
+*TestResults*
+*.log
+*.log.*
+*Publish.xml
+*.sln.cache
+js.js
+app.js
+css.css
57 Code/Channels/AOL/AolConfiguration.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using Inbox2.Channels.Imap2;
+using Inbox2.Channels.Smtp;
+using Inbox2.Platform.Channels.Configuration;
+using Inbox2.Platform.Framework.Extensions;
+
+namespace Inbox2.Channels.AOL
+{
+ [Serializable]
+ [Export(typeof(ChannelConfiguration))]
+ public class AolConfiguration : ChannelConfiguration
+ {
+ public AolConfiguration()
+ {
+ InnerInputChannel = new Channel { Type = typeof(Imap2ClientChannel), Hostname = "imap.aol.com", Port = 143, IsSecured = false, MaxConcurrentConnections = 1 };
+ InnerOutputChannel = new Channel { Type = typeof(SmtpClientChannel), Hostname = "smtp.aol.com", Port = 587, IsSecured = false, MaxConcurrentConnections = 1 };
+ }
+
+ public override string DisplayName
+ {
+ get { return "AOL"; }
+ }
+
+ public override string DefaultDomain
+ {
+ get { return "aol.com"; }
+ }
+
+ public override int PreferredSortOrder
+ {
+ get { return 30; }
+ }
+
+ public override ChannelCharasteristics Charasteristics
+ {
+ get
+ {
+ var charasteristics = ChannelCharasteristics.Default;
+
+ charasteristics.SupportsReadStates = true;
+ charasteristics.CanCustomize = true;
+
+ return charasteristics;
+ }
+ }
+
+ public override ChannelConfiguration Clone()
+ {
+ return this.DeepCopy(new XmlSerializer(typeof(AolConfiguration)));
+ }
+ }
+}
187 Code/Channels/AOL/Inbox2.Channels.AOL.csproj
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E485016E-4E4E-4275-8161-975B6E621F0E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Inbox2.Channels.AOL</RootNamespace>
+ <AssemblyName>Inbox2.Channels.AOL</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\Stable Assemblies\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition, Version=2008.9.4.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\ThirdParty\MEF\System.ComponentModel.Composition.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AolConfiguration.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Platform\Channels\Inbox2.Platform.Channels.csproj">
+ <Project>{43B96CD2-D7DA-4286-A209-EE9585EF6927}</Project>
+ <Name>Inbox2.Platform.Channels</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Framework\Inbox2.Platform.Framework.csproj">
+ <Project>{FB90E43A-0E32-41D5-A7AB-83EA0D936E5E}</Project>
+ <Name>Inbox2.Platform.Framework</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Interfaces\Inbox2.Platform.Interfaces.csproj">
+ <Project>{B9CE1540-1D68-43B2-83DB-47EC21D158A6}</Project>
+ <Name>Inbox2.Platform.Interfaces</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Logging\Inbox2.Platform.Logging.csproj">
+ <Project>{6AE2A2AF-9B61-45B0-A375-666C5225A5B4}</Project>
+ <Name>Inbox2.Platform.Logging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Imap2\Inbox2.Channels.Imap2.csproj">
+ <Project>{528A7823-5CED-4E31-ABDF-E1F6F821FCFD}</Project>
+ <Name>Inbox2.Channels.Imap2</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Smtp\Inbox2.Channels.Smtp.csproj">
+ <Project>{D977B2FC-E1BE-410E-8544-8B7263AB44C6}</Project>
+ <Name>Inbox2.Channels.Smtp</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
+ <Visible>False</Visible>
+ <ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Resources\icon-10.png" />
+ <EmbeddedResource Include="Resources\icon-13.png" />
+ <EmbeddedResource Include="Resources\icon-64.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!--<Target Name="GenSerializationAssembly" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
+ <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
+ <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
+ </SGen>
+ </Target>
+ <Target Name="AfterBuild" DependsOnTargets="GenSerializationAssembly" />-->
+ <PropertyGroup>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
36 Code/Channels/AOL/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Inbox2.Channels.AOL")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Tabdeelee")]
+[assembly: AssemblyProduct("Inbox2.Channels.AOL")]
+[assembly: AssemblyCopyright("Copyright © Tabdeelee 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("63707b35-cace-49c8-8287-b0d861314556")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
BIN Code/Channels/AOL/Resources/icon-10.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Code/Channels/AOL/Resources/icon-13.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Code/Channels/AOL/Resources/icon-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 Code/Channels/Exchange/ChannelHelper.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Net;
+using ExchangeServicesWsdlClient;
+
+namespace Inbox2.Channels.Exchange
+{
+ internal static class ChannelHelper
+ {
+ internal static ExchangeServiceBinding BuildChannel(string hostname, string username, string password)
+ {
+ // First, set up the binding to Exchange Web Services.
+ ExchangeServiceBinding binding = new ExchangeServiceBinding();
+
+ Uri epUri = new Uri(hostname);
+
+ // Add prefix unless user specifies one himself
+ if (!hostname.EndsWith(".asmx", StringComparison.InvariantCultureIgnoreCase))
+ epUri = new Uri(epUri, "/EWS/Exchange.asmx");
+
+ binding.Credentials = new NetworkCredential(username, password);
+ binding.Url = epUri.ToString();
+ binding.RequestServerVersionValue = new RequestServerVersion { Version = ExchangeVersionType.Exchange2007_SP1 };
+
+ return binding;
+ }
+ }
+}
547 Code/Channels/Exchange/ExchangeClient.cs
@@ -0,0 +1,547 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using ExchangeServicesWsdlClient;
+using Inbox2.Platform.Channels.Entities;
+using Inbox2.Platform.Channels.Interfaces;
+using Inbox2.Platform.Framework.Extensions;
+using Inbox2.Platform.Framework.Interop;
+
+namespace Inbox2.Channels.Exchange
+{
+ public class ExchangeClient
+ {
+ private readonly string hostname;
+ private readonly string username;
+ private readonly string password;
+
+ public ExchangeClient(string hostname, IChannelCredentialsProvider provider)
+ {
+ var creds = provider.GetCredentials();
+
+ this.hostname = hostname;
+ this.username = creds.Claim;
+ this.password = creds.Evidence;
+ }
+
+ public ExchangeClient(string hostname, string username, string password)
+ {
+ this.hostname = hostname;
+ this.username = username;
+ this.password = password;
+ }
+
+ public BaseFolderType GetFolder(DistinguishedFolderIdNameType folderType)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var getFolderType = new GetFolderType
+ {
+ FolderIds = new[] { new DistinguishedFolderIdType { Id = folderType } },
+ FolderShape = new FolderResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties }
+ };
+
+ var getFolderResponse = binding.GetFolder(getFolderType);
+
+ if (getFolderResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(getFolderResponse.ResponseMessages.Items[0].MessageText);
+
+ return ((FolderInfoResponseMessageType) getFolderResponse.ResponseMessages.Items[0]).Folders[0];
+ }
+
+ public BaseFolderType GetRootFolder()
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var findFolderType = new FindFolderType
+ {
+ Traversal = FolderQueryTraversalType.Shallow,
+ ParentFolderIds = new[] { new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.root } },
+ FolderShape = new FolderResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties }
+ };
+
+ var findFolderResponse = binding.FindFolder(findFolderType);
+
+ if (findFolderResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(findFolderResponse.ResponseMessages.Items[0].MessageText);
+
+ BaseFolderType[] bft = ((FindFolderResponseMessageType)findFolderResponse.ResponseMessages.Items[0]).RootFolder.Folders;
+
+ return bft[0];
+ }
+
+ /// <summary>
+ /// Returns all folders in the exchange box.
+ /// </summary>
+ /// <returns></returns>
+ public IEnumerable<BaseFolderType> FindAllFolders(string id)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var findFolderType = new FindFolderType
+ {
+ Traversal = FolderQueryTraversalType.Shallow,
+ ParentFolderIds = new[] { new FolderIdType { Id = id } },
+ FolderShape = new FolderResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties }
+ };
+
+ FindFolderResponseType findFolderResponse = binding.FindFolder(findFolderType);
+
+ if (findFolderResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(findFolderResponse.ResponseMessages.Items[0].MessageText);
+
+ var folders = ((FindFolderResponseMessageType)findFolderResponse.ResponseMessages.Items[0]).RootFolder.Folders;
+
+ foreach (var baseFolderType in folders)
+ {
+ yield return baseFolderType;
+
+ // Find children of current folder
+ foreach (var folderType in FindAllFolders(baseFolderType.FolderId.Id))
+ yield return folderType;
+ }
+ }
+
+ /// <summary>
+ /// Gets a list of all the items in the mailbox with all their properties.
+ /// </summary>
+ /// <returns></returns>
+ public IEnumerable<MessageType> GetHeaders(ChannelFolder folder)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var findItemRequest = new FindItemType { Traversal = ItemQueryTraversalType.Shallow };
+ var itemProperties = new ItemResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties };
+
+ findItemRequest.ItemShape = itemProperties;
+ findItemRequest.ParentFolderIds = new BaseFolderIdType[] { new FolderIdType { Id = folder.FolderId } };
+
+ FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);
+
+ foreach (FindItemResponseMessageType responseMessage in findItemResponse.ResponseMessages.Items)
+ {
+ if (responseMessage.ResponseClass == ResponseClassType.Success)
+ {
+ ArrayOfRealItemsType mailboxItems = (ArrayOfRealItemsType) responseMessage.RootFolder.Item;
+
+ if (mailboxItems.Items == null)
+ yield break;
+
+ foreach (MessageType inboxItem in mailboxItems.Items)
+ yield return inboxItem;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a specific message from exchange by id (attachments are only loaded shallow).
+ /// </summary>
+ /// <param name="messageId"></param>
+ /// <returns></returns>
+ public MessageType GetMessage(string messageId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ ItemIdType itemId = new ItemIdType();
+ itemId.Id = messageId;
+
+ GetItemType getItemRequest = new GetItemType();
+ getItemRequest.ItemShape = new ItemResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties };
+ getItemRequest.ItemIds = new[] { itemId };
+
+ GetItemResponseType getItemResponse = binding.GetItem(getItemRequest);
+
+ if (getItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(getItemResponse.ResponseMessages.Items[0].MessageText);
+
+ var getItemResponseMessage = (ItemInfoResponseMessageType)getItemResponse.ResponseMessages.Items[0];
+
+ if (getItemResponseMessage.Items.Items == null || getItemResponseMessage.Items.Items.Length == 0)
+ throw new ApplicationException("Error in GetMessage, empty ItemInfoResponseMessageType");
+
+ return (MessageType)getItemResponseMessage.Items.Items[0];
+ }
+
+ /// <summary>
+ /// Gets the id and changekey of a specific message by id.
+ /// </summary>
+ /// <param name="messageId"></param>
+ /// <returns></returns>
+ public MessageType GetMessageId(string messageId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ ItemIdType itemId = new ItemIdType();
+ itemId.Id = messageId;
+
+ // Re-get item and changekey from exchange
+ GetItemResponseType getItemResponse = binding.GetItem(new GetItemType
+ {
+ ItemShape = new ItemResponseShapeType { BaseShape = DefaultShapeNamesType.IdOnly },
+ ItemIds = new[] { itemId }
+ });
+
+ if (getItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(getItemResponse.ResponseMessages.Items[0].MessageText);
+
+ return (MessageType)((ItemInfoResponseMessageType)getItemResponse.ResponseMessages.Items[0]).Items.Items[0];
+ }
+
+ /// <summary>
+ /// Asks Exchange to send a specific message.
+ /// </summary>
+ /// <param name="messageId"></param>
+ public void SendMessage(ItemIdType messageId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ // Send message
+ var sendItem = new SendItemType { ItemIds = new BaseItemIdType[1], SavedItemFolderId = new TargetFolderIdType() };
+ var siSentItemsFolder = new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.sentitems };
+
+ sendItem.SavedItemFolderId.Item = siSentItemsFolder;
+ sendItem.SaveItemToFolder = true;
+ sendItem.ItemIds[0] = messageId;
+
+ SendItemResponseType sendItemResponse = binding.SendItem(sendItem);
+
+ if (sendItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(sendItemResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Gets a specific attachment from exchange by id.
+ /// </summary>
+ /// <param name="id"></param>
+ /// <returns></returns>
+ public FileAttachmentType GetAttachment(string id)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+ var getAttachmentRequest = new GetAttachmentType();
+
+ var attachmentIdArray = new RequestAttachmentIdType[1];
+ attachmentIdArray[0] = new RequestAttachmentIdType { Id = id };
+
+ getAttachmentRequest.AttachmentIds = attachmentIdArray;
+
+ GetAttachmentResponseType getAttachmentResponse = binding.GetAttachment(getAttachmentRequest);
+
+ if (getAttachmentResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(getAttachmentResponse.ResponseMessages.Items[0].MessageText);
+
+ var attachmentResponseMessage =
+ (AttachmentInfoResponseMessageType)getAttachmentResponse.ResponseMessages.Items[0];
+
+ if (attachmentResponseMessage.Attachments == null || attachmentResponseMessage.Attachments.Length == 0)
+ throw new ApplicationException("Error in GetAttachment, empty AttachmentInfoResponseMessageType");
+
+ return (FileAttachmentType)attachmentResponseMessage.Attachments[0];
+ }
+
+ /// <summary>
+ /// Saves the given message to the drafts folder.
+ /// </summary>
+ /// <param name="message"></param>
+ /// <returns></returns>
+ public ItemIdType SaveMessage(ChannelMessage message)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var createItemRequest = new CreateItemType();
+
+ // Indicate that we want to save only at first
+ createItemRequest.MessageDisposition = MessageDispositionType.SaveOnly;
+ createItemRequest.MessageDispositionSpecified = true;
+ createItemRequest.Items = new NonEmptyArrayOfAllItemsType();
+
+ // Create a single e-mail message.
+ var exchMessage = new MessageType();
+ exchMessage.Subject = message.Context;
+ exchMessage.Body = new BodyType { BodyType1 = BodyTypeType.HTML, Value = message.BodyHtml.ReadString() };
+ exchMessage.ItemClass = "IPM.Note";
+ exchMessage.Sender = new SingleRecipientType();
+ exchMessage.Sender.Item = new EmailAddressType { EmailAddress = message.From.Address };
+
+ exchMessage.ToRecipients = new EmailAddressType[message.To.Count];
+ exchMessage.CcRecipients = new EmailAddressType[message.CC.Count];
+ exchMessage.BccRecipients = new EmailAddressType[message.BCC.Count];
+
+ for (int i = 0; i < message.To.Count; i++)
+ exchMessage.ToRecipients[i] = new EmailAddressType { EmailAddress = message.To[i].Address };
+
+ for (int i = 0; i < message.CC.Count; i++)
+ exchMessage.CcRecipients[i] = new EmailAddressType { EmailAddress = message.CC[i].Address };
+
+ for (int i = 0; i < message.BCC.Count; i++)
+ exchMessage.BccRecipients[i] = new EmailAddressType { EmailAddress = message.BCC[i].Address };
+
+ exchMessage.Sensitivity = SensitivityChoicesType.Normal;
+
+ // Add the message to the array of items to be created.
+ createItemRequest.Items.Items = new ItemType[1];
+ createItemRequest.Items.Items[0] = exchMessage;
+
+ // Send the request to create and send the e-mail item, and get the response.
+ CreateItemResponseType createItemResponse = binding.CreateItem(createItemRequest);
+
+ // Determine whether the request was a success.
+ if (createItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(createItemResponse.ResponseMessages.Items[0].MessageText);
+
+ return ((ItemInfoResponseMessageType)createItemResponse.ResponseMessages.Items[0]).Items.Items[0].ItemId;
+ }
+
+ /// <summary>
+ /// Saves all attachments belonging to a specific message. This method can only be called after the message
+ /// has been saved in exchange.
+ /// </summary>
+ /// <param name="messageId"></param>
+ /// <param name="message"></param>
+ /// <returns></returns>
+ public IEnumerable<ItemIdType> SaveAttachments(ItemIdType messageId, ChannelMessage message)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ // Create add attachment request.
+ var attachementRequest = new CreateAttachmentType();
+ attachementRequest.ParentItemId = messageId;
+ attachementRequest.Attachments = new AttachmentType[message.Attachments.Count];
+
+ for (int i = 0; i < message.Attachments.Count; i++)
+ {
+ var channelAttachment = message.Attachments[i];
+ var exchAttachment = new FileAttachmentType();
+
+ exchAttachment.Name = channelAttachment.Filename;
+ exchAttachment.ContentType = MimeHelper.GetMimeType(channelAttachment.Filename);
+ exchAttachment.Content = channelAttachment.ContentStream.GetBytes();
+
+ attachementRequest.Attachments[i] = exchAttachment;
+
+ var saveAttachmentResponse = binding.CreateAttachment(attachementRequest);
+
+ // Determine whether the request was a success.
+ if (saveAttachmentResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(saveAttachmentResponse.ResponseMessages.Items[0].MessageText);
+
+ AttachmentIdType attachmentId = ((AttachmentInfoResponseMessageType)saveAttachmentResponse.ResponseMessages.Items[0]).Attachments[0].AttachmentId;
+
+ yield return new ItemIdType { ChangeKey = attachmentId.RootItemChangeKey, Id = attachmentId.RootItemId };
+ }
+ }
+
+ /// <summary>
+ /// Delete the given message permanatly.
+ /// </summary>
+ /// <param name="messageId"></param>
+ public void DeleteMessage(ItemIdType messageId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var deleteItemRequest = new DeleteItemType
+ {
+ ItemIds = new BaseItemIdType[] {messageId},
+ DeleteType = DisposalType.HardDelete
+ };
+
+ DeleteItemResponseType deleteResponse = binding.DeleteItem(deleteItemRequest);
+
+ if (deleteResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(deleteResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Sets the message readstate.
+ /// </summary>
+ public void SetMessageReadState(ItemIdType messageId, bool isRead)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var setField = new SetItemFieldType
+ {
+ Item1 = new MessageType { IsRead = isRead, IsReadSpecified = true },
+ Item = new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.messageIsRead }
+ };
+
+ var updatedItems = new[]
+ {
+ new ItemChangeType
+ {
+ Updates = new ItemChangeDescriptionType[] { setField },
+ Item = messageId
+ }
+ };
+
+ var request = new UpdateItemType
+ {
+ ItemChanges = updatedItems,
+ ConflictResolution = ConflictResolutionType.AutoResolve,
+ MessageDisposition = MessageDispositionType.SaveOnly,
+ MessageDispositionSpecified = true
+ };
+
+ UpdateItemResponseType updateItemResponse = binding.UpdateItem(request);
+
+ if (updateItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(updateItemResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Sets the message importance flag.
+ /// </summary>
+ public void SetMessageImportance(ItemIdType messageId, bool isStarred)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var setField = new SetItemFieldType
+ {
+ Item1 = new MessageType { Importance = isStarred ? ImportanceChoicesType.High : ImportanceChoicesType.Normal, ImportanceSpecified = true },
+ Item = new PathToUnindexedFieldType { FieldURI = UnindexedFieldURIType.itemImportance }
+ };
+
+ var updatedItems = new[]
+ {
+ new ItemChangeType
+ {
+ Updates = new ItemChangeDescriptionType[] { setField },
+ Item = messageId
+ }
+ };
+
+ var request = new UpdateItemType
+ {
+ ItemChanges = updatedItems,
+ ConflictResolution = ConflictResolutionType.AutoResolve,
+ MessageDisposition = MessageDispositionType.SaveOnly,
+ MessageDispositionSpecified = true
+ };
+
+ UpdateItemResponseType updateItemResponse = binding.UpdateItem(request);
+
+ if (updateItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(updateItemResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Creates a folder with the given name and returns the associated folderid.
+ /// </summary>
+ /// <param name="name"></param>
+ /// <param name="parentFolderId"></param>
+ /// <returns></returns>
+ public string CreateFolder(string name, string parentFolderId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var request = new CreateFolderType
+ {
+ Folders = new BaseFolderType[] { new FolderType { DisplayName = name } },
+ ParentFolderId = new TargetFolderIdType { Item = new FolderIdType { Id = parentFolderId } }
+ };
+
+ CreateFolderResponseType moveItemResponse = binding.CreateFolder(request);
+
+ if (moveItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(moveItemResponse.ResponseMessages.Items[0].MessageText);
+
+ var response = (FolderInfoResponseMessageType) moveItemResponse.ResponseMessages.Items[0];
+ return response.Folders[0].FolderId.Id;
+ }
+
+ /// <summary>
+ /// Moves the given message to the given folder.
+ /// </summary>
+ public void MoveMessageToFolder(ItemIdType messageId, string folderId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var request = new MoveItemType
+ {
+ ItemIds = new BaseItemIdType[] { messageId },
+ ToFolderId = new TargetFolderIdType { Item = new FolderIdType { Id = folderId } }
+ };
+
+ MoveItemResponseType moveItemResponse = binding.MoveItem(request);
+
+ if (moveItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(moveItemResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Moves the given message to the given folder.
+ /// </summary>
+ public void CopyMessageToFolder(ItemIdType messageId, string folderId)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var request = new CopyItemType
+ {
+ ItemIds = new BaseItemIdType[] { messageId },
+ ToFolderId = new TargetFolderIdType { Item = new FolderIdType { Id = folderId } }
+ };
+
+ CopyItemResponseType moveItemResponse = binding.CopyItem(request);
+
+ if (moveItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(moveItemResponse.ResponseMessages.Items[0].MessageText);
+ }
+
+ /// <summary>
+ /// Gets the nr of items in a given folder
+ /// </summary>
+ /// <returns></returns>
+ public long GetNrItemsInFolder(ChannelFolder folder)
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var findItemRequest = new FindItemType { Traversal = ItemQueryTraversalType.Shallow };
+ var itemProperties = new ItemResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties };
+ findItemRequest.ItemShape = itemProperties;
+
+ var folderIdArray = new DistinguishedFolderIdType[2];
+ folderIdArray[0] = new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.inbox };
+
+ findItemRequest.ParentFolderIds = folderIdArray;
+
+ FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);
+
+ // Determine whether the request was a success.
+ if (findItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(findItemResponse.ResponseMessages.Items[0].MessageText);
+
+ var responseMessage =
+ (FindItemResponseMessageType) findItemResponse.ResponseMessages.Items[0];
+
+ var mailboxItems = (ArrayOfRealItemsType)responseMessage.RootFolder.Item;
+
+ if (mailboxItems.Items == null) return 0;
+
+ return mailboxItems.Items.Length;
+ }
+
+ /// <summary>
+ /// Retrieves contacts from exchange database.
+ /// </summary>
+ /// <returns></returns>
+ public IEnumerable<ContactItemType> GetContacts()
+ {
+ var binding = ChannelHelper.BuildChannel(hostname, username, password);
+
+ var findItemRequest = new FindItemType
+ {
+ ItemShape = new ItemResponseShapeType {BaseShape = DefaultShapeNamesType.AllProperties},
+ ParentFolderIds = new[] { new DistinguishedFolderIdType { Id = DistinguishedFolderIdNameType.contacts } }
+ };
+
+ FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);
+
+ // Determine whether the request was a success.
+ if (findItemResponse.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Error)
+ throw new Exception(findItemResponse.ResponseMessages.Items[0].MessageText);
+
+ var responseMessage = (FindItemResponseMessageType)findItemResponse.ResponseMessages.Items[0];
+ var contactItems = (ArrayOfRealItemsType)responseMessage.RootFolder.Item;
+
+ return contactItems.Items.Cast<ContactItemType>();
+ }
+ }
+}
415 Code/Channels/Exchange/ExchangeClientChannel.cs
@@ -0,0 +1,415 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using System.Net;
+using ExchangeServicesWsdlClient;
+using Inbox2.Platform.Channels.Entities;
+using Inbox2.Platform.Channels.Interfaces;
+using Inbox2.Platform.Framework.Extensions;
+using Inbox2.Platform.Logging;
+using Logger = Inbox2.Platform.Logging.Logger;
+
+namespace Inbox2.Channels.Exchange
+{
+ public class ExchangeClientChannel : IClientInputChannel, IClientOutputChannel, IPagableChannel, IReadStateChannel, IClientContactsChannel, ILabelsChannel
+ {
+ private ChannelFolder folder;
+ private List<ChannelFolder> folders;
+
+ #region Properties
+
+ public long StartIndex { get; set; }
+
+ public long EndIndex { get; set; }
+
+ public long PageSize { get; set; }
+
+ public ChannelProgressDelegate BytesRead { get; set; }
+
+ public ChannelProgressDelegate BytesWritten { get; set; }
+
+ public string Hostname { get; set; }
+
+ public int Port { get; set; }
+
+ public bool IsSecured { get; set; }
+
+ public string Username
+ {
+ get { return CredentialsProvider.GetCredentials().Claim; }
+ }
+
+ public string Password
+ {
+ get { return CredentialsProvider.GetCredentials().Evidence; }
+ }
+
+ public bool IsEnabled { get; set; }
+
+ public int MaxConcurrentConnections { get; set; }
+
+ public IChannelCredentialsProvider CredentialsProvider { get; set; }
+
+ public string Protocol
+ {
+ get { return "ExchangeWS"; }
+ }
+
+ public string SourceAdress
+ {
+ get
+ {
+ string username = CredentialsProvider.GetCredentials().Claim;
+
+ return username.Contains("@") ? username : String.Format("{0}@{1}", username, Hostname);
+ }
+ }
+
+ public LabelsSupport LabelsSupport
+ {
+ get { return LabelsSupport.Folders; }
+ }
+
+ public string AuthMessage { get; private set; }
+
+ #endregion
+
+ public ConnectResult Connect()
+ {
+ var credentials = CredentialsProvider.GetCredentials();
+ var binding = ChannelHelper.BuildChannel(Hostname, credentials.Claim, credentials.Evidence);
+
+ folders = new List<ChannelFolder>();
+
+ // Try connecting
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(binding.Url);
+ request.AllowAutoRedirect = false;
+ request.Credentials = new NetworkCredential(credentials.Claim, credentials.Evidence);
+
+ try
+ {
+ HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+
+ Logger.Debug("Server {0} returned status-code {1}", LogSource.Channel, binding.Url, response.StatusCode);
+
+ if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Found)
+ return ConnectResult.Success;
+
+ AuthMessage = String.Format("Statuscode {0}", response.StatusCode);
+
+ return ConnectResult.AuthFailure;
+ }
+ catch (Exception ex)
+ {
+ AuthMessage = ex.Message;
+
+ return ConnectResult.AuthFailure;
+ }
+ }
+
+ public IEnumerable<ChannelFolder> GetFolders()
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ // inbox
+ var inbox = client.GetFolder(DistinguishedFolderIdNameType.inbox);
+ folders.Add(new ChannelFolder(inbox.FolderId.Id, inbox.DisplayName, ChannelFolderType.Inbox));
+ folders.AddRange(GetChildFolders(client, inbox.FolderId.Id, ChannelFolderType.Label));
+
+ // sent items
+ var sent = client.GetFolder(DistinguishedFolderIdNameType.sentitems);
+ folders.Add(new ChannelFolder(sent.FolderId.Id, sent.DisplayName, ChannelFolderType.SentItems));
+ folders.AddRange(GetChildFolders(client, sent.FolderId.Id, ChannelFolderType.SentItems));
+
+ // trash
+ var trash = client.GetFolder(DistinguishedFolderIdNameType.deleteditems);
+ folders.Add(new ChannelFolder(trash.FolderId.Id, trash.DisplayName, ChannelFolderType.Trash));
+
+ // spam
+ var spam = client.GetFolder(DistinguishedFolderIdNameType.junkemail);
+ folders.Add(new ChannelFolder(spam.FolderId.Id, spam.DisplayName, ChannelFolderType.Spam));
+
+ return folders;
+ }
+
+ IEnumerable<ChannelFolder> GetChildFolders(ExchangeClient client, string folderId, ChannelFolderType folderType)
+ {
+ var childFolders = client.FindAllFolders(folderId);
+
+ return childFolders.Select(f => new ChannelFolder(f.FolderId.Id, f.DisplayName, folderType));
+ }
+
+ public void SelectFolder(ChannelFolder folder)
+ {
+ this.folder = folder;
+ }
+
+ public IEnumerable<ChannelMessageHeader> GetHeaders()
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ foreach (MessageType inboxItem in client.GetHeaders(folder).Reverse().Skip((int)StartIndex).Take((int)PageSize))
+ {
+ var header = new ChannelMessageHeader
+ {
+ MessageNumber = inboxItem.ItemId.Id,
+ MessageIdentifier = inboxItem.InternetMessageId,
+ Context = inboxItem.Subject,
+ // Not sending size because exchange changes can the size due
+ // to user actions usch as change priority.
+ //Size = inboxItem.Size,
+ DateReceived = inboxItem.DateTimeReceived,
+ IsRead = inboxItem.IsRead,
+ // Not processing IsStarred because somebody could send you an
+ // email with importance: high and would end up getting starred;
+ // feature just asking for abuse :-)
+ //IsStarred = inboxItem.Importance == ImportanceChoicesType.High,
+ };
+
+ yield return header;
+ }
+ }
+
+ public IEnumerable<ChannelMessage> GetMessage(ChannelMessageHeader header)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ ChannelMessage message = new ChannelMessage();
+ MessageType inboxItem = client.GetMessage(header.MessageNumber);
+
+ // Now the message Body is there.
+ BodyType messageBody = inboxItem.Body;
+
+ message.Size = header.Size;
+ message.MessageNumber = header.MessageNumber;
+ message.MessageIdentifier = header.MessageIdentifier;
+ message.Context = header.Context;
+ message.From = new SourceAddress(inboxItem.From.Item.EmailAddress, inboxItem.From.Item.Name);
+
+ if (inboxItem.ToRecipients != null)
+ foreach (var toRecipient in inboxItem.ToRecipients)
+ message.To.Add(new SourceAddress(toRecipient.EmailAddress, toRecipient.Name));
+
+ if (inboxItem.CcRecipients != null)
+ foreach (var ccRecipient in inboxItem.CcRecipients)
+ message.CC.Add(new SourceAddress(ccRecipient.EmailAddress, ccRecipient.Name));
+
+ if (inboxItem.BccRecipients != null)
+ foreach (var bccRecipient in inboxItem.BccRecipients)
+ message.BCC.Add(new SourceAddress(bccRecipient.EmailAddress, bccRecipient.Name));
+
+ message.InReplyTo = inboxItem.InReplyTo;
+ message.Metadata = header.Metadata;
+ message.IsRead = inboxItem.IsRead;
+ message.BodyHtml = messageBody.Value.ToStream();
+ message.DateReceived = header.DateReceived;
+
+ if (inboxItem.Attachments != null)
+ {
+ foreach (AttachmentType exchAttachment in inboxItem.Attachments)
+ {
+ var fileAttachment = client.GetAttachment(exchAttachment.AttachmentId.Id);
+
+ message.Attachments.Add(new ChannelAttachment
+ {
+ Filename = fileAttachment.Name,
+ ContentType = ContentType.Attachment,
+ ContentStream = new MemoryStream(fileAttachment.Content)
+ });
+ }
+ }
+
+ yield return message;
+ }
+
+ public void Send(ChannelMessage message)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ var messageId = client.SaveMessage(message);
+
+ // Upload attachments
+ if (message.Attachments.Count > 0)
+ client.SaveAttachments(messageId, message);
+
+ // Refresh and send message by message-id
+ client.SendMessage(client.GetMessageId(messageId.Id).ItemId);
+ }
+
+ public bool Disconnect()
+ {
+ return true;
+ }
+
+ public IClientInputChannel Clone()
+ {
+ return new ExchangeClientChannel
+ {
+ Hostname = Hostname,
+ Port = Port,
+ IsSecured = IsSecured,
+ MaxConcurrentConnections = MaxConcurrentConnections,
+ CredentialsProvider = CredentialsProvider
+ };
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public long GetNumberOfItems()
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ return client.GetNrItemsInFolder(folder);
+ }
+
+ public void MarkRead(ChannelMessageHeader message)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.SetMessageReadState(messageId, true);
+ }
+
+ public void MarkUnread(ChannelMessageHeader message)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.SetMessageReadState(messageId, false);
+ }
+
+ public void MarkDeleted(ChannelMessageHeader message)
+ {
+ var trash = GetFolders().First(f => f.FolderType == ChannelFolderType.Trash);
+
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.MoveMessageToFolder(messageId, trash.FolderId);
+ }
+
+ public void SetStarred(ChannelMessageHeader message, bool starred)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.SetMessageImportance(messageId, starred);
+ }
+
+ public void Purge(ChannelMessageHeader message)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.DeleteMessage(messageId);
+ }
+
+ public ChannelFolder CreateFolder(string folderName)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var folderId = client.CreateFolder(folderName, folders.First(f => f.FolderType == ChannelFolderType.Inbox).FolderId);
+
+ var newFolder = new ChannelFolder(folderId, folderName, ChannelFolderType.Label);
+
+ folders.Add(newFolder);
+
+ return newFolder;
+ }
+
+ public void MoveToFolder(ChannelMessageHeader message, ChannelFolder folder)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.MoveMessageToFolder(messageId, folder.FolderId);
+ }
+
+ public void CopyToFolder(ChannelMessageHeader message, ChannelFolder folder)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.CopyMessageToFolder(messageId, folder.FolderId);
+ }
+
+ public void RemoveFromFolder(ChannelMessageHeader message, ChannelFolder folder)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.DeleteMessage(messageId);
+ }
+
+ public void AddLabel(ChannelMessageHeader message, string labelname)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(message.MessageNumber).ItemId;
+
+ client.CopyMessageToFolder(messageId, folders.First(f => f.Name.ToLower() == labelname.ToLower()).FolderId);
+ }
+
+ public void RemoveLabel(string messagenumber, string labelname)
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+ var messageId = client.GetMessageId(messagenumber).ItemId;
+
+ client.DeleteMessage(messageId);
+ }
+
+ public IEnumerable<ChannelContact> GetContacts()
+ {
+ var client = new ExchangeClient(Hostname, CredentialsProvider);
+
+ foreach (var contactItem in client.GetContacts())
+ {
+ if (contactItem.EmailAddresses == null || contactItem.EmailAddresses.Length == 0)
+ {
+ Logger.Warn("Contact {0} had no email address, ignoring", LogSource.Sync, contactItem.DisplayName);
+
+ continue;
+ }
+
+ var contact = new ChannelContact();
+
+ contact.Profile.ChannelProfileKey = contactItem.ItemId.Id;
+ contact.Profile.SourceAddress = new SourceAddress(contactItem.EmailAddresses[0].Value, contactItem.DisplayName);
+
+ contact.Person.Lastname = contactItem.Surname;
+ contact.Person.Firstname = contactItem.GivenName;
+
+ if (contactItem.BirthdaySpecified)
+ contact.Person.DateOfBirth = contactItem.Birthday;
+
+ contact.Profile.ScreenName = contactItem.Nickname;
+ contact.Profile.Title = contactItem.JobTitle;
+ contact.Profile.ScreenName = contactItem.DisplayName;
+ contact.Profile.CompanyName = contactItem.CompanyName;
+
+ if (contactItem.PhysicalAddresses.Length > 0)
+ {
+ contact.Profile.Street = contactItem.PhysicalAddresses[0].Street;
+ contact.Profile.ZipCode = contactItem.PhysicalAddresses[0].PostalCode;
+ contact.Profile.City = contactItem.PhysicalAddresses[0].City;
+ contact.Profile.Country = contactItem.PhysicalAddresses[0].CountryOrRegion;
+ }
+
+ yield return contact;
+ }
+ }
+
+ IClientContactsChannel IClientContactsChannel.Clone()
+ {
+ return new ExchangeClientChannel()
+ {
+ Hostname = Hostname,
+ Port = Port,
+ IsSecured = IsSecured,
+ MaxConcurrentConnections = MaxConcurrentConnections,
+ CredentialsProvider = CredentialsProvider
+ };
+ }
+ }
+}
52 Code/Channels/Exchange/ExchangeConfiguration.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+using Inbox2.Platform.Channels.Configuration;
+using Inbox2.Platform.Framework.Extensions;
+using Inbox2.Platform.Interfaces.Enumerations;
+
+namespace Inbox2.Channels.Exchange
+{
+ [Serializable]
+ [Export(typeof(ChannelConfiguration))]
+ public class ExchangeConfiguration : ChannelConfiguration
+ {
+ public ExchangeConfiguration()
+ {
+ InnerInputChannel = new Channel { Type = typeof(ExchangeClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 2 };
+ InnerOutputChannel = new Channel { Type = typeof(ExchangeClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 2 };
+ InnerContactsChannel = new Channel { Type = typeof(ExchangeClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 2 };
+ }
+
+ public override string DisplayName
+ {
+ get { return "Exchange"; }
+ }
+
+ public override DisplayStyle DisplayStyle
+ {
+ get { return DisplayStyle.Advanced; }
+ }
+
+ public override ChannelCharasteristics Charasteristics
+ {
+ get
+ {
+ var charasteristics = ChannelCharasteristics.Default;
+
+ charasteristics.SupportsReadStates = true;
+ charasteristics.SupportsLabels = true;
+
+ return charasteristics;
+ }
+ }
+
+ public override ChannelConfiguration Clone()
+ {
+ return this.DeepCopy(new XmlSerializer(typeof(ExchangeConfiguration)));
+ }
+ }
+}
23,747 Code/Channels/Exchange/ExchangeWebService.cs
23,747 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
193 Code/Channels/Exchange/Inbox2.Channels.Exchange.csproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{357C154B-152A-4381-A5C2-A17A5993B129}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Inbox2.Channels.Exchange</RootNamespace>
+ <AssemblyName>Inbox2.Channels.Exchange</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\Stable Assemblies\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition, Version=2008.9.4.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\ThirdParty\MEF\System.ComponentModel.Composition.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ChannelHelper.cs" />
+ <Compile Include="ExchangeClient.cs" />
+ <Compile Include="ExchangeClientChannel.cs" />
+ <Compile Include="ExchangeConfiguration.cs" />
+ <Compile Include="ExchangeWebService.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Platform\Channels\Inbox2.Platform.Channels.csproj">
+ <Project>{43B96CD2-D7DA-4286-A209-EE9585EF6927}</Project>
+ <Name>Inbox2.Platform.Channels</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Framework\Inbox2.Platform.Framework.csproj">
+ <Project>{FB90E43A-0E32-41D5-A7AB-83EA0D936E5E}</Project>
+ <Name>Inbox2.Platform.Framework</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Interfaces\Inbox2.Platform.Interfaces.csproj">
+ <Project>{B9CE1540-1D68-43B2-83DB-47EC21D158A6}</Project>
+ <Name>Inbox2.Platform.Interfaces</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\Platform\Logging\Inbox2.Platform.Logging.csproj">
+ <Project>{6AE2A2AF-9B61-45B0-A375-666C5225A5B4}</Project>
+ <Name>Inbox2.Platform.Logging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.VisualBasic.PowerPacks.10.0">
+ <Visible>False</Visible>
+ <ProductName>Microsoft Visual Basic PowerPacks 10.0</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Resources\icon-10.png" />
+ <EmbeddedResource Include="Resources\icon-13.png" />
+ <EmbeddedResource Include="Resources\icon-64.png" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!--<Target Name="GenSerializationAssembly"
+ DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
+ Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
+ Outputs="$(OutputPath)$(_SGenDllName)">
+ <SGen BuildAssemblyName="$(TargetFileName)"
+ BuildAssemblyPath="$(OutputPath)"
+ References="@(ReferencePath)"
+ ShouldGenerateSerializer="true"
+ UseProxyTypes="false"
+ KeyContainer="$(KeyContainerName)"
+ KeyFile="$(KeyOriginatorFile)"
+ DelaySign="$(DelaySign)"
+ ToolPath="$(SGenToolPath)">
+ <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
+ </SGen>
+ </Target>
+ <Target Name="AfterBuild" DependsOnTargets="GenSerializationAssembly" />-->
+ <PropertyGroup>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
36 Code/Channels/Exchange/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Inbox2.Channels.Exchange")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Tabdeelee")]
+[assembly: AssemblyProduct("Inbox2.Channels.Exchange")]
+[assembly: AssemblyCopyright("Copyright © Tabdeelee 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("121474e6-35ab-4823-b8a3-7a354dd48e63")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
BIN Code/Channels/Exchange/Resources/icon-10.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Code/Channels/Exchange/Resources/icon-13.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Code/Channels/Exchange/Resources/icon-64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 Code/Channels/Facebook/ChannelHelper.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using Inbox2.Channels.Facebook.REST;
+
+namespace Inbox2.Channels.Facebook
+{
+ internal static class ChannelHelper
+ {
+ internal static IFacebookClient BuildChannel()
+ {
+ EndpointAddress address = new EndpointAddress("http://api.facebook.com/restserver.php");
+ WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.None);
+
+ binding.ReaderQuotas.MaxDepth = 2147483647;
+ binding.ReaderQuotas.MaxStringContentLength = 2147483647;
+ binding.ReaderQuotas.MaxArrayLength = 2147483647;
+ binding.ReaderQuotas.MaxBytesPerRead = 2147483647;
+ binding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
+ binding.MaxReceivedMessageSize = Int32.MaxValue;
+
+ ChannelFactory<IFacebookClient> cf = new ChannelFactory<IFacebookClient>(binding, address);
+ cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
+
+ return cf.CreateChannel();
+ }
+
+ internal static DateTime ConvertFromUnixTimestamp(double timestamp)
+ {
+ DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
+ return origin.AddSeconds(timestamp);
+ }
+ }
+}
340 Code/Channels/Facebook/FacebookClientChannel.cs
@@ -0,0 +1,340 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using Inbox2.Channels.Facebook.REST;
+using Inbox2.Channels.Facebook.REST.DataContracts;
+using Inbox2.Platform.Framework.Extensions;
+using Inbox2.Platform.Channels;
+using Inbox2.Platform.Channels.Entities;
+using Inbox2.Platform.Channels.Interfaces;
+using Inbox2.Platform.Channels.Web;
+
+namespace Inbox2.Channels.Facebook
+{
+ public class FacebookClientChannel : IClientInputChannel, IClientOutputChannel, IClientContactsChannel, IClientStatusUpdatesChannel
+ {
+ #region Fields
+
+ protected const string MessageComposePageMobile = "http://m.facebook.com/inbox/?rfb157ae2=&compose=&ids={0}&refid=0";
+ protected FacebookRESTClient client;
+
+ #endregion
+
+ #region Properties
+
+ public string Hostname
+ {
+ get { return "http://api.facebook.com/restserver.php"; }
+ set { }
+ }
+
+ public int Port
+ {
+ get { return 80; }
+ set { }
+ }
+
+ public bool IsSecured
+ {
+ get { return false; }
+ set { }
+ }
+
+ public bool IsEnabled
+ {
+ get; set;
+ }
+
+ public int MaxConcurrentConnections
+ {
+ get; set;
+ }
+
+ public IChannelCredentialsProvider CredentialsProvider
+ {
+ get; set;
+ }
+
+ public string Protocol
+ {
+ get { return "Facebook API"; }
+ }
+
+ public string SourceAdress
+ {
+ get { return CredentialsProvider.GetCredentials().Claim; }
+ }
+
+ public string AuthMessage { get; private set; }
+
+ #endregion
+
+ public FacebookClientChannel()
+ {
+ }
+
+ public ConnectResult Connect()
+ {
+ BuildRestClient();
+
+ FbAuth result = client.Authenticate();
+
+ if (result == FbAuth.Success)
+ return ConnectResult.Success;
+
+ return ConnectResult.AuthFailure;
+ }
+
+ public IEnumerable<ChannelFolder> GetFolders()
+ {
+ yield return new ChannelFolder("inbox", "inbox", ChannelFolderType.Inbox);
+ }
+
+ public void SelectFolder(ChannelFolder folder)
+ {
+
+ }
+
+ public IEnumerable<ChannelMessageHeader> GetHeaders()
+ {
+ BuildRestClient();
+
+ var messages = client.GetMessages(FbMessageFolder.Inbox).ToList();
+
+ foreach (FbMessage fbMessage in messages)
+ {
+ var header = new ChannelMessageHeader();
+
+ header.MessageIdentifier = fbMessage.MessageId;
+ header.MessageNumber = fbMessage.MessageId;
+ header.Context = fbMessage.Subject;
+ header.From = fbMessage.From;
+ header.To = fbMessage.To;
+ header.Body = fbMessage.Body;
+ header.IsRead = fbMessage.Read;
+ header.DateReceived = fbMessage.DateCreated;
+ header.Metadata.i2mpRelationId = fbMessage.ThreadId;
+
+ yield return header;
+ }
+ }
+
+ public IEnumerable<ChannelMessage> GetMessage(ChannelMessageHeader header)
+ {
+ ChannelMessage message = new ChannelMessage();
+ message.MessageNumber = header.MessageNumber;
+ message.MessageIdentifier = header.MessageIdentifier;
+ message.From = header.From;
+ message.Context = header.Context;
+ message.BodyText = header.Body.ToStream();
+ message.IsRead = header.IsRead;
+ message.DateReceived = header.DateReceived;
+ message.ConversationId = header.Metadata.i2mpRelationId;
+
+ yield return message;
+ }
+
+ public IEnumerable<ChannelContact> GetContacts()
+ {
+ BuildRestClient();
+
+ int count = 1;
+ var waitTime = new TimeSpan(0, 0, 1);
+
+ foreach (FbContact fbContact in client.GetContacts())
+ {
+ ChannelContact contact = ParseFbContact(fbContact);
+
+ if (count % 10 == 0)
+ Thread.Sleep(waitTime);
+
+ count++;
+ yield return contact;
+ }
+ }
+
+ IClientContactsChannel IClientContactsChannel.Clone()
+ {
+ return new FacebookClientChannel
+ {
+ Hostname = Hostname,
+ Port = Port,
+ IsSecured = IsSecured,
+ MaxConcurrentConnections = MaxConcurrentConnections,
+ CredentialsProvider = CredentialsProvider
+ };
+ }
+
+ public void Send(ChannelMessage message)
+ {
+ }
+
+ public ChannelSocialProfile GetProfile()
+ {
+ BuildRestClient();
+ var user = client.GetLoggedInUser();
+
+ return new ChannelSocialProfile
+ {
+ Id = user.UserId,
+ FullName = user.Name,
+ AvatarUrl = user.AvatarSquareUrl
+ };
+ }
+
+ public IEnumerable<ChannelStatusUpdate> GetMentions(int pageSize)
+ {
+ yield break;
+ }
+
+ public IEnumerable<ChannelStatusUpdate> GetUpdates(int pageSize)
+ {
+ BuildRestClient();
+
+ foreach (var fbStatus in client.GetStatusses(pageSize))
+ {
+ var status = ParseFbStatus(fbStatus);
+
+ status.Children.AddRange(fbStatus.Comments.Select(ParseFbStatus));
+
+ yield return status;
+ }
+ }
+
+ public IEnumerable<ChannelStatusUpdate> GetUserUpdates(string username, int pageSize)
+ {
+ BuildRestClient();
+
+ // Always select 50 from fb and return the requested nr because some updates from
+ // Facebook might be filtered out due to actorid being different from sourceid.
+ return client.GetStatusses(username, 50).Select(ParseFbStatus).Take(pageSize);
+ }
+
+ public IEnumerable<ChannelStatusUpdate> GetUpdates(string keyword, int pageSize)
+ {
+ BuildRestClient();
+
+ yield break;
+ }
+
+ public void UpdateMyStatus(ChannelStatusUpdate update)
+ {
+ BuildRestClient();
+
+ if (String.IsNullOrEmpty(update.InReplyTo))
+ client.SetStatus(update.Status);
+ else
+ client.PostComment(update.Status, update.InReplyTo);
+ }
+
+ IClientStatusUpdatesChannel IClientStatusUpdatesChannel.Clone()
+ {
+ return new FacebookClientChannel
+ {
+ Hostname = Hostname,
+ Port = Port,
+ IsSecured = IsSecured,
+ MaxConcurrentConnections = MaxConcurrentConnections,
+ CredentialsProvider = CredentialsProvider
+ };
+ }
+
+ public bool Disconnect()
+ {
+ if (client != null)
+ {
+ client.Dispose();
+ client = null;
+ }
+
+ return true;
+ }
+
+ public IClientInputChannel Clone()
+ {
+ FacebookClientChannel channel = new FacebookClientChannel();
+ channel.Hostname = Hostname;
+ channel.Port = Port;
+ channel.IsSecured = IsSecured;
+ channel.MaxConcurrentConnections = MaxConcurrentConnections;
+ channel.CredentialsProvider = CredentialsProvider;
+
+ return channel;
+ }
+
+ void BuildRestClient()
+ {
+ if (client == null)
+ {
+ var sessionKey = ChannelContext.Current.ClientContext.GetSetting("/Channels/Facebook/SessionKey").ToString();
+ var sessionSecret = ChannelContext.Current.ClientContext.GetSetting("/Channels/Facebook/SessionSecret").ToString();
+
+ var apiKey = FacebookApiKeys.GetApiKey();
+ var apiSecret = FacebookApiKeys.GetApiSecret();
+
+ if ("/Settings/Channels/Codebase".AsKey("cloud") == "client")
+ {
+ client = new FacebookRESTClient(apiKey, sessionSecret, sessionKey, sessionSecret);
+ }
+ else
+ {
+ client = new FacebookRESTClient(apiKey, apiSecret, sessionKey, sessionSecret);
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ Disconnect();
+ }
+
+ ChannelContact ParseFbContact(FbContact fbContact)
+ {
+ ChannelContact contact = new ChannelContact();
+
+ contact.Person.Firstname = fbContact.Firstname;
+ contact.Person.Lastname = fbContact.Lastname;
+
+ contact.Profile.ChannelProfileKey = fbContact.UserId;
+ contact.Profile.ProfileType = ProfileType.Social;
+ contact.Profile.SourceAddress = new SourceAddress(fbContact.UserId, contact.Person.Name);
+
+ if (!String.IsNullOrEmpty(fbContact.AvatarSquareUrl.Trim()))
+ {
+ ChannelAvatar avatar = new ChannelAvatar();
+ avatar.Url = fbContact.AvatarSquareUrl;
+ avatar.ContentStream = WebContentStreamHelper.GetContentStream(avatar.Url);
+
+ contact.Profile.ChannelAvatar = avatar;
+ }
+
+ return contact;
+ }
+
+ ChannelStatusUpdate ParseFbStatus(FbStatus fbStatus)
+ {
+ var status = new ChannelStatusUpdate();
+
+ status.ChannelStatusKey = fbStatus.StatusId;
+ status.From = fbStatus.From;
+ status.To = fbStatus.To;
+ status.Status = fbStatus.Message;
+ status.DatePosted = fbStatus.DateCreated;
+
+ foreach (var fbAttachment in fbStatus.Attachments)
+ {
+ var attachment = new ChannelStatusUpdateAttachment();
+
+ attachment.MediaType = (short)fbAttachment.MediaType;
+ attachment.PreviewAltText = fbAttachment.PreviewAltText;
+ attachment.PreviewImageUrl = fbAttachment.PreviewImageUrl;
+ attachment.TargetUrl = fbAttachment.TargetUrl;
+
+ status.Attachments.Add(attachment);
+ }
+
+ return status;
+ }
+ }
+}
70 Code/Channels/Facebook/FacebookConfiguration.cs
@@ -0,0 +1,70 @@
+using System;
+using System.ComponentModel.Composition;
+using System.Xml.Serialization;
+using Inbox2.Platform.Channels;
+using Inbox2.Platform.Channels.Configuration;
+using Inbox2.Platform.Channels.Interfaces;
+using Inbox2.Platform.Framework.Extensions;
+using Inbox2.Platform.Interfaces.Enumerations;
+
+namespace Inbox2.Channels.Facebook
+{
+ [Serializable]
+ [Export(typeof(ChannelConfiguration))]
+ public class FacebookConfiguration : ChannelConfiguration
+ {
+ public FacebookConfiguration()
+ {
+ InnerInputChannel = new Channel { Type = typeof(FacebookClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 2 };
+ InnerOutputChannel = new Channel { Type = typeof(FacebookClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 1 };
+ InnerContactsChannel = new Channel { Type = typeof(FacebookClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 1 };
+ InnerStatusUpdatesChannel = new Channel { Type = typeof(FacebookClientChannel), Port = 80, IsSecured = false, MaxConcurrentConnections = 1 };
+ }
+
+ public override string DisplayName
+ {
+ get { return "Facebook"; }
+ }
+
+ public override DisplayStyle DisplayStyle
+ {
+ get { return DisplayStyle.FbConnect; }
+ }
+
+ public override ChannelCharasteristics Charasteristics
+ {