DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world
  • submit to reddit
        Lame webserver I wrote in PERL as a test.. It was never completed, but I want to save this for future reference.  

#!/usr/bin/perl -w
# Jeff Torgerson
# chee-Z WebServer
# TODO:
# [] parse parameters
# [] pass arguments to web pages, and regex replace the values
# [] config for base directory, port, etc

use strict;
use IO::Socket;
use Time::Local;

#####################
# declarations
#####################
my ($client,$cheezServer,$count,$jCount,$linenumber,$line,$logfile,$fileToServe,$ourMsg,$time,$timestamp,$fnf,$year);
my (@date,@info,@lines,@ln);

#####################
## Settings
#####################
$logfile = "chee-z_webserver.log";

#####################
# main
#####################
$cheezServer = IO::Socket::INET->new
(
LocalPort => 80,
Type => SOCK_STREAM,
Reuse => 1,
Listen => 5 # number of clients to allow
) or die "Could not open your dumb server.. es ist kaput!";

# Now, wait for a connection
while ($client = $cheezServer->accept()) {
# $client->autoflush(1);

my $request = <$client>; # Get the first line
# right below here i get strange error on command line hits
# Use of uninitialized value in pattern match (m//) at E:\scripts\webserver.pl line 40.
if ($request =~ m|^GET /(.+)HTTP/1.[01]|) { # this must match a valid http request
my $theActualFile = stripParams($1); # I need to get rid of the params passed
# writeLogFile("debug","$theActualFile");# This allows me to throw a debug msg into the log file
if (-e $theActualFile) { # does the file exist
print $client "HTTP/1.0 200 OK\nContent-Type: text/html\n\n"; # Start serving my request

open($fileToServe,"<$theActualFile") or die "Can't open file: $theActualFile";
while(<$fileToServe>) { print $client $_ };
# now write the log file
writeLogFile("200","$1");
} else {
# we have a file not found if we get here, 404 error
$fnf = notFound("$theActualFile");
print $client $fnf; # writes the not found page
}
} else {
# we did not get a valid request
print $client "HTTP/1.0 400 BAD REQUEST\n";
print $client "Content-Type: text/plain\n\n";
print $client "BAD REQUEST\n";
}
close $client;
}

# now, close the server
close($cheezServer);

############################################################
## Subroutines
############################################################


##############################
## 404 errors here
sub notFound{
my $theFile = $_[0];
$ourMsg = "HTTP/1.0 404 FILE NOT FOUND\n";
$ourMsg = $ourMsg."Content-Type: text/html\n\n";
$ourMsg = $ourMsg."<h2>404 - File Not found</h2><b>".$theFile."</b> not found\n";
writeLogFile("404","$theFile");
return $ourMsg;
}

##############################
## Write my log file
sub writeLogFile{
my $httpStatusCode = $_[0];
my $entry = $_[1];

# now, open the log file
open(cheeZjournal,">>$logfile" ) || die "Could not open journal"; # Open the file
@lines = <cheeZjournal>;
@info = stat cheeZjournal;
@date = localtime($info[9]);
$year = sprintf("%d-%d-%d",$date[4]+1,$date[3],$date[5]+1900);
$time = "$date[2]:$date[1]"; # goofy error here when time is 7:03, I get 7:3
$timestamp = "$year|$time||$info[9]||";
$linenumber = $count;
print cheeZjournal "$httpStatusCode|$timestamp|$entry\n";
close(cheeZjournal) ; # Close the file
print @lines;
}

##############################
## Strip all the parameters
## off the file name for use
sub stripParams{
my @request;
my $fullStuff = $_[0];
# split on the Q to get only the file name
@request = split(/\?/,$fullStuff);
return $request[0]
}

    
        
require 'optparse'

# default options
OPTIONS = {
  :first       => "default value",
  :another     => 23,
  :bool        => false,
  :list        => ["x", "y", "z"],
  :dest        => File.expand_path(File.dirname($0))
}


ARGV.options do |o|
  script_name = File.basename($0)
  
  o.set_summary_indent('  ')
  o.banner =    "Usage: #{script_name} [OPTIONS]"
  o.define_head "Abstract description of script"
  o.separator   ""
  o.separator   "Mandatory arguments to long options are mandatory for " +
                "short options too."
  
  o.on("-f", "--first=[val]", String,
       "A long and short (optional) string argument",
       "Default: #{OPTIONS[:first]}")   { |OPTIONS[:first]| }
  o.on("-a", "--another=val", Integer,
       "Requires an int argument")      { |OPTIONS[:another]| }
  o.on("-b", "--boolean",
       "A boolean argument")            { |OPTIONS[:bool]| }
  o.on("--list=[x,y,z]", Array, 
       "Example 'list' of arguments")   { |OPTIONS[:list]| }
  
  o.separator ""

  o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
  
  o.parse!
end

puts "first:     #{OPTIONS[:first]}"
puts "another:   #{OPTIONS[:another]}"
puts "bool:      #{OPTIONS[:bool]}"
puts "list:      #{OPTIONS[:list].join(',')}"
puts "arguments: #{ARGV}"
    
        I'm probably not using this board right but hopefully someone can help me out.  I'm relatively new to perl... but I've done a little bit of batch scripting so I am used to how the language works and can learn easily.  My problem is that I need to copy a file from one drive and paste it into a folder on a different drive.  This process takes place daily and is followed by other tasks, but I need to know how to copy a file whose name is always different because there is a date stamp in the middle of the file name.  If anyone can help me out i'd be greatly appreciateive.  PLEASE HELP ME!    
        The Xml Deserializer functions parse an XML file and give you a basic object of the nodes and attributes.  Using the discography xml fragment below as an example, you can do:

myData.album._title
myData.album.song[0]._href;

// this is if the <album> node had node text
// <album title="blah">Album Content</album>
myData.album.__content__

Pick it up piping hot at http://rubyurl.com/q05.

#include "xml_deserializer.as"

/* Sample XML file
<discography>
  <album title="Late For The Sky" year="1974">
    <song title="Late For The Sky" href="late_for_the_sky.mp3"/>
    <song title="Fountain Of Sorrow" href="fountain_of_sorrow.mp3"/>
  </album>
</discography>
*/

// xml callback function
function parseDiscography(success) {
  if(!success) return;
	
  XmlDeserializer.parse_nodes(myData, XmlDeserializer.xml_object.childNodes[0]);
	
  play();

  var albums = XmlDeserializer.get_items(myData.album);
  for(var a=0; a < albums.length; a++) {
    var album = albums[a];
    var songs = XmlDeserializer.get_items(album.song);
    for(var s=0; s < songs.length; s++) {
      var song = songs[s];
      if(song._href != undefined) {
        var song_obj = { 
          title: album._title + ' :: ' + song._title,
          href: myDiscoPath + song._href
        };

        // global array used by flash
        mySongs.push(song_obj);
      }
    }
  }
}

// object used by XmlDeserializer class
var myData = {};
// strip off disco.xml
var myDiscoPath = myDisco.substr(0, myDisco.length-9); 
//XmlDeserializer.debug = true;

// myDisco is url to discography xml file
XmlDeserializer.parse_xml(myDisco, parseDiscography);
    
        Spider a directory using:

find . -type d ! \( -name "*CVS" \) -exec python cvsAdd.py {} \;
find . -name "*.py" -exec python cvsAdd.py {} \;

in cvsAdd.py, put the following:

import sys, pexpect, getpass

PASS='myPass'

def cvsAdd(fname):
    global PASS
    if not PASS:
        PASS = getpass.getpass()
    
    child = pexpect.spawn('cvs add "%s"' % fname)
    child.expect("me@my-cvs-host password:")
    child.sendline(PASS)

    for line in child:
        print line

cvsAdd(sys.argv[1])
    
        It seems like a simple task, but here's how you can simulate the calling of a controller's action:

ruby script/console

irb> require 'action_controller/test_process'
irb> require 'application'
irb> require 'site_controller'
irb> request = ActionController::TestRequest.new
irb> response = ActionController::TestResponse.new
irb> request.env['REQUEST_METHOD'] = 'GET'
irb> request.action = "late_employee"
irb> InfoController.process(request,response)

Basically, it's like getting inside of a TestUnit method, but you have to do the dirty work yourself.    
        
lookupd -flushcache
    
        
function checkPhone(str) 
{
	var phone2 = /^(\+\d)*\s*(\(\d{3}\)\s*)*\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2}$/; 
	if (str.match(phone2)) {
   		return true;
 	} else {
 		return false;
 	}
}

Phone format 
phone:
339-4248
339-42-48
339 42 48
339 4248
3394248
(095) #phone#
(095)#phone#
+7 (095) #phone#
+7 (095)#phone#
+7(095) #phone#
+7(095)#phone#    
        
{exp:weblog:category_heading weblog="weblog"}{category_name}{/exp:weblog:category_heading}
Show the currently viewed category as a heading outside of the {weblog.entries} tag.    
        Engineering format lists the exponent in powers of three

def number_to_engineering(value, precision=3)
  expof10 = ((Math.log10(value)/3.0).floor)*3
  value *= 10**(-expof10)
  case 
    when value>=1000.0 : 
      value /= 1000.0
      expof10 +=3 
    when value>=100.0 :  precision -= 2 
    when value>=10.0 :  precision -= 1 
  end
  "%.*fe%d" % [precision-1, value, expof10]
end

number_to_engineering(15000) => "15e3"

    
        For those of us who can't remember the formatting codes

def number_to_scientific(num,precision=3)
	"%.#{precision}e" % num
end

number_to_scientific(10000) => 1.000e004
in some cases it might be better to use the 'g' code instead of the 'e' code.      
        
def number_to_ordinal(num)
  num = num.to_i
  if (10...20)===num
    "#{num}th"
  else
    g = %w{ th st nd rd th th th th th th }
    a = num.to_s
    c=a[-1..-1].to_i
    a + g[c]
  end
end

number_to_ordinal(12) => "12th"
number_to_ordinal(7) => "7th"

Note that floats will be converted to ints (without rounding) before processing.      
        Actually, you can customize the separators to your needs.

def text_list(listtext,sep1=", ", sep2=", and ")
  n=listtext.size
  if n>1 : (listtext.first(n-1)).join(sep1) + sep2 +listtext.last 
  else listtext.first end
end

text_list(["cat", "dog", "bird"]) => "cat, dog, and bird"
    
        see my <a href="http://weblog.digett.com/2005/08/21/add-the-latest-version-of-rails-when-deploying/">blog post</a> about this...

desc "Performs an export of the rails trunk"
task :rails_export => :environment do
  FileUtils.rm_rf "#{RAILS_ROOT}/vendor/rails"
  puts 'exporting... ' + ENV["VERSION"].to_s 
  `svn export http://dev.rubyonrails.org/svn/rails/trunk#{ENV["VERSION"] ? "@#{ENV['VERSION']}" : ""} #{RAILS_ROOT}/vendor/rails`
  puts 'applying patches...'
  FileList[File.expand_path("#{RAILS_ROOT}/config/diffs/*.diff")].sort.each do |diff_file|
    %x{cd #{File.expand_path("#{RAILS_ROOT}/vendor/rails")} && cat #{File.expand_path(diff_file)} | patch -p0}
  end
end

Does an svn export from rails.  Provide a revision if you don't want to check out the latest.  It then applies patches in config/diffs in alphabetical order.

rake rails_export VERSION=2000

Here is a SwitchTower recipe to perform this action automatically:

set :rails_version, '2031' # custom ST variable

desc "Checks out rails rev ##{rails_version}"
task :after_symlink do
  run "cd #{current_release} && rake rails_export VERSION=#{rails_version}"
end
    
        
ActiveRecord::Base.class_eval do
  alias_method :destroy!, :destroy
  
  class << self
    alias_method :find_with_deleted, :find
    alias_method :count_with_deleted, :count
    
    def find(*args)
      if [:all, :first].include?(args.first)
        constrain = "#{table_name}.deleted_at IS NULL"
        constrains = (scope_constrains.nil? or scope_constrains[:conditions].nil? or scope_constrains[:conditions] == constrain) ?
          constrain :
          "#{scope_constrains[:conditions]} AND #{constrain}"
        constrain(:conditions => constrains) { return find_with_deleted(*args) }
      end
      find_with_deleted(*args)
    end
    
    def count(conditions = nil, joins = nil)
      constrain(:conditions => "#{table_name}.deleted_at IS NULL") { count_with_deleted(conditions, joins) }
    end
  end
  
  def destroy
    update_attribute(:deleted_at, self.class.default_timezone == :utc ? Time.now.utc : Time.now) unless new_record?
    freeze
  end
end

ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
  alias_method :find_with_deleted, :find
  def find(*args)
    constrain(:conditions => "#{@join_table}.deleted_at IS NULL") { find_with_deleted(*args) }
  end
end

see <a href="http://techno-weenie.net/blog/code/251/paranoid-activerecord-models">my blog entry about this</a>.