YAFLogo

MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
Is it possible to inject an external RSS feed into a topic?
Sponsor

Zero2Cool
  • Zero2Cool
  • 100% (Exalted)
  • YAF Leader YAF Version: YAF 3.1.16
10 years ago
Outside of YAF, yes.

Here's a snippet to get you started off.


     #region New Topic, Create It
        protected bool CreateTopic(string Author, string Subject, string Message, string Description, string Link, int ForumID)
        {
            using (SqlConnection connection = new SqlConnection(conn.ConnectionString))
            {
                try
                {
                    connection.Open();

                    SqlCommand command = new SqlCommand("yaf_topic_save", connection);

                    command.CommandType = CommandType.StoredProcedure;


                    Message = string.Format("[quote=[url={0}]{1}[/url]] {2}[/quote]", Link, Author, Message);

                    int Priority = 0;

                    command.Parameters.Add(new SqlParameter("@ForumID", ForumID));
                    command.Parameters.Add(new SqlParameter("@Subject", Subject));
                    command.Parameters.Add(new SqlParameter("@UserID", 2424));
                    command.Parameters.Add(new SqlParameter("@Message", Message));
                    command.Parameters.Add(new SqlParameter("@Description", Description));
                    //command.Parameters.Add(new SqlParameter("@Status", "RSS"));
                    command.Parameters.Add(new SqlParameter("@Priority", Priority));
                    command.Parameters.Add(new SqlParameter("@UserName", DBNull.Value));
                    command.Parameters.Add(new SqlParameter("@IP", "44.33.22.11"));
                    //command.Parameters.Add(new SqlParameter("@Posted", PublishedDate));
                    command.Parameters.Add(new SqlParameter("@Posted", DateTime.UtcNow.AddMinutes(-1)));
                    command.Parameters.Add(new SqlParameter("@BlogPostID", DBNull.Value));
                    command.Parameters.Add(new SqlParameter("@Flags", 22));
                    command.Parameters.Add(new SqlParameter("@UTCTIMESTAMP", DateTime.UtcNow.AddMinutes(-1)));

                    command.CommandTimeout = 5;

                    command.ExecuteNonQuery();

                    return true;
                }
                catch (Exception ex)
                {
                    ErrorMessage = ex.Message + Environment.NewLine + ex.StackTrace;
                    return false;
                }

            }
        }
        #endregion

MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
Thanks! - I was originally worried about dependencies on the SQL side, but the code is very easy to follow (even for a VB.Net guy)
I wrote a standalone feed reader (for another project) that I can modify to insert the retrieved feed data into the same message record. Simpler than I thought.

Glad to see stored procedures are used in YAF - other projects are eliminating stored procs & replaced everything w/LINQ, but they don't scale at all and run much slower.
Zero2Cool
  • Zero2Cool
  • 100% (Exalted)
  • YAF Leader YAF Version: YAF 3.1.16
10 years ago
Do you have your feed reader as open source? The one I have is kind of a crapshoot. When I add a new feed I have to run it through step by step to ensure the date parser doesn't blow up lol
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
It's a work in progress and part of a bigger project (I'll probably open-source it eventually).
My code reads a list of RSS feeds from another XML file that loads in the FeedListParams containing the MessageID to update and some stuff to show pics, dates, etc. (I used a structure instead of a class for quick & dirty coding)
Public Structure FeedListParams
Public feeduri As String
Public feedtitle As String
Public messageid As Integer ' the MessageID of the SQL table
Public upperlimit As Integer 'how many RSS feed records to show
Public truncatetochars As Integer 'truncate the Description to this many chars
Public showdate As Boolean
Public showimages As Boolean
Public saveimageslocally As Boolean 'not implemented, but will grab any remote pics, resize& save
Public resizeimages As Boolean
Public maxpixels As Integer 'maximum width pixels - for formatting
Public showasseparatetopics As Boolean 'not implemented yet, but I plan on automatically putting in each feed record into their own separate topics
End Structure

'the FeedItem structure (you can use a class, but, once again, quick & dirty code)
Public Structure FeedItem
Public title As String
Public link As String
Public pubDate As String
Public description As String
Public enclosure As XmlNode 'this node usually has a picture URI - at least WordPress RSS feeds do
End Structure

'in another function, you can call Message = ProcessRSS(f) where f is the structure FeedListParams
'the Message string variable will contain the entire message.
You first have to create the initial topic (and put a filler character to start), make the topic "sticky", find the corresponding MessageID (for that Topic) from the table in the database so you know where to update it.


Public Function ProcessRSS(f As FeedListParams) As String
Dim request As WebRequest = WebRequest.Create(f.feeduri)
Dim response As WebResponse = request.GetResponse()
Dim sb As New StringBuilder("")
Dim rssStream As Stream = response.GetResponseStream()
Dim rssDoc As New XmlDocument()
rssDoc.Load(rssStream)
Dim rssItems As XmlNodeList = rssDoc.SelectNodes("rss/channel/item")

