Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Thursday, November 21, 2013

oracle and apache cxf

How to setup Ruby and new Oracle Instant Client on Leopard

http://blog.rayapps.com/2008/04/24/how-to-setup-ruby-and-new-oracle-instant-client-on-leopard/ ul>li*>a[href='$#']{$#}

Get Oracle Instant Client working on Mac. Then get it working with Ruby!

export DYLD_LIBRARY_PATH="/usr/local/oracle/instantclient_10_2"
export SQLPATH="/usr/local/oracle/instantclient_10_2"
export TNS_ADMIN="/usr/local/oracle/network/admin"
export NLS_LANG="AMERICAN_AMERICA.UTF8"
export PATH=$PATH:$DYLD_LIBRARY_PATH

RubyForge: ruby-oci8: Project Filelist

http://rubyforge.org/frs/?group_id=256

Download Ruby OCI8.

Tnsnames.ora - Oracle FAQ

http://www.orafaq.com/wiki/Tnsnames.ora

SERVICE_NAME is the same thing as SID?

ORA11 =
 (DESCRIPTION = 
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
   )
 (CONNECT_DATA =
   (SERVICE_NAME = ORA11)
 )
)

Another example

connection_label =
 (DESCRIPTION = 
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = server.name.org)(PORT = 1521))
   )
 (CONNECT_DATA =
   (SERVICE_NAME = service.name)
 )
)

Class: OCI8 - Documentation by YARD 0.7.5

http://ruby-oci8.rubyforge.org/en/OCI8.html

Documentation for OCI8. What are the parameters for the constructor again?

 - (OCI8) initialize(username, password, dbname = nil, privilege = nil) constructor 

Instant Client downloads for Mac OS X (Intel x86)

http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html

You need a username/password to get access to these, but it's no big deal.

It might also be handy to have Oracle JDBC drivers around as well.

Markdown - Wikipedia, the free encyclopedia

http://en.wikipedia.org/wiki/Markdown

I finally checked out how to add markdown for SO (Stack Overflow) entries.

Text attributes *Italic*, **bold**, `monospace`.

<p>Text attributes <em>Italic</em>,
<strong>bold</strong>,
<code>monospace</code>.</p>

Bash - Manipulating Strings - Substring Extraction

http://tldp.org/LDP/abs/html/string-manipulation.html

Extracts $length characters of substring from $string at $position.

${string:position:length}

echo ${stringZ:0}                            # abcABC123ABCabc
echo ${stringZ:1}                            # bcABC123ABCabc
echo ${stringZ:7}                            # 23ABCabc

echo ${stringZ:7:3}                          # 23A
                                             # Three characters of substring.

Apache CXF -- FAQ

http://cxf.apache.org/faq.html#FAQ-HowcanIturnonschemavalidationforjaxwsendpoint%3F

It appears there is a configuration setting that can be used to have Apache CXF handle validation. It also appears that this will not be a turn-key solution for me. Something is not quite right as it seems CXF doesn't have access to the XSD files, even though they are included in the class path.

Saturday, November 9, 2013

some points on message-level encryption

SSL and Certificates

The Most Common OpenSSL Commands

http://www.sslshopper.com/article-most-common-openssl-commands.html

Continues to be a great resources for keytool. Another similar resource exists for OpenSSL.

Southern Illinois University - File Encryption Guidelines and Procedures

http://pki.siu.edu/encrypting_files.html

basic 2-way ssl handshake

Web Help Desk Documentation Library | Installation | Importing an SSL Certificate

http://docs.webhelpdesk.com/m/5197/l/54068-importing-an-ssl-certificate

A CA Reply is the signed certificate, the result of a CA signing a certificate request (CSR).

Certificate chains may be of any length. The highest certificate in the chain, the root certificate, should be a self-signed certificate, signed by the trusted CA. Each certificate in the chain must imported into the keystore so that the complete chain can be sent to the browser. If the CA Reply does not include the chain certificates, they must be added to the keystore manually before the CA reply. The certificates must be imported in order of dependency—i.e., the root certificate must be added first, then the next chained certificate that was signed by the root certificate, and so on, down to the CA reply.

Michael Vorburger's Old Blog: Setting up two-way (mutual) SSL with Tomcat on Java5 is easy!

http://blog1.vorburger.ch/2006/08/setting-up-two-way-mutual-ssl-with.html

A pretty comprehensive tutorial on setting up 2-way SSL with Tomcat, including how to set up the keystores using keytool.

Bash

Bash Regular Expressions | Linux Journal

http://www.linuxjournal.com/content/bash-regular-expressions

Using regular expressions in bash and how to extract the match data values.

#!/bin.bash

if [[ $# -lt 2 ]]; then
    echo "Usage: $0 PATTERN STRINGS..."
    exit 1
fi
regex=$1
shift
echo "regex: $regex"
echo

while [[ $1 ]]
do
    if [[ $1 =~ $regex ]]; then
        echo "$1 matches"
        i=1
        n=${#BASH_REMATCH[*]}
        while [[ $i -lt $n ]]
        do
            echo "  capture[$i]: ${BASH_REMATCH[$i]}"
            let i++
        done
    else
        echo "$1 does not match"
    fi
    shift
done

Advanced Bash-Scripting Guide: Chapter 8.

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-8.html

Bash functions don't explicitly declare their variables. You just access $1, $2, $3, ... to access a function's parameters.

  #!/bin/bash 
  function quit {
     exit
  }  
  function e {
      echo $1 
  }  
  e Hello
  e World
  quit
  echo foo 

linux - Extract File Basename Without Path and Extension in Bash - Stack Overflow

http://stackoverflow.com/questions/2664740/extract-file-basename-without-path-and-extension-in-bash

Bash string manipulations can make easy work of parsing file names. Pretty cool!

  $ s=/the/path/foo.txt
  $ echo ${s##*/}
  foo.txt
  $ s=${s##*/}
  $ echo ${s%.txt}
  foo
  $ echo ${s%.*}
  foo

bash String Manipulations Issue 18

http://linuxgazette.net/18/bash.html

More information on bash string manipulations.

  Given:
      foo=/tmp/my.dir/filename.tar.gz 

  We can use these expressions:

  path = ${foo%/*}
      To get: /tmp/my.dir (like dirname)
  file = ${foo##*/}
      To get: filename.tar.gz (like basename)
  base = ${file%%.*}
      To get: filename 
  ext = ${file#*.}
      To get: tar.gz 

Advanced Bash-Scripting Guide: Chapter 7. Tests

http://tldp.org/LDP/abs/html/nestedifthen.html

Nested if/then condition tests.

  a=3

  if [ "$a" -gt 0 ]
  then
    if [ "$a" -lt 5 ]
    then
      echo "The value of \"a\" lies somewhere between 0 and 5."
    fi
  fi

  # Same result as:

  if [ "$a" -gt 0 ] && [ "$a" -lt 5 ]
  then
    echo "The value of \"a\" lies somewhere between 0 and 5."
  fi

Advanced Bash-Scripting Guide: Chapter 6. Tests

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-6.html

Conditionals with variables.

  #!/bin/bash
  T1="foo"
  T2="bar"
  if [ "$T1" = "$T2" ]; then
      echo expression evaluated as true
  else
      echo expression evaluated as false
  fi

Advanced Bash-Scripting Guide: Chapter 7. Other Comparison Operators

http://www.tldp.org/LDP/abs/html/comparison-ops.html

Integer comparisons is a little different from string comparison.

-eq

    is equal to
    if [ "$a" -eq "$b" ]

-ne

    is not equal to
    if [ "$a" -ne "$b" ]

-gt

    is greater than
    if [ "$a" -gt "$b" ]

-ge

    is greater than or equal to
    if [ "$a" -ge "$b" ]

Why can't a trusted public key with certificate chain be imported into my truststore and still retain it's chain?

open https://www.java.net//node/674524 https://www.java.net//node/674524

Apparently, in order to create a public key with a certificate chain that is recognized in one's truststore, they must be associated with a private key. Since any given keystore should only have one private key, and since it is not good form to carry around someone else's private key, it seems logical that the trusted certificate entries in one's truststore (or the trusted cert entries in one's keystore) not contain trusted cert entries with full keychains.

Yeah, it is a bit unintuitive, but you cannot import certificate chains *unless* they are associated with a private key (as in the CA's reply to the CSR). Check the docs on how to import to an existing key entry (need to specify its alias).

Ivaylo

PS

There are two types of entries- key entries and trusted cert entries, and only the key entry can contain a "chain" of certificates, attached to it. The trusted cert entries are all single cert entries.

Import PKCS7 (Chained Certificate) using KeyTool command to JKS - Stack Overflow

http://stackoverflow.com/questions/15814569/import-pkcs7-chained-certificate-using-keytool-command-to-jks

keytool import or importcert can take a text file with PEM blocks or a PKCS7 file as an input file.

openssl pkcs7 -in initial_file.p7b -inform DER -print_certs -outform PEM -out certs_chain.pem

Security

More great information on message-level encryption. While the whole document is relevant only to the Web Services Stack product, there are some useful points that we can pull from the beginning of the document.

  • Message-level security is applied between the web service client and the web service itself in both directions.
  • Message-level security secures the message content itself, but it does not secure the communication channel. This is in contrast to transport-level security, where the communication channel is secured.
  • "useReqSigCert" is a special fictional encryption user that is recognized by the security module. In this case, your certificate (that is used to verify your signature) is used for the encryption of the response. Thus, it is possible to have only one configured encryption user for all clients that access the service.
  • Message-level security allows you to digitally sign or encrypt documents exchanged between systems or business partners. It improves communication-level security by adding security features that are particularly important for inter-enterprise communication. Message-level security is recommended and sometimes a prerequisite for inter-enterprise communication.
  • A digital signature authenticates the business partner signing the message and ensures data integrity of the business document carried by a message.
  • Signatures are used in two scenarios:
  • Non-repudiation of origin
  • The sender signs a message so that the receiver can prove that the sender actually sent the message.
  • Non-repudiation of receipt
  • The receiver signs a receipt message back to the sender so that the original sender can prove that the receiver actually received the original message.
  • Message-level encryption is required if message content needs to be confidential not only on the communication lines but also in intermediate message stores.

Message-level security relies on public and private x.509 certificates maintained in the J2EE keystore, where each certificate is identified by its alias name and the keystore view where it is stored. Certificates are used in the following situations:

  • When signing a message, the sender signs it with its private key and attaches its certificate containing the public key to the message.
  • The receiver then verifies the digital signature of the message with the sender’s certificate attached to the message. There are two alternative trust models to verify the authenticity of the sender’s public certificate:
  • In the direct trust model, the signer’s public key certificate is compared with the locally maintained, expected public key certificate of the partner. Therefore, the direct trust model requires offline exchange of public key certificates, which can be self-signed or issued by a CA..
  • In the hierarchical trust model, the signer’s public key certificate is validated by a locally maintained public certificate of the CA that issued the signer’s public certificate. In addition, the subject name and the issuer of the signer’s certificate is compared with the expected partner’s identity configured in a receiver agreement on the receiver side.
  • Generally, the hierarchical trust model enables chains of certificates attached to the message. The certificate used for signing has to be signed by a root CA.
  • In the hierarchical trust model, the sender and the receiver only need to agree upon the CA and the subject name that the sender has used in its certificate.
  • When encrypting a message, the sender encrypts with the public key of the receiver (also verifying the correctness of the receiver’s certificate by using the public key of the certificate’s root CA).
  • The receiver decrypts with its private key certificate.

A practical description of essential PKI concepts is provided in " What is PKI?" by Entrust. Here is a summary of some concepts:

  • Public & Private Keys – Public and private keys are complementary: public keys are used for encryption, and private keys are used for message decryption. The public key goes through a provisioning process and is provided to the "public" as an X.509 certificate. An X.509 certificate carries with it detailed information about the certificate owner (for example, name and e-mail address) and additional information about the certificate authority (CA) used to vouch for the validity and integrity of the public key contained in the X.509 certificate. The private key never leaves the enterprise and is the "crown jewel" of the security infrastructure.
  • Trusting an X.509 certificate – Whenever an X.509 certificate is presented, the receiver has to establish that the X.509 is trusted. This trust is established by certificate chain traversal, a mechanism where the X.509 receiver verifies that the issuing authority (certificate authority) indeed issued the X.509 certificate presented. An additional check required by the receiver is to check whether the X.509 certificate has been revoked. This check is accomplished by looking up the X.509's serial number in a list of revoked certificates stored in a Certificate Revocation List (CRL). You may chose not to use an issuing certificate authority (CA) and use self-signed certificates. Such certificates have to be registered with the receiver as trusted certificates that do not require certificate chain validation.
  • JKS – Java Key Store is a portable repository of X.509 certificates and private keys; it is used by Java-based applications for cryptographic operations.

Message-level security is the cornerstone of enterprise-class SOA. Using SOAP encryption and SOAP signatures, confidentiality and integrity remain "always on" by being independent of transport protocols. With security now living within the SOAP messages, it does not matter if the transport pipe – HTTP, FTP, JMS – between Web service consumers, producers, or intermediaries is SSL enabled.

Message-level security provisions have the following additional advantages when compared with transport-level security alone:

  • Granular Security – message-level encryption on any selected part of the SOAP message.
  • Always on Security – SSL security features last as long as the SSL session is established. With message-level security, SOAP messages at rest can be encrypted even after the SSL connections are terminated. Security now lives within the message and is independent of the transport.

Vim

reformat in vim for a nice column layout - Stack Overflow

http://stackoverflow.com/questions/1229900/reformat-in-vim-for-a-nice-column-layout

The 'column' command is actually a Bash command that we are pulling into the current document in our vim session.

:%!column -t -s ','

Ruby

Ruby Java Bridge

Apparently provides an API for Ruby to execute java code.

Saturday, November 2, 2013

getting comfortable with prawn

deployment - Capistrano for Java? - Stack Overflow

http://stackoverflow.com/questions/183091/capistrano-for-java

Deployment strategy for Java web services?

Other options include

  • ControlTier
  • Fabric (Python)
  • Func

At my work we use Capistrano exclusively to deploy all of our Java applications. It is definitely possible.

Bob Smith, http://stackoverflow.com/questions/183091/capistrano-for-java

java - Debugging in Maven? - Stack Overflow

http://stackoverflow.com/questions/2935375/debugging-in-maven

It sure would be nice to not have a dependency on Eclipse. Having access to a command-line debugger would help in that area.

mvn exec:exec -Dexec.executable="java" -Dexec.args="-classpath %classpath -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044 com.mycompany.app.App"

ruby - Rails/Prawn: how do I use rails helpers inside a Prawn class? - Stack Overflow

http://stackoverflow.com/questions/9708884/rails-prawn-how-do-i-use-rails-helpers-inside-a-prawn-class

Extending Prawn helpers was as easy as creating an initializer and putting something like this in.

# $RAILS_ROOT/config/initializers/prawnto.rb
 
 module MyFancyModule

    def party!
      text "It's a big party!"
    end

  end

  Prawn::Document.extensions << MyFancyModule

It's also possible to mix in some of your own Rails helpers or anything really. I'm not sure if this is anything other than a more formal way of introducing a monkey patch, though.

# $RAILS_ROOT/config/initializers/prawnto.rb

Prawn::Document.extensions << ReportPdf
Prawn::Document.extensions << EntriesHelper

prawnto_2 does not accept a way to use a different class for the instance. You have to inject your modifications into Prawn::Document when Rails first comes up (e.g., an initializer).

# prawnto_2-0.2.5/lib/prawnto/template_handlers/renderer.rb

      def initialize(view_context, calling_object = nil)
        @view_context = view_context
        @calling_object = calling_object
        set_instance_variables
        @pdf = Prawn::Document.new(@prawnto_options[:prawn]);
      end

Current Cursor Position when Using the Prawn Ruby Library - Stack Overflow

http://stackoverflow.com/questions/183039/current-cursor-position-when-using-the-prawn-ruby-library

#move_cursor_to is probably a better way to accomplish moving the cursor to a particular 'y' position.

move_cursor_to(200)

ruby on rails - prawnto displaying tables that don't break when new page - Stack Overflow

http://stackoverflow.com/questions/2081635/prawnto-displaying-tables-that-dont-break-when-new-page

When paginating a PDF file using Prawn, there is no other way to determine the ultimate height of a stretchy box than to render it and access the @height attribute to get its value.

It appears that programatically determining where to introduce a page break might be challenging, especially when using prawnto_2. It might just mean that it will be necessary to not use the gem that helps integrate Prawn with Rails and use more explicit notation in the controller actions.

# controller action

  respond_to do |format|
    format.html
    format.pdf do
      pdf = Prawn::Document.new
      pdf.text "This is an audit."
      # Use whatever prawn methods you need on the pdf object to generate the PDF file right here.

      send_data pdf.render, type: "application/pdf", disposition: "inline"
      # send_data renders the pdf on the client side rather than saving it on the server filesystem.
      # Inline disposition renders it in the browser rather than making it a file download.
    end
  end

There is an interesting solution for pagination that involves using transaction/rollback, but apparently it is a little buggy.

@current_page = pdf.page_count

@roll = pdf.transaction do 
  pdf.move_down 20

  pdf.table @data,
    :font_size  => 12, 
    :border_style => :grid,
    :horizontal_padding => 10,
    :vertical_padding   => 3,
    :border_width       => 2,
    :position           => :left,
    :row_colors => ["FFFFFF","DDDDDD"]

  pdf.rollback if pdf.page_count > @current_page

end 

if @roll == false

  pdf.start_new_page

  pdf.table @data,
    :font_size  => 12, 
    :border_style => :grid,
    :horizontal_padding => 10,
    :vertical_padding   => 3,
    :border_width       => 2,
    :position           => :left,
    :row_colors => ["FFFFFF","DDDDDD"]
end

#153 PDFs with Prawn (revised) - RailsCasts

http://railscasts.com/episodes/153-pdfs-with-prawn-revised?view=comments

Several comments hint at some of the cool things that can be done. A more comprehensive list of examples can be found in Prawn's self-generated help document.

ruby on rails - Using lists in prawn - Stack Overflow

http://stackoverflow.com/questions/10513581/using-lists-in-prawn

Creating a bulleted list in Prawn. It's suggested that WickedPDF offers a better PDF generating solution.

table([ ["•", "First Element"],
        ["•", "Second Element"],
        ["•", "Third Element"] ])

Referring to selected text in a zen coding operation

http://code.google.com/p/zen-coding/wiki/ZenHTMLSelectorsEn

Yes! This is a great way to take a list of urls and format them in an unordered list.

ul>li*>a[href='$#']{$#}

Monday, October 14, 2013

jQuery timepicker

Subversion (source control)

Subversion Tutorial: 10 Most Used SVN Commands with Examples

Needed to know how to retrieve information in svn. It's been a long time. Git is so much better.

svn checkout/co URL PATH

jQuery Timepicker

Was looking for a viable time picker for tracker.

JQuery

.addClass() | jQuery API Documentation

http://api.jquery.com/addClass/

Adds the specified class(es) to each of the set of matched elements.

$( "p" ).addClass( "myClass yourClass" );

How can I make a redirect page in jQuery/JavaScript? - Stack Overflow

http://stackoverflow.com/questions/503093/how-can-i-make-a-redirect-page-in-jquery-javascript

Redirecting users after an AJAX call using JavaScript.

window.location.replace(...)

It is better than using window.location.href =, because replace() does not put the originating page in the session history, meaning the user won't get stuck in a never-ending back-button fiasco

Ryan McGeary, Feb 3 '09

Ruby/Rails

ruby - Radio buttons on Rails - Stack Overflow

http://stackoverflow.com/questions/623051/radio-buttons-on-rails

How to use Rails models in combination with radio buttons.

<div class="form_row">
    <label for="theme">Theme:</label>
    <% [ 'plain', 'desert', 'green', 'corporate', 'funky' ].each do |theme| %>
      <br><%= radio_button_tag 'theme', theme, @theme == theme %>
      <%= theme.humanize %>
    <% end %>
</div>

Run migrations from rails console - Stack Overflow

I love this! Use console to run migrations instead of waiting for the environment to load with each run.

# run migrations
ActiveRecord::Migrator.migrate "db/migrate"
ActiveRecord::Migrator.down "db/migrate", 20131011115823

# show the available migrations
puts ActiveRecord::Migrator.get_all_versions
puts ActiveRecord::Migrator.migrations_path

# show the available migrations; does not show whether those migrations have been applied or not 
puts (ActiveRecord::Migrator.migrations "db/migrate").map{|x| "#{x.version}: #{x.filename}"}

Tuesday, September 3, 2013

weblog; Ruby game development

Java game library + JRuby + awesome DSL = Gemini

http://dkoontz.wordpress.com/2008/07/14/java-game-library-jruby-awesome-dsl-gemini/

It appears that Gemini is dead and no longer available. There continue to be folks saying that game development in Ruby is just not work while because of performance reasons.

Prelude of the Chambered (JRuby port)

https://github.com/peterc/potc-jruby

Cool clone for FPS like Castle Wolfenstein. In the middle of trying to understand how items are assigned to loot locations.

Slick2D: 2D Java Game Library

http://slick.ninjacave.com/

Slick2D is an easy to use set of tools and utilites wrapped around LWJGL OpenGL bindings to make 2D Java game development easier.

http://slick.ninjacave.com/

Let’s Build a Simple Video Game with JRuby: A Tutorial

http://www.rubyinside.com/video-game-ruby-tutorial-5726.html

Ruby isn't known for its game development chops despite having a handful of interesting libraries suited to it. Java, on the other hand, has a thriving and popular game development scene flooded with powerful libraries, tutorials and forums. Can we drag some of Java's thunder kicking and screaming over to the world of Ruby? Yep! - thanks to JRuby. Let's run through the steps to build a simple 'bat and ball' game now.

http://www.rubyinside.com/video-game-ruby-tutorial-5726.html
Ruby is not for game development. http://gafferongames.com/2009/01/11/ruby-is-not-at-all-suitable-for-game-development/

I love ruby. It’s beautiful language, with elegant and expressive syntax – perfect as a scripting language, and great for prototyping new ideas quickly… I use it every chance I get, and truly enjoy coding in it.

But is it suitable for game development?

Unfortunately the answer is a resounding no!

weblog; Rails views; associations and ajax

Dynamic creation of variables in ruby

    inst_var_name = params[:controller].gsub(/\//, "_").singularize
    instance_variable_set("@#{inst_var_name}", @model)
http://www.funonrails.com/2010/02/dynamic-creation-of-variables-in-ruby.html

How to use dynamic attributes / columns in Squeel statements?

Interesting and has possibilities, but it was taking too much time to figure out a generic approach, so I fell back to typical active record call.

    klass = guess_model_class
    foreign_key_id = "#{klass.reflect_on_all_associations.first.name.to_s}_id"
    @models = klass.find(:all, conditions: ["#{foreign_key_id} = ?", params[foreign_key_id.to_sym]])

Squeel demands that an non-existent variable or method be called so that #method_missing gets called and uses the undefined name to generate sql.

    klass = guess_model_class
    foreign_key_id = "#{klass.reflect_on_all_associations.first.name.to_s}_id"

    # works, but is not generic
    @models = klass.where{new_and_returning_member_progress_id == params[:new_and_returning_member_progress_id]}

    # doesn't work
    @models = klass.where{klass.columns[0] == params[foreign_key_id.to_sym]}

    # doesn't work
    @models = klass.where{table_name.send(foreign_key_id.to_sym) == params[foreign_key_id.to_sym]}
http://stackoverflow.com/questions/12612889/how-to-use-dynamic-attributes-columns-in-squeel-statements

Test if a word is singular or plural in Ruby on Rails

def test_singularity(str)
  str.pluralize != str and str.singularize == str
end
    inst_var_name = params[:controller].gsub(/\//, "_").singularize
http://stackoverflow.com/questions/1801698/test-if-a-word-is-singular-or-plural-in-ruby-on-rails

polymorphic_url: Universal partial

    <div class="well"><%= link_to "Parents", polymorphic_url([@new_and_returning_member_progress, :family, :parents], layout: "none") %></div>
http://apidock.com/rails/ActionController/PolymorphicRoutes/polymorphic_url

Monday, January 23, 2012

ENV before Ruby

When making environment variables available to a Ruby script, make sure the environment key/value pairs are declared before the call to run a Ruby script.

E.g.,

MY_ENV_VAR=test ruby show_my_env_var.rb

first things first

I probably goes without saying, but when you are starting out with a new project, it is best to get as much of the framework available to your customer up front. Stick with as much bland as possible (e.g., wire frame) so that it's obvious that colors, graphics, etc. are not the focus up front. What good is the fancy shine when there is little functionality.

I spent a good amount of time looking for a tool that I could use to create wire frames that could be easily published and couldn't find one that would generate actual RoR views that could be published. The best tool I found was only for Windows and I use a Mac. With wire frame views in place along with the ability to navigate from resource to resource, it would be very easy to prioritize the pages and add actual functionality/color/graphics to that particular resource.

Active Scaffold is very interesting and is an example of using convention to save time in creating forms based on model configuration. I realize it's asking quite a bit, but it would be nice to have a tool where controls could be drawn/resized/etc and then published to RoR views.

It might be something worth looking into.

Wednesday, January 18, 2012

the basics of textual progress bars

While running through some maintenance of some log directories, I learned a little bit about $stdout and textual progress indicators.

The app I work with logs like crazy. There are time-date-stamped log files all over, products of the much appreciated log roller we use. Obviously, log rolling helps eliminate the need to peruse through an 8+ gygabyte text file. That's good. The accumulation of so many log files, however, get's to be almost as annoying. Just like my commuter car, at some point you can't stand it anymore and it's time to do some house cleaning.

I'm a software developer, and a lazy software developer at that. If there is any reason to code something, I'll gravitate towards creating a script, even to generate lines I can run in my console to tar up log files. There are so many log files to be tarred that I found myself wanting to view the progress since it's no fun staring at a frozen screen.

I use tail -f often to watch log entries being made from the web application I'm working with.

tail -f log/development.log


I can also see what files in a directory were last touched.

ls -lat | head


Wouldn't it be nice to have a script that monitored the directory and let me see those tar archives grow? That much was pretty easy.

while(true)
puts `ls -lat log/archive | head`
sleep(1)
end


But it is ugly. You get entries that scroll you off the page. Then I start thinking about those textual progress bars. They seem to print some character that moves the cursor back to the beginning of the line so that the next print of characters over-writes the last. That would solve my problem with the scrolling.

Ok; again, I'm lazy. I did a little research, but admittedly, just enough to get the results I wanted. So here are some facts/theories:
  1. carriage returns (\r) are different from newlines (\n). When used together, the cursor shows up on the next line. If you only use a carriage return, the cursor returns to the beginning of the line it is currently on.
  2. 'puts' automatically adds a carriage return (cr) and newline (\r\n) to the outputted string. Ok; that's a step in the right direction.
  3. 'printf' may be used to print to the console without a cr or newline
  4. 'printf' automatically buffers, spitting content out to screen only when the script is finished. If we could only force a flush. Including a call to 'flush' doesn't seem to do the trick.
  5. $stdout and $stderr are built in handles to STDOUT and STDERR (go figure!). I'm not sure, but I think that 'printf' is a method associated with Kernel. I do know that calls to $stdout.printf("hello world") followed by $stdout.flush() does work.
We should have everything that is required now. Let's try this again.

while(true)
res = `ls -lat log/archive | head`
$stdout.printf("%s\r", res) #note: don't use a newline; only a carriage return
$stdout.flush() #or you won't see anything,... ever
sleep(1)
end


Ah, much better! Now, since I can't leave well enough alone, I will clean up my output, limiting the output only to the first actual file in the list.

#note: hit Ctrl-c to end the loop
while(true)
#note: there is no check for when no match was found
res = `ls -lat log/archive | head`.match(/^[^\r\n]+[\r\n]+([^\r\n]+)/)[1]

$stdout.printf("%s\r", res) #note: don't use a newline; only a carriage return
$stdout.flush() #note: flush or you won't see anything,... ever
sleep(1)
end


So to sum up, while there are several gems or plugins that offer the nice convenience of a textual progress bar, it all comes down to printing a line that ends in a carriage return (\r) only and flushing the STDOUT buffer.

Here are several references I discovered during the fun little journey I made into the world of progress bars:

http://www.ruby-forum.com/topic/175626
http://blog.dhavalparikh.co.in/2009/04/progress-bar-in-rails/
http://0xcc.net/ruby-progressbar/index.html.en
http://stackoverflow.com/questions/238073/how-to-add-a-progress-bar-to-a-bash-script
https://github.com/jfelchner/ruby-progressbar/blob/master/lib/progressbar.rb

# shortcut for doing sprintf
http://snippets.dzone.com/posts/show/5027