YAFLogo

MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
11 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
11 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
11 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
11 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
11 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
11 years ago
the winking smileys are supposed to be right parenthesis
MC9000
  • MC9000
  • 60.2% (Friendly)
  • YAF Camper Topic Starter
11 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
11 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
11 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
11 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
11 years ago

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

Originally Posted by: MC9000 

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