LuckyCatLabs

Making code suck less

Release (Sort-of): RubySunrise Gem

As a follow-up to the Java sunrise/sunset calculator I released early last year, I’m releasing a ruby gem that does essentially the same thing. Just in A LOT less code, but with the same attention to test goodness.

To install and use the RubySunrise gem just:

$ gem install RubySunrise

or download from RubyGems.

The current version as of today is 0.2, which requires the tzinfo gem (link) to perform the timezone offset lookups.

If you want/need the lastest, just grab it from the github repo:

$ git clone git://github.com/mikereedell/sunrisesunset-ruby
$ gem build RubySunrise

At this time the RubySunrise gem covers astronomical, nautical, civil, and official sunrise/sunset calculations for every location that experiences a sunrise and sunset every day (Sorry Alaska!). I’m currently working on the strangeness that is causing my Alaskan test suite to fail with known-good data.

Example time:

require 'solareventcalculator'

date = Date.parse('2008-11-01')
calc = SolarEventCalculator.new(date, BigDecimal.new("39.9537"), BigDecimal.new("-75.7850"))

utcOfficialSunrise = calc.compute_utc_official_sunrise
localOfficialSunrise = calc.compute_official_sunrise('America/New_York')

puts "utcOfficialSunrise #{utcOfficialSunrise}"
puts "localOfficialSunrise #{localOfficialSunrise}"

Which yields:

utcOfficialSunrise 2008-11-01T11:33:00+00:00
localOfficialSunrise 2008-11-01T07:33:00-04:00

The source is available under the Apache License, Version 2.0:
http://github.com/mikereedell/sunrisesunset-ruby

View Comments

Maven with Ruby Part II

Want to add something to your projects Maven builds (like code coverage…) but don’t want to CTL-C/CTL-V your way to boredom? Use the below script to lend a hand. Substitute the XML in the SNIPPET variable to the artifact/plugin/dependency to be injected (leave the tag in place) and use the command:

$>ruby mavenInjector.rb /xpath/to/element

Here’s the code. Check the git repository for the latest.

In the beginning of the ‘for’ loop in the inject method I remove the read-only bit from the file. This is for those of us afflicted with ClearCase and can be removed for those fortunate enough to use a sane SCM.

#/usr/bin/env ruby
require 'rexml/document.rb'
require 'fileutils.rb'

class MavenInjector

  def inject(path)
    if(path == nil)
      puts 'Must provide the root path of the node to inject under.'
      exit
    end

    poms = Dir[Dir.pwd() + "/**/pom.xml"]

    for pom in poms do
      if(!File.writable?(pom))
        FileUtils.chmod 0644, pom
      end

      pomXML = REXML::Document.new(File.new(pom))
      element = pomXML.get_elements(path)[0]

      if(element == nil)
        parentElement = pomXML.get_elements("/project/build")[0]
        element = REXML::Element.new("plugins", parentElement)
      end

      for plugin in getElementsToInject() do
        element.add_element(plugin)
      end

      formatter = REXML::Formatters::Default.new(4)
      formatter.write(pomXML, File.new(pom, "w+"))
    end
  end

  def getElementsToInject()
    elementXML = REXML::Document.new(SNIPPET)
    return elementXML.get_elements("/inject/plugin")
  end
end

SNIPPET = <

    org.codehaus.mojo
    cobertura-maven-plugin
    

html
        
    
  

HEAD

MavenInjector.new.inject(ARGV[0])

Any questions/problems/enhancements are welcome in the comments.

View Comments

Using Ruby To Help Maven

Maven projects can become a wasteland of neglected, old dependencies: huge, unmanageable pom files and a local repository that’s catalog of every Apache project in the past 10 years. Who knows if your project still requires that old version of Xerces?

This script takes the name of a dependency and removes it from every pom.xml in any sub-directory from where it’s called, removing the dependency element for the given jar file from each one. The script also saves the tree in the file $artifactname.xml in case you need to put it back.

#/usr/bin/env ruby
require 'rexml/document.rb'

if(ARGV[0] == nil)
  puts 'Must provide the name of the artifact to remove.'
  exit
end

artifact = ARGV[0].chomp
poms = Dir[Dir.pwd() + "/**/pom.xml"]

for pom in poms do
  pomXML = REXML::Document.new(File.new(pom))
  element = pomXML.get_elements("//dependency[artifactId='" + artifact + "']")[0]

  if(element != nil)
    temp = File.new(artifact + ".xml", "w+")
    formatter = REXML::Formatters::Default.new()
    formatter.write(element, temp)
    puts "Removing the dependency: " + artifact + "\nfrom " + pom
    element.parent.delete(element)
    pomXML.write(File.new(pom, "w+"))
  else
    puts "No artifacts with the name:'" + artifact + "' were found."
  end
end
View Comments

Licensing Your Code the Ruby Way

Do you have an existing project you want to open-source? Does the thought of manually adding the license comment block to EVERY. SINGLE. SOURCE. FILE. sound not-so-exciting? Here’s some help, ruby style:

class Licenser

    def licenseFiles(dir)
          filenames = Dir[dir.chop + "**/*.java"]
	  for filename in filenames do
              contents = ''
              File.open(filename, 'r') { |file| contents = file.read }
              contents = HEADER + contents
              File.open(filename, 'w') { |file| file.write(contents) }
          end
    end
end

HEADER = <<HEAD
/*
 * Copyright 2008-2009 Mike Reedell / LuckyCatLabs.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

HEAD

	Licenser.new.licenseFiles(ARGV[0])

This script was inspired by the the check_license_headers.rb script in the Apache SVN repo. Couldn’t get it to work on my setup, so I rewrote the parts I needed.

This can be found in the LuckyCat Labs GitHub scripts project. Look for updates to handle more source types and to check for existing license headers.

View Comments

Release: Sunrise/Sunset Java Library

New from LuckyCat Labs is a Java library that computes the sunrise / sunset using GPS coordinates and today’s date.  To use, simply download the tar or zip file from the GitHub page, or use git to pull the source:

$ git clone git://github.com/mikereedell/sunrisesunsetlib-java

Once you have the source, use the command:

$ ant all

To compile the source, build the bin, src, and test jars, execute the unit tests and generate the JavaDoc for the library.

This code snippet illustrates the main usage pattern:

// Location of sunrise/set, as latitude/longitude.
Location location = new Location("39.9937", "-75.7850");

// Create calculator object with the location and time zone identifier.
SunriseSunsetCalculator calculator = new SunriseSunsetCalculator(location, "America/New_York");

Calendar date = Calendar.getInstance();
String dawn = calculator.getCivilSunriseForDate(date);
String dusk = calculator.getCivilSunsetForDate(date);

The list of supported time zone identifiers is given by:

//Returns String[] of supported tz identifiers.
TimeZone.getAvailableIDs();

Any feedback? Comments? Features? Bugs? Comment below or add to the project wiki.

Released under the Apache License 2.0.

View Comments