Mini Kabibi Habibi
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.ServiceModel.Syndication
Imports System.Web.UI
Imports System.Xml
Imports DevExpress.Web.ASPxClasses
Imports DevExpress.Web.ASPxSplitter
Imports DevExpress.Web.ASPxGridView
Imports System.Text.RegularExpressions
Imports DevExpress.Data.Filtering
Imports System.Web.UI.WebControls
Partial Public Class Feeds
Inherits System.Web.UI.Page
Private Const FeedItemPreviewFormat As String = "<div class='FeedPreview'>" & "<div class='Subject'>{0}</div>" & "<div class='Info'>" & "<span>{1}</span>" & "<a href='{2}' target='_blank'>View on Web</a>" & "</div>" & "<div class='Separator'></div>" & "<div class='Body'>{3}</div>" & "</div>"
Private Shared ReadOnly FeedRegistry As New Dictionary(Of String, String)()
Private Shared LastFeedFetchTime As DateTime = DateTime.MinValue
Private Shared ReadOnly FeedTTL As TimeSpan = TimeSpan.FromHours(2)
Private Shared FetchedFeeds As New Dictionary(Of String, SyndicationFeed)()
Private Shared ReadOnly FeedFetchLock As Object = New Object()
Shared Sub New()
FeedRegistry("Blogs") = "http://community.devexpress.com/blogs/MainFeed.aspx"
FeedRegistry("Videos") = "http://tv.devexpress.com/rss.ashx"
FeedRegistry("Webinars") = "http://www.devexpress.com/rss/webinars/"
FeedRegistry("News") = "http://www.devexpress.com/rss/news/news20.xml"
FeedRegistry("BBC News") = "http://feeds.bbci.co.uk/news/rss.xml"
FeedRegistry("Engadget") = "http://www.engadget.com/rss.xml"
FeedRegistry("Stack Overflow") = "http://stackoverflow.com/feeds/tag?tagnames=devexpress&sort=newest"
End Sub
Protected ReadOnly Property SearchText() As String
Get
Return Utils.GetSearchText(Me)
End Get
End Property
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)
Utils.ApplyTheme(Me)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
LoadFeedToGrid()
PrepareMasterSplitter()
End Sub
Protected Sub FeedItemPreviewPanel_Callback(ByVal sender As Object, ByVal e As CallbackEventArgsBase)
Dim text As String = String.Format("Can't find feed with the key = {0}", e.Parameter)
If (Not String.IsNullOrEmpty(e.Parameter)) Then
Dim feedItem = CurrentFeed.Items.FirstOrDefault(Function(i) i.Id = e.Parameter)
If feedItem IsNot Nothing Then
text = FormatFeedItem(feedItem)
End If
End If
FeedItemPreviewPanel.Controls.Add(New LiteralControl(text))
End Sub
Protected Sub FeedGrid_CustomCallback(ByVal sender As Object, ByVal e As ASPxGridViewCustomCallbackEventArgs)
If e.Parameters = "FeedChanged" OrElse e.Parameters = "Search" AndAlso String.IsNullOrEmpty(SearchText) Then
FeedGrid.FilterExpression = ""
ElseIf e.Parameters = "Search" Then
FeedGrid.FilterExpression = New GroupOperator(GroupOperatorType.Or, New FunctionOperator(FunctionOperatorType.Contains, New OperandProperty("Title"), SearchText), New FunctionOperator(FunctionOperatorType.Contains, New OperandProperty("From"), SearchText)).ToString()
End If
End Sub
Protected Sub FeedGrid_CustomColumnDisplayText(ByVal sender As Object, ByVal e As ASPxGridViewColumnDisplayTextEventArgs)
If (Not String.IsNullOrEmpty(SearchText)) AndAlso (e.Column.FieldName = "From" OrElse e.Column.FieldName = "Title") Then
Dim text As String
If String.IsNullOrEmpty(e.DisplayText) Then
text = e.Value.ToString()
Else
text = e.DisplayText
End If
e.DisplayText = New Regex(SearchText, RegexOptions.IgnoreCase).Replace(text, "<span class='hgl'>$0</span>")
End If
End Sub
Protected Function FormatFeedItem(ByVal feedItem As SyndicationItem) As String
Return String.Format(FeedItemPreviewFormat, feedItem.Title.Text, GetCreator(CurrentFeed, feedItem), feedItem.Links(0).Uri.AbsoluteUri, feedItem.Summary.Text)
End Function
Protected ReadOnly Property CurrentFeed() As SyndicationFeed
Get
Return GetFeed(FeedNavBar.SelectedItem.Text)
End Get
End Property
Private Function GetFeed(ByVal key As String) As SyndicationFeed
If (Not FetchedFeeds.ContainsKey(key)) OrElse DateTime.Now.Subtract(LastFeedFetchTime) > FeedTTL Then
SyncLock FeedFetchLock
Using reader = New XmlTextReader(FeedRegistry(key))
FetchedFeeds(key) = SyndicationFeed.Load(reader)
End Using
LastFeedFetchTime = DateTime.Now
End SyncLock
End If
Return FetchedFeeds(key)
End Function
Private Sub LoadFeedToGrid()
Dim data = SelectData()
If data IsNot Nothing Then
FeedGrid.DataSource = data
FeedGrid.DataBind()
Else
FeedGrid.SettingsText.EmptyDataRow = String.Format("Please accept our apologies for the inconvenience. The feed URL is currently unavailable: {0}", FeedRegistry(FeedNavBar.SelectedItem.Text))
FeedGrid.Settings.ShowFooter = False
End If
End Sub
Private Function SelectData() As Object
Try
Return _
From i In CurrentFeed.Items _
Where (Not i.Summary.Text.Contains("<object")) AndAlso (Not i.Summary.Text.Contains("<embed")) AndAlso (Not i.Summary.Text.Contains("<iframe")) AndAlso (Not i.Summary.Text.Contains("Server Error")) _
Select New With {Key .ID = i.Id, Key .Date = i.PublishDate, Key .From = GetCreator(CurrentFeed, i), Key .Title = i.Title.Text, Key .Description = i.Summary.Text, Key .Url = i.Links(0).Uri.AbsoluteUri}
Catch
Return Nothing
End Try
End Function
Private Function GetCreator(ByVal feed As SyndicationFeed, ByVal item As SyndicationItem) As String
If item.Authors.Count > 0 Then
If ((item.Authors(0).Name) IsNot Nothing) Then
Return item.Authors(0).Name
Else
Return item.Authors(0).Email
End If
End If
Dim creator = item.ElementExtensions.FirstOrDefault(Function(e) e.OuterName = "creator")
If creator IsNot Nothing Then
Return creator.GetReader().ReadInnerXml()
End If
Return feed.Title.Text
End Function
Private Sub PrepareMasterSplitter()
Dim rootHolder = TryCast(Page.Master.Master.FindControl("RootHolder"), ContentPlaceHolder)
Dim pane = (CType(rootHolder.FindControl("LayoutSplitter"), ASPxSplitter)).GetPaneByName("LeftPane")
pane.PaneStyle.BorderTop.BorderWidth = 0
End Sub
End Class