Dim Item As FeedItem
Dim totalCount As Integer = rssItems.Count
If totalCount > f.upperlimit Then
totalCount = f.upperlimit
End If
If totalCount > 0 Then
sb.Append("

" + f.feedtitle + "

")
sb.Append("
")
sb.Append("
    ")
    Dim i As Integer = 0
    While i < totalCount

    sb.Append("
  • ")
    Dim imageURI As String = "../images/sp75.png" 'padding pic
    If f.showimages Then
    Item.enclosure = rssItems.Item(i).SelectSingleNode("enclosure")
    If Item.enclosure IsNot Nothing Then
    imageURI = ObjToStr(Item.enclosure.Attributes("url").Value)
    End If
    End If
    sb.Append("")
    Item.title = ObjToStr(rssItems.Item(i).SelectSingleNode("title").InnerXml.ToString.Trim).Replace("'", "''")
    Item.link = ObjToStr(rssItems.Item(i).SelectSingleNode("link").InnerXml.ToString.Trim).Replace("'", "''")
    sb.Append("

    " + Item.title + "

    ")

    Item.pubDate = String.Empty
    If f.showdate Then
    Item.pubDate = ObjToDate(rssItems.Item(i).SelectSingleNode("pubDate").InnerXml.ToString.Trim).ToShortDateString
    sb.Append("
    Published On: " & Item.pubDate & "
    ")
    End If





    'NOTE: I replaced the CDATA tags via simple replace - there are better ways of doing this
    Item.description = ObjToStr(rssItems.Item(i).SelectSingleNode("description").InnerXml.ToString.Trim).Replace("", "").Replace("’", "'").Replace("—", "--").Replace("'", "''")
    sb.Append("

    " & Item.description & "

    ")
    sb.Append("
  • ")
    i += 1
    End While
    sb.Append("
")
End If
Return sb.ToString()
End Function



SOME CSS: (added into the theme css file)
#rsstitle {
color: #295885;
font-size: 12px;

}
.rsswrap {
font-family: Verdana;
line-height: 15px;
color: #000;
}
.rsswrap ul li {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
border-bottom: 1px solid #E8E8E8;
display: block;
float: left;
font-size: 11px;
list-style-type: none;
padding: 10px 0;
width: 100%;
}
.rsswrap ul li img {
float: left;
margin-right: 5px;
margin-bottom: 30px;
width: 75px;
border: 0 none;
outline: medium none;
}
.rsswrap ul li a {
color: #295885;
text-decoration: none;
}
.rsswrap ul li a h3 {
color: #295885;
text-decoration: none;
font-size: 14px;
margin: 0;
padding: 0;
}
.rsspubdate {
color: #959595;
font-size: 10px;
}
.rsswrap ul li p {
padding-bottom: 14px;
font-size: 12px;
margin-top: 5px;
margin-bottom: 5px;

}



The stored proc:
CREATE PROCEDURE [dbo].[RSS_EXT_UpdateMessage]
(
@MessageID int,
@Message ntext
)
AS
BEGIN
SET NOCOUNT ON;

BEGIN TRY
update yaf_Message
set [Message]=@Message
where messageID=@MessageID;
SELECT 'SUCCESS';
END TRY
BEGIN CATCH
SELECT 'ERROR';
END CATCH;

END
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
the winking smileys are supposed to be right parenthesis
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
Oh, the helper functions: I use these for safely converting objects with optional defaults (been using for years)

Public Shared Function ObjToInt(ByVal o As Object, Optional ByVal DefaultValue As Integer = 0I) As Integer
Dim retval As Integer = DefaultValue
If IsDBNull(o) OrElse IsNothing(o) Then
retval = DefaultValue
Else
Try
If IsNumeric(o) Then
retval = Convert.ToInt32(o)
End If
Catch ex As InvalidCastException
retval = DefaultValue
End Try
End If
Return retval
End Function

Public Shared Function ObjToBoo(ByVal o As Object, Optional ByVal DefaultValue As Boolean = False) As Boolean
Dim retval As Boolean = DefaultValue
If IsDBNull(o) OrElse IsNothing(o) Then
retval = DefaultValue
Else
Try
If TypeOf o Is String Then
Dim s As String = DirectCast(o, String)
Select Case s.ToLower
Case "y", "yes", "t", "true", "1", "-1"
retval = True
Case Else
retval = False
End Select
Else
retval = Convert.ToBoolean(o)
End If
Catch ex As InvalidCastException
retval = DefaultValue
End Try
End If
Return retval
End Function

Public Shared Function ObjToStr(ByVal o As Object, Optional ByVal DefaultValue As String = "") As String
Dim retval As String = DefaultValue
If IsDBNull(o) OrElse IsNothing(o) Then
retval = DefaultValue
Else
Try
retval = Convert.ToString(o)
Catch ex As InvalidCastException
retval = DefaultValue
End Try
End If
Return retval
End Function

Public Shared Function ObjToDate(ByVal o As Object, Optional ByVal DefaultValue As Date = #1/1/1900#) As Date
Dim retval As Date = DefaultValue
If IsDBNull(o) OrElse IsNothing(o) Then
retval = DefaultValue
Else
Try
retval = CType(o, DateTime)
Catch ex As InvalidCastException
retval = DefaultValue
End Try
End If
Return retval
End Function
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
Here is the feed inside the topic live:

RSS feed inside topic message 


warning: it looks like crap if you are in edit mode due to the CSS
Zero2Cool
  • Zero2Cool
  • 100% (Exalted)
  • YAF Leader YAF Version: YAF 3.1.16
10 years ago
Cool cool. I'll have to look into this more when I have time. I like the page you created, nice touch with images. The feeds I'm reading I don't believe have a image in the data.

With my RSS feeds, I'm collecting them, storing them in a table, then on this page HERE  I display the 15 most recent articles. If you're logged in, you can see a "Discuss" button and once clicked, it'll create a topic in the forums for discussion. The actual page is all hard coded and needs to be redesigned. If I won the dang lottery I'd have enough time to do this how I want instead of just 'get it done' lol

btw, if you weren't already aware, there's a code BBCode to stop those pesky smilies in YAF. :)



        Public Shared Function ObjToInt(ByVal o As Object, Optional ByVal DefaultValue As Integer = 0I) As Integer
            Dim retval As Integer = DefaultValue
            If IsDBNull(o) OrElse IsNothing(o) Then
                retval = DefaultValue
            Else
                Try
                    If IsNumeric(o) Then
                        retval = Convert.ToInt32(o)
                    End If
                Catch ex As InvalidCastException
                    retval = DefaultValue
                End Try
            End If
            Return retval
        End Function

        Public Shared Function ObjToBoo(ByVal o As Object, Optional ByVal DefaultValue As Boolean = False) As Boolean
            Dim retval As Boolean = DefaultValue
            If IsDBNull(o) OrElse IsNothing(o) Then
                retval = DefaultValue
            Else
                Try
                    If TypeOf o Is String Then
                        Dim s As String = DirectCast(o, String)
                        Select Case s.ToLower
                            Case "y", "yes", "t", "true", "1", "-1"
                                retval = True
                            Case Else
                                retval = False
                        End Select
                    Else
                        retval = Convert.ToBoolean(o)
                    End If
                Catch ex As InvalidCastException
                    retval = DefaultValue
                End Try
            End If
            Return retval
        End Function

        Public Shared Function ObjToStr(ByVal o As Object, Optional ByVal DefaultValue As String = "") As String
            Dim retval As String = DefaultValue
            If IsDBNull(o) OrElse IsNothing(o) Then
                retval = DefaultValue
            Else
                Try
                    retval = Convert.ToString(o)
                Catch ex As InvalidCastException
                    retval = DefaultValue
                End Try
            End If
            Return retval
        End Function

        Public Shared Function ObjToDate(ByVal o As Object, Optional ByVal DefaultValue As Date = #1/1/1900#) As Date
            Dim retval As Date = DefaultValue
            If IsDBNull(o) OrElse IsNothing(o) Then
                retval = DefaultValue
            Else
                Try
                    retval = CType(o, DateTime)
                Catch ex As InvalidCastException
                    retval = DefaultValue
                End Try
            End If
            Return retval
        End Function 

MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
Nice site! I still have to figure out how I'm going to seed my forum 🙂
Zero2Cool
  • Zero2Cool
  • 100% (Exalted)
  • YAF Leader YAF Version: YAF 3.1.16
10 years ago
Originally Posted by: MC9000 

Nice site! I still have to figure out how I'm going to seed my forum 🙂


Thanks.

I have a table of RSS Links that a separate program reads every X minutes. If it finds a new Summary greater than the date of the last one, it inserts into a database. Then the page above just grabs the top 15.

I'm wanting to move it from an EXE and have it done via web service, but I have zero experience with that so it might not even be possible.
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
10 years ago
check out NopCommerce's scheduled tasks feature (on the admin side) - the source code is free. www.nopcommerce.com,
it's probably a good start since it will run background tasks in asp.net
YAF Logo Copyright © YetAnotherForum.NET & Ingo Herbote. All rights reserved
About Us

The YAF.NET is an open source .NET forum project. YAF.NET is supported by an team of international developers who are build community by building community software.

Powered by Resharper Donate with PayPal button