YAFLogo

Posted by: MC9000 - Tuesday, 3 December 2013 07:36:52
Is it possible to inject an external RSS feed into a topic?

Posted by: Zero2Cool - Tuesday, 3 December 2013 15:00:57
Outside of YAF, yes. Here's a snippet to get you started off. [code=csharp] #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 [/code]

Posted by: MC9000 - Tuesday, 3 December 2013 21:51:28
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.

Posted by: Zero2Cool - Wednesday, 4 December 2013 14:26:20
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

Posted by: MC9000 - Thursday, 5 December 2013 00:45:45
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

Posted by: MC9000 - Thursday, 5 December 2013 00:47:32
the winking smileys are supposed to be right parenthesis

Posted by: MC9000 - Thursday, 5 December 2013 00:51:51
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

Posted by: MC9000 - Thursday, 5 December 2013 01:01:12
Here is the feed inside the topic live: [url=http://goammo.com/default.aspx?g=posts&t=3#post3]RSS feed inside topic message[/url] warning: it looks like crap if you are in edit mode due to the CSS

Posted by: Zero2Cool - Thursday, 5 December 2013 01:31:28
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 [url=http://packershome.com/latest.aspx]HERE [/url]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. :) [code=vb] 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 [/code]

Posted by: MC9000 - Thursday, 5 December 2013 09:28:27
Nice site! I still have to figure out how I'm going to seed my forum :)

Posted by: Zero2Cool - Thursday, 5 December 2013 14:11:43
[quote=MC9000;62103]Nice site! I still have to figure out how I'm going to seed my forum :) [/quote] 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.

Posted by: MC9000 - Saturday, 7 December 2013 02:38:20
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