Tag: code


RMine iphone app

I just released RMine, an open source iPhone application for interacting with a Redmine project management server over on github. This is actually the second incarnation of RMine, the first one was a bit more basic and was pretty much our first iPhone application.

This version is newer and snazzier and comes with its own redmine plugin for now. Eventually the goal will be to have it run with out-of-the-box redmine 0.9 or 0.10 when the restful api is far enough along where nothing else is needed. I am told that progress is being made every week on that front so it should not be long now.

Screenshots:
RMine iphone app
RMine iphone app
RMine iphone app

Check it out..

Redmine2Twitter

What do you do when you have mail, instant messages, rss feeds, web pages, text messages and revision control to all keep up with? Myneid came up with an idea of getting redmine updates from within twitter, so I took a crack at it:

#!/usr/bin/env ruby
require 'rubygems'
gem 'feedtools'
gem 'htmltokenizer'
require 'feed_tools'
require 'html/htmltokenizer'
require 'twitter'

#your redmine url
feed_url = "http://redmine.yourcompany.net/projects/activity?format=atom&key=YOURRSSKEY"

#grab redmine data
feed = FeedTools::Feed.open(feed_url)
post_these = Array.new

#fetch salient pieces from this stream
feed.items.each do |act|
  tweet =  "#{act.title}"
  t = HTMLTokenizer.new(act.description)
  desc = String.new
  unless ARGV[0].nil? or ARGV[0] != 'full'
    while token = t.getTag('p')
      desc << t.getTrimmedText('p').gsub(/\n/, ' ')
    end
    tweet << "\t#{desc[0..137]}..."
  end
  if act.time >= 5.minutes.ago
    post_these << tweet
  end
end

#connect to twitter if we need to
if post_these.size > 0
  twitter = Twitter::Base.new('YOURTWITTERUSERNAME', 'YOURTWITTERPASSWORD')
end

#post the oldest first
for tweet in post_these.reverse
  status = twitter.post(tweet)
end


Beware, this script has no real error checking, but as long as your credentials and access key are all correct it should be golden. You will need the feedtools, twitter, and html tokenizer gems to get it to run.

I run this from cron every 5 minutes. As long as the redmine server and the server that the cron is run from both have accurate system clocks it should work well. A more elaborate version some day may include more error checking and dupe checking.

Have fun out there.

Time Sensitive Background

I just added a new feature to my website. If you notice, the top graphic is somewhat like a sky. Now it changes depending on the time of day you are visiting my website. However, I did not accomplish this by making multiple graphics, and changing them out. I actually wrote a new model for rails that uses the Imagemagick/MiniMagick image processing library to accomplish this. So every few minutes of the day when it is called it will actually tint the picture an appropriate shade. It also saves these images, so they only have to be generated once. Here is the code for the model:

require 'rubygems'
gem 'mini_magick'
require 'mini_magick'

class Tphoto
  attr_accessor :time, :file
  def initialize(time,file)
    @filename = file
    @noon = Time.parse("%Y-%m-%d " << "12:45:00")
    distance = time.to_i - @noon.to_i
    if(distance > 0) then
      time = time - (distance * 2)
    end
    @seconds = time.strftime("%H%M").to_i/10
    @viewurl = "/images/tphoto/#{@seconds}/#{@filename}"
    unless File.exist?("#{RAILS_ROOT}/public/images/tphoto/#{@seconds}/#{@filename}")
      generate_time(@seconds, @file)
    end
  end

  def generate_time(seconds, file)
    unless File.exist?("#{RAILS_ROOT}/public/images/tphoto/#{@seconds}")
       Dir.mkdir("#{RAILS_ROOT}/public/images/tphoto/#{@seconds}")
    end
    image = MiniMagick::Image.from_file("#{RAILS_ROOT}/public/images/tphoto/#{@filename}")
      image.combine_options do |c|
        c.fill("#FFFFFF")
        c.tint(seconds+10)
    end
    image.write("#{RAILS_ROOT}/public/images/tphoto/#{@seconds}/#{@filename}")
  end

  def viewurl
    return @viewurl
  end

  def filepath
    return "#{RAILS_ROOT}/public/images/tphoto/#{@seconds}/#{@filename}"
  end

end

and here is the code for the controller:

class TphotoController < ApplicationController
  def index
    @time = Time.now
    @tphoto = Tphoto.new(@time, "monday.jpg")
    @response.headers['Last-Modified'] = Time.now.httpdate
    @response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
    @response.headers['Pragma'] = 'no-cache'
    @response.headers['Expires'] = 'Thu, 19 Nov 1981 08:52:00 GMT'
    send_file @tphoto.filepath, :type => 'image/jpeg', :disposition => 'inline'
  end
end

FLV Files in C++

This took me a bit of stumbling around before I found it, but if anyone is working with raw flv (Flash video) files, here is how you could print a header. I am using this in a cgi program that is designed to stream flv files from any point in the file. If it seeks to a point that is not the beginning, then it has to print this header so that the flash player is not confused about what kind of file it is:

cout << "FLV";
cout << '\x01';
cout << '\x01';
cout << '\x00';
cout << '\x00';
cout << '\x00';
cout << '\x09';
cout << '\x00';
cout << '\x00';
cout << '\x00';
cout << '\x09';

Human Time

I recently added the capability to display time in more human friendly terms. Basically, instead of saying Posted at 2007-11-30 20:18:36, a relevant post will say "posted 3 days ago". You can see this on every post or twitter on my site. I did not realize the full potential of Ruby until I sat down to write the code to make this happen. I simply extended Ruby's default Time class with the following:

class Time
   def humantime
            age = Time.now.to_i - self.to_i
            seconds_max = 60
            minutes_max = 3600
            hours_max   = 86400
            days_max    = 604800
            weeks_max   = 2629743
            months_max  = 31556926
            p = ''
            unit = ' second'
            if age < seconds_max
                amt = age
            elsif age < minutes_max
                amt = age/seconds_max
                unit = ' minute'
            elsif age < hours_max
                amt = age/minutes_max
                unit = ' hour'
            elsif age < days_max
                amt = age/hours_max
                unit = ' day'
            elsif age < weeks_max
                amt = age/days_max
                unit = ' week'
            elsif age < months_max
                amt = age/weeks_max
                unit = ' month'
            else
                amt = age/months_max
                unit = ' year'
            end

            if amt > 1
              p = 's'
            end

            humantime = amt.to_s + unit + p + " ago"
       end
end

So now, to get the time in human time, I just call the .humantime method that is now a part of every Time object.

Tag cloud

  1. 1 entries are tagged with 2007
  2. 1 entries are tagged with 2008
  3. 1 entries are tagged with 2009
  4. 2 entries are tagged with 2010
  5. 2 entries are tagged with applevalley
  6. 1 entries are tagged with archlinux
  7. 1 entries are tagged with artichoke
  8. 1 entries are tagged with automation
  9. 1 entries are tagged with batcountry
  10. 1 entries are tagged with beats
  11. 1 entries are tagged with bigsur
  12. 3 entries are tagged with bm2009
  13. 8 entries are tagged with burningman
  14. 1 entries are tagged with christmas
  15. 5 entries are tagged with code
  16. 1 entries are tagged with cplusplus
  17. 1 entries are tagged with desert
  18. 1 entries are tagged with drinks
  19. 1 entries are tagged with dspam
  20. 2 entries are tagged with dunes
  21. 1 entries are tagged with energy
  22. 1 entries are tagged with esplanade
  23. 5 entries are tagged with europe
  24. 1 entries are tagged with evdo
  25. 2 entries are tagged with flv
  26. 1 entries are tagged with gadgets
  27. 1 entries are tagged with government
  28. 1 entries are tagged with haiku
  29. 1 entries are tagged with icecast
  30. 1 entries are tagged with internetradio
  31. 1 entries are tagged with iphone
  32. 2 entries are tagged with losangeles
  33. 1 entries are tagged with math
  34. 3 entries are tagged with mix
  35. 1 entries are tagged with motivation
  36. 1 entries are tagged with moving
  37. 3 entries are tagged with music
  38. 1 entries are tagged with newserver
  39. 1 entries are tagged with obama
  40. 1 entries are tagged with oil
  41. 1 entries are tagged with productivity
  42. 1 entries are tagged with radio
  43. 1 entries are tagged with rails
  44. 3 entries are tagged with recipe
  45. 1 entries are tagged with redmine
  46. 2 entries are tagged with reflections
  47. 1 entries are tagged with rmine
  48. 8 entries are tagged with ruby
  49. 1 entries are tagged with salmon
  50. 1 entries are tagged with salsa
  51. 1 entries are tagged with shoutcast
  52. 3 entries are tagged with site
  53. 2 entries are tagged with snow
  54. 1 entries are tagged with spill
  55. 1 entries are tagged with spotmanradio
  56. 1 entries are tagged with streamtranscoder
  57. 1 entries are tagged with summer
  58. 1 entries are tagged with tecate
  59. 1 entries are tagged with thanksgiving
  60. 6 entries are tagged with travel
  61. 1 entries are tagged with trip
  62. 1 entries are tagged with turkey
  63. 3 entries are tagged with twitter
  64. 1 entries are tagged with website
  65. 3 entries are tagged with work
  66. 1 entries are tagged with x4200
  67. 3 entries are tagged with yz250

Twitter Updates

Links to check out

Subscribe RSS