Jonathan Gnagy's Blog

Rails for everyone!

Listing all entries tagged 'blog additions'. Feed

Even More Blog Improvements

I’ve had some time to burn since I’m not working for a couple weeks while I’m on paternity leave. During the night, my wife and I take shifts watching Marissa sleep (yeah, we’re paranoid like that). During my last shift (this one), I’ve accomplished quite a bit. I’ve managed to:

  • Utilize Google’s Translate javascript API to provide site-wide translations
  • Create a fully-functional, albeit simple, Todo / Checklist system and integrate into my blog
    • Uses Scriptaculous effects
    • I serialized the list items into an Array, so I only need a single column for an arbitrary number of list items. Also, no need for a separate “ListItems” model / table.
    • It allows me to mark lists as public, so everyone can see them. By default lists are private.
    • All adding and removing from the list is done via Ajax (with a non-javascript HTTP/1.0 POST fall-through), so it looks pretty snazzy.
    • I’ve started an experimental option to apply my tagging system to lists as well, but I haven’t figured out how I will make it all work, or how to display it.
  • Polish up some sections of my site that weren’t quite passing XHTML 1.0 Strict compliance tests. I’m sure there are more out there, so feel free to comment if you happen to come upon a page this isn’t. Come to think of it, I’m sure the list stuff isn’t yet, since I didn’t check it.
  • Make more of the site RESTful and support more pure XML operations (for scripting and such).

I’m sure I did more stuff, but I can’t really remember it right now. My eyes are awfully blurry… I’ll try to figure out some code to post tomorrow.

New Blog Features

I added some minor improvements to my blog. Some of these feature include:

  • All tags now offer feeds, even if they aren’t in the “Popular Tags”. Just click on the tag, and the grey banner contains a feed link.
  • All successful searches (i.e., those that return results) allow for subscriptions via Atom feeds. Similar to tag feeds, they exist in the grey banner that details the search term.
  • All uploaded media is available and searchable from the newly added “Media” link under the also newly added “Extras” section on the right.
  • Several small improvements to admin areas…

Here’s some code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def feeds
    case params[:feed]
      when "all"
        @entries = Entry.find(
          :all, 
          :limit => 25, 
          :order => "updated_at DESC"
        )
      when "by_tag"
        @entries = Tag.find_by_name(params[:tag]).entries.find(
          :all, 
          :limit => 25, 
          :order => 'updated_at DESC'
        )
      when "by_search"
        query = "%#{params[:q]}%"
        @entries = Entry.find(
          :all, 
          :conditions => ["body LIKE ?", query], 
          :limit => 25, 
          :order => 'updated_at DESC'
        )
    end # case params[:feed]
    respond_to do |format|
      format.atom  { render :layout => nil }
    end
end

Got SPAM?

My blog got its first spam bot attack yesterday. I cleaned it up, of course, but I’d like for it to not happen again. So i’m trying something I found on another Ruby on Rails dev’s blog. We’ll see if this does the trick for a little while…

Media + Blog = Happy

I’ve added the ability for me to upload images to my blog. I designed the feature so I can easily expand it to include other kinds of media, such as Video and Audio, but I just finished the images portion. I figured it would be worth mentioning. Here’s an example:

My Face

The syntax I’m using supports in-line styling, but its not as easy as I’d like it to be. I used the following to display the image:


!{width: 200px;}/blog/images/uploaded/face.jpg(My Face)!

Not exactly the cleanest syntax for using media I manage with a database… Maybe someday, I’ll add support for a special tag, like I do with [code][/code].

XMPP with Rails

In the beginning, my blog didn’t have any way to notify me when someone comments on an entry. After a while, I added an ActionMailer class (called Notifier) to email me when a comment is saved. Realizing that this might open up the door for people to spam me, I added some very basic spam checking, looking for certain inappropriate key words through regular expression matching. Maybe some day I’ll actually try and tie-in Spamassassin or something.

Today, I added a couple more advancements in regards to comments. Now, it also sends me an Instant Message through Jabber (XMPP) notifying me of a new comment. I also decided to move the sending of the email and the instant message to its own thread because I noticed some slowness when testing new comments. Now things are fast and smooth again.

Here’s the code I used to make the IM and email happen:

Add this to the Comment model:

1
2
3
4
5
6
7
...
  protected
  def validate
    SPAM_REGEXES.each do |r|
      errors.add("body", "fails SPAM checks") if body.match(r)
    end
  end

Add this to the Comment controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
    if @comment.save
      t = Thread.new do
        Notifier.deliver_comment_notification(@comment.entry.author, @comment)
        begin
          # Connect to the server and set presence to available for chat.
          client = Jabber::Simple.new('jlg_blog_bot@jabber.org/blog', JABBER_PASSWORD.to_s)
          client.deliver(
            @comment.entry.author.email, 
            "You have a new comment on your blog entry titled '#{@comment.entry.title}'",
            :normal
          )
          sleep(1)
          client.disconnect
          logger.info "Sent XMPP message about: '#{@comment.entry.title}'"
        rescue
          logger.warn "Sending of XMPP message failed..."
        end
      end # new thread
    else
      # If the comment wasn't saved, it was probably marked as spam
      flash[:warn] = "Your comment was not saved. Perhaps it was flagged as spam."
    end
...

You still need to modify the ‘config/environment.rb’ file to include definitions for JABBER_PASSWORD and SPAM_REGEXES.