teamon.eu

Łatwiejsze drukowanie z klp.pl

07 września 2008

Serwis klp.pl znają chyba wszyscy uczniowie. Portal nie raz ratował życie mojej klasie (liceum, mat-fiz-inf :p). Posiada jednak jedną wadę - nie można wydrukować na raz całego artykułu tylko trzeba odwiedzić każdą strone po kolei.

Tak było do dziś! Postanowiłem umilić sobie i innym drukowanie, a wynikiem tego postanowienia jest 40 linijek kodu w Ruby. Smacznego.

Sposób użycia:

ruby klp.rb http://ludzie-bezdomni.klp.pl/a-8239.html > ludzie-bezdomni.html

Dla zainteresowanych jeszcze którki opis. Program pobiera wersje do druku (pierwszą stronę) sprawdza ilość stron, pobiera je wszystkie i łączy.

 
require 'net/http'
require 'iconv'
 
class Klp
  def initialize(url)
    @http = Net::HTTP.new('klp.pl')
    match = url.match(%r[http://(.+).klp.pl/a-(\d+).html])
    @name = match[1]
    @id = match[2]
    @content = [] 
  end
 
  def fetch_page(page)
    resp, body = @http.get "/doda.php?akcja=druk&ida=#{@id}&strona=#{page}"
    Iconv.iconv('utf-8', 'iso-8859-2', body).first
  end
 
  def parse_content(body)
    body[%r[</h1>(.+)strona: &nbsp;&nbsp;]um, 1]
  end
 
  def join
    page = fetch_page(1)
    @title = page[%r[<h1>(.+?)</h1>], 1]
    pages_count = page.scan(%r[<a href=\?akcja=druk&ida=\d+&strona=(\d+)>]u).flatten.map {|e| e.to_i}.max
    @content << parse_content(page)
    if pages_count > 1
      (2..pages_count).each do |p|
        @content << parse_content(fetch_page(p))
      end
    end
 
    puts @title
    puts "----"
    puts @content
  end
end
 
Klp.new(ARGV[0]).join
 

P.S. Czytajcie lektury!

P.S. 2 Wersja online: http://klp.heroku.com

11 komentarzy

Merb rake stats

01 sierpnia 2008

Dzisiaj bez komentarza.

merb stats screenshot lib/tasks/stats.rake
 
desc "LOC statistic"
task :stats do
  STATISTICS_DIRS = {
    :controllers  => 'app/controllers',
    :helpers      => 'app/helpers',
    :models       => 'app/models',
    :lib          => 'lib',
    :spec         => 'spec'
  }
  EMPTY_STATS = { :lines => 0, :loc => 0, :classes => 0, :modules => 0, :methods => 0 }
 
  def show_line(name, stats, color = nil)
    ce = color ? "\033[0m" : ""
    puts  "| #{color}#{name.to_s.capitalize.ljust(20)}#{ce} " + 
          "| #{color}#{stats[:lines].to_s.rjust(7)}#{ce} " +
          "| #{color}#{stats[:loc].to_s.rjust(7)}#{ce} " +
          "| #{color}#{stats[:classes].to_s.rjust(7)}#{ce} " +
          "| #{color}#{stats[:modules].to_s.rjust(7)}#{ce} " +
          "| #{color}#{stats[:methods].to_s.rjust(7)}#{ce} |"
    puts separator
  end
 
  def separator
    '+----------------------+---------+---------+---------+---------+---------+'
  end
 
  def check_dir(dir)
    Dir.foreach(dir) do |file_name|
      if File.stat(dir / file_name).directory? and (/^\./ !~ file_name)
        check_dir(dir / file_name)
      end
 
      if file_name =~ /.*\.rb$/
        File.open(dir / file_name).each_line do |line|
          @stats[:lines]    += 1
          @stats[:loc]      += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
          @stats[:classes]  += 1 if line =~ /class [A-Z]/
          @stats[:modules]  += 1 if line =~ /module [A-Z]/
          @stats[:methods]  += 1 if line =~ /def [a-z]/
        end
      end
    end
  end
 
  @all = {}
  total = EMPTY_STATS.clone
  ce = "\033[0m"
  cb = "\033[35m"
  cg = "\033[4;32m"
  cr = "\033[31m"
 
  puts separator
  puts "| #{cg}Name#{ce}                 | #{cg}Lines#{ce}   | #{cg}LOC#{ce}     | #{cg}Classes#{ce} | #{cg}Modules#{ce} | #{cg}Methods#{ce} |"
  puts separator
 
  STATISTICS_DIRS.each_pair do |name, dir| 
    @stats = EMPTY_STATS.clone
    check_dir(dir)
    @all[name] = @stats
    show_line(name, @stats)
    @stats.each_pair { |type, count| total[type] += count }
  end
 
  show_line('Total', total, cr)
 
  code_loc = [:controllers, :helpers, :models].inject(0) { |sum, e| sum += @all[e][:loc] }
  test_loc = @all[:spec][:loc]
 
  puts "   Code LOC: #{cb}#{code_loc}#{ce}     Test LOC: #{cb}#{test_loc}#{ce}     Test to code radio:  #{cb}1:%0.2f#{ce}" % (test_loc.to_f / code_loc.to_f)
  puts
end
 
4 komentarze

Merb fixtures

30 lipca 2008

Ostatnio szukałem jakiegoś dobrego narzędzia do fixtures (nie mam pojęcia jak to można po polsku nazwa) w Merbie i znalazłem projekt na githubie merb-fixtures. Niestety okazało się, że sprawia pewne problemy w szczególności z dm-is-nested_set z paczki dm-more DataMappera. Jednak postanowiłem się nie poddawać i korzystając z kodu merb-fixtures napisać coś własnego.

Więcej... 1 komentarz

Błąd(?) w Ruby Array#shuffle

25 lipca 2008

"Odkryłem" nieciekawe zachowanie metody Array#shuffle. Okazało się, że metoda zachowuje się tak samo przy każdym uruchomieniu ruby.

 
[ 03:29:14 teamon ~ ] irb
>> a = (1..100).to_a
=> [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, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
>> 100.times { a.shuffle! }
=> 100
>> a
=> [26, 38, 9, 30, 63, 17, 64, 32, 2, 33, 55, 56, 37, 36, 75, 54, 8, 61, 1, 53, 43, 20, 95, 100, 71, 79, 47, 89, 29, 91, 68, 77, 93, 83, 88, 35, 52, 76, 27, 84, 22, 60, 85, 57, 82, 23, 4, 78, 21, 44, 28, 3, 70, 45, 73, 39, 98, 18, 86, 7, 97, 12, 62, 67, 50, 96, 51, 40, 10, 69, 34, 14, 99, 15, 72, 11, 59, 31, 46, 92, 58, 19, 13, 5, 74, 80, 66, 65, 25, 6, 94, 48, 16, 41, 87, 81, 49, 42, 24, 90]
>> exit
[ 03:29:34 teamon ~ ] irb
>> a = (1..100).to_a
=> [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, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
>> 99.times { a.shuffle! }
=> 99
>> a
=> [25, 89, 47, 87, 7, 73, 93, 78, 38, 77, 44, 65, 35, 33, 22, 92, 75, 98, 66, 43, 56, 42, 39, 40, 19, 67, 5, 12, 14, 36, 88, 57, 74, 21, 58, 18, 81, 52, 1, 91, 82, 29, 84, 27, 46, 28, 63, 2, 10, 96, 6, 31, 59, 94, 99, 54, 37, 26, 51, 34, 23, 61, 97, 86, 100, 24, 45, 62, 9, 55, 71, 80, 20, 8, 50, 69, 64, 79, 53, 48, 95, 32, 85, 11, 16, 72, 15, 17, 49, 4, 60, 70, 30, 13, 90, 68, 3, 41, 76, 83]
>> a.shuffle
=> [26, 38, 9, 30, 63, 17, 64, 32, 2, 33, 55, 56, 37, 36, 75, 54, 8, 61, 1, 53, 43, 20, 95, 100, 71, 79, 47, 89, 29, 91, 68, 77, 93, 83, 88, 35, 52, 76, 27, 84, 22, 60, 85, 57, 82, 23, 4, 78, 21, 44, 28, 3, 70, 45, 73, 39, 98, 18, 86, 7, 97, 12, 62, 67, 50, 96, 51, 40, 10, 69, 34, 14, 99, 15, 72, 11, 59, 31, 46, 92, 58, 19, 13, 5, 74, 80, 66, 65, 25, 6, 94, 48, 16, 41, 87, 81, 49, 42, 24, 90]
>> 
 

Na szczęście jest na to rozwiązanie:

 
[ 03:22:21 teamon ~ ] irb
>> (1..100).to_a.sort_by {rand}
=> [52, 3, 92, 83, 80, 29, 85, 10, 71, 41, 34, 74, 21, 98, 1, 97, 45, 7, 42, 96, 82, 87, 43, 6, 15, 23, 11, 25, 67, 20, 79, 64, 86, 58, 14, 65, 75, 99, 39, 48, 27, 77, 17, 62, 28, 70, 95, 47, 13, 63, 81, 33, 49, 76, 78, 88, 91, 73, 4, 2, 50, 90, 54, 26, 59, 53, 51, 66, 18, 46, 40, 8, 44, 61, 60, 89, 93, 24, 68, 57, 56, 32, 31, 94, 72, 69, 36, 38, 19, 84, 100, 30, 5, 35, 22, 9, 12, 55, 16, 37]
>> exit
[ 03:22:26 teamon ~ ] irb
>> (1..100).to_a.sort_by {rand}
=> [66, 58, 64, 48, 23, 90, 100, 92, 28, 53, 84, 40, 94, 19, 7, 62, 50, 72, 85, 45, 99, 93, 42, 81, 54, 86, 46, 60, 74, 69, 29, 11, 91, 65, 63, 75, 32, 79, 41, 89, 26, 35, 87, 24, 44, 98, 36, 25, 27, 43, 18, 67, 10, 52, 17, 80, 16, 57, 14, 3, 34, 2, 47, 78, 1, 12, 76, 61, 4, 39, 20, 33, 21, 55, 95, 38, 49, 51, 56, 88, 6, 71, 70, 77, 97, 37, 5, 31, 96, 13, 15, 8, 83, 59, 82, 68, 73, 30, 9, 22]
>> 
 

Jak dla mnie to dość poważny błąd, szczególnie jeśli używamy tego w Rakefile (np codzienne przemieszanie tabeli).

P.S. Jakby sie komuś chciało sprawdzić i porównać to:

 
[ 03:34:36 teamon ~ ] ruby -v
ruby 1.8.7 (2008-06-20 patchlevel 22) [i686-darwin9]
 
6 komentarzy

Prostsze formularze w Ruby on Rails

16 lipca 2008

Zawsze irytowało mnie pisanie formularzy. Ciągłe powtarzanie kodu w stylu:

 
<p>
  <%= f.label :field %>
  <%= f.text_field :field %>
</p>
 

wydało mi się nieco bezsensowne. Na szczęście jest na to rozwiązanie. Helper form_for posiada parametr :builder który pozwala na ustawienie własnego FormBuildera - klasy obsługującej "budowanie" pól formularza.

Mój wymarzony formularz wygląda teraz mniej więcej tak:

Więcej... 3 komentarze