Never been to TextSnippets before?

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 (or not, you can keep them private!)

« Newer Snippets
Older Snippets »
Showing 21-40 of 128 total

Сортировка массива с городами

// К примеру мне нужен массив с городами(имя, год основания). Отсортировать его(по году основания) и вывести названия городов.
// Чтобы отсортировать массив по населению, надо лишь заменить year на population)

cities = Array.new
cities << { :name => 'SPb',    :year => 1703, :population => 5_000_000 }
cities << { :name => 'Moscow', :year => 1147, :population => 10_000_000_000 }

cities.sort_by { |city| city[:year] }.each do |city|
  puts "#{city[:name]}"
end

Calculate the number of working days between two dates

Function
   # wdays is an array with the days of the week
   # to exclude days (eg: wdays = [0,6] for sunday and saturday )

   def calculate_working_days(d1,d2,wdays)
        diff = d2 - d1
        holidays = 0
        ret = (d2-d1).divmod(7)
        holidays =  ret[0].truncate * wdays.length
        d1 = d2 - ret[1]
        while(d1 <= d2)
                if wdays.include?(d1.wday)
                        holidays += 1
                end
                d1 += 1
        end
        diff - holidays
   end


Iterates over date range.
d1 = Date.new( 2006, 12, 1 ) 

d2 = Date.new( 2007, 1, 15 )

weekdays = (d1..d2).reject { |d| [0,6].include? d.wday } 

weekdays.length

Never render the full layout in a Rails view when called via AJAX

Essential for degradable javascript, when one never knows if a view or partial is being called via XmlHttpRequest or not. Throw the below code in your ApplicationController (application.rb)

More info in this blog post

def render(*args)
        args.first[:layout] = false if request.xhr? and args.first[:layout].nil?
        super
end

Интересное использование default params

// http://blog.floehopper.org/presentations/lrug-mock-objects-2007-07-09/
# def started?(clock = Clock.new)

class Clock
  def time
    Time.now
  end
end

class Event
  def initialize(start_time)
    @start_time = start_time
  end
  
  def started?(clock = Clock.new)
    clock.time > @start_time
  end  
end

Округлить дробное число до двух разрядов

gpo6Hoe_4ucJIo = 3.1415926535
puts ( gpo6Hoe_4ucJIo * 100 ).to_i.to_f / 100
puts sprintf( "%.2f", gpo6Hoe_4ucJIo ).to_f    # предпочтительнее, так как действительно округляет

Cmd-console utf unicode encoding solution

$KCODE = "utf-8"
STDIN.encoding = "utf-8"

Substrings in Ruby

The other day I was wondering why some really simple Ruby code of mine wasn’t working. The code under test looked something like this:

    def find_directories
        directories = []
        entries = `ls -l`.split/\n/  # get long-format directory listing
        entries.shift   # toss away the totals line
        entries.each do |entry|
            is_directory = (entry[0] == 'd')  # is it a directory?
            directories &lt;&lt; dir if is_directory
        end
        directories
    end

I figured that my ls -l.split/\n/ trickery wasn’t working. So I fired up irb and tried it manually. It worked fine.
Then I sprinkled a few puts statements throughout. entries was fine, and each entry was perfect, looking something like this:
drwx------ 24 jcohen jcohen 816 Aug 19 11:04 Documents

I couldn’t figure out what was wrong. All I had to do was look at the first character of entry; if it was a ‘d’, then I knew I had a directory. But for some reason, is_directory was always false. I googled, checked the RDocs for the String class, thumbed through the PickAxe, and something I read triggered one of those ah-ha moments.
Rats: My C# brain is still alive and kicking.

To confirm my fears, I fired up irb again:

irb> s = "Jeff" 
=> "Jeff" 
irb> s[0]
=> 74

That’s right, folks: on a string, the bracket syntax – when given only one parameter – will return the ASCII value of the character inside. Not the actual character, as it will in C#.
To correctly grab a one-character substring from a string, you have to supply two parameters:

irb> s[0,1]
=> "J" 

Aperture Duplicate Finder | Beta 1


#! /usr/bin/env ruby

## Aperture Duplicate Finder GUI Edition ##
## Does *not* require SQLite3 Vr. > 3.4  ##
## Writes into ZRESERVED column in ZRKVERSION ##

require 'digest'
require 'open3'
require 'pp'

$TERMINAL_MODE = true
$DEBUG = false
$REINDEXALL = true
$STACK = true
$UNSTACK = true

class DuplicateFinder

def initialize
  @aperture = Aperture.new
  @run_ok = @aperture.album_zpk != 0 ? true : false
end

def start
  main() if @run_ok
end

def main

  clean_slate() if $REINDEXALL

  pics_to_index = @aperture.get_unindexed_pics()

  generate_hashes(pics_to_index) unless pics_to_index.empty?

  dupes, dupe_groups = @aperture.get_duplicates()

  pp dupes if $DEBUG
  pp dupe_groups if $DEBUG

  find_duplicates()

end

def generate_hashes(pics_to_index)

  sha1_update_all = MultilineQuery.new

  begin

  pics_to_index.each_with_index do |row,i|

        path = (@aperture.libpath + row.last).gsub(/\\/,'')
        open(path, "r") { |f| sha1_update_all.newline("update ZRKVERSION set ZRESERVED = '#{Digest::SHA1.hexdigest(f.read)}' where Z_PK = #{row.first}") }

        @aperture.send(sha1_update_all.commit) if (i%300).zero?
        sha1_update_all = MultilineQuery.new if (i%300).zero?

        if $TERMINAL_MODE
          puts `clear`
          puts "#{pics_to_index.size} will be indexed."
          puts "Indexed #{i+1} | #{File.basename(path)}"
        end

  end

  @aperture.send(sha1_update_all.commit)

  rescue => e
    @aperture.send(sha1_update_all.commit)
  end

end

def find_duplicates

  dupes, dupe_groups = @aperture.get_duplicates()

  if $TERMINAL_MODE
    puts `clear`
    puts "Found #{dupes.size} duplicates in #{dupe_groups.size} groups."
  end

  albumstack_update, count = MultilineQuery.new, 0

  dupe_groups.each_with_index do |checksum,i|

      x = dupes.find_all { |k,v| v == checksum }.map! { |k| k.first.to_i }.sort!

      pp x if $DEBUG

      stackid = Digest::MD5.hexdigest(Time.now.to_f.to_s)

      if $STACK
        albumstack_update.newline("update ZRKVERSION set ZSTACKID = '#{stackid}' where ZRESERVED = '#{checksum}'")
      elsif $UNSTACK
        albumstack_update.newline("update ZRKVERSION set ZSTACKID = null where ZRESERVED = '#{checksum}'")
      end

      x.each_with_index do |id,i|
          albumstack_update.newline("update ZRKVERSION set ZSTACKINDEX = #{i} where Z_PK = #{id}") if $STACK
          albumstack_update.newline("insert into Z_11VERSIONS values (#{@aperture.album_zpk},#{id})")
          albumstack_update.newline("update ZRKVERSION set ZMAINRATING = -1 where Z_PK = #{id}") if i != 0
          count += 1
      end

  end

  albumstack_update.newline("update ZRKPERSISTENTALBUM set ZVERSIONCOUNT = #{count} where Z_PK = #{@aperture.album_zpk}")

  pp albumstack_update.commit if $DEBUG

  @aperture.send_by_file(albumstack_update.commit)

end

def clean_slate
  @aperture.send("update ZRKVERSION set ZRESERVED = null where Z_PK in (select Z_PK from ZRKVERSION)")
end

end

class Aperture

  attr_reader :libpath, :dbpath, :album_zpk

  def initialize
    @libpath, @dbpath = find_library()
    @album_zpk = create_new_album()
  end
  
  def get_unindexed_pics
    ids = parse_for_requery(send('select Z_PK from ZRKVERSION where ZRESERVED is null'))
    query = "select V.Z_PK,Path||'/'||ImportGroup||'/'||FolderName||'/'||FileName as FullPath from ZRKVERSION V join (select ZUUID, ZLIBRARYRELATIVEPATH as Path from ZRKFOLDER) b on (b.ZUUID = V.ZPROJECTUUID) join (select Z_PK, ZNAME as FolderName, ZIMPORTGROUP as ImportGroup from ZRKMASTER) c on (c.Z_PK = V.ZMASTER) join (select Z_PK,ZNAME as Filename, ZCHECKSUM as CheckSum from ZRKFILE) d on (d.Z_PK = V.ZFILE) where V.Z_PK in (#{ids})"
    parse_results(send(query))
  end

  def get_duplicates
    e = parse_results(send("begin; select Z_PK,ZRESERVED from ZRKVERSION where ZRESERVED in (select ZRESERVED from ZRKVERSION group by ZRESERVED having count(ZRESERVED) > 1); select ZRESERVED from ZRKVERSION group by ZRESERVED having count(ZRESERVED) > 1; commit;"))
    a,b = e.partition { |x| x.size == 2 }
    return a.inject({}) { |h,k| h.update k.first => k.last }, b.flatten
  end

  def send(msg)
    unless msg =~ /^\//
      %x|sqlite3 -list -separator ':::' #{@dbpath} "#{msg}"|
    else
      Open3.popen3("sqlite3 -init #{msg} #{@dbpath}")
    end
  end

  def send_by_file(msg)
    sqldump = ENV['HOME'] + "/Library/Caches/" + Digest::MD5.hexdigest(Time.now.to_f.to_s)
    File.open(sqldump,'w') { |f| f << msg }
    send(sqldump)
  end

  private

  def find_library
    aperture_plist = ENV['HOME'] + '/Library/Preferences/com.apple.Aperture.plist'
    plistdump = ENV['HOME'] + '/Library/Caches/' + 'plistdump.tmp'
    `plutil -convert xml1 -o #{plistdump} #{aperture_plist}`
    relative_lib_path = File.open(plistdump).grep(/aplibrary/).first.match(/>(.+)</).to_a[1]
    fullpath = relative_lib_path =~ /^~/ ? relative_lib_path.gsub(/^~/, ENV['HOME']) : relative_lib_path
    `rm #{plistdump}`
    puts "The current active library resides at " + fullpath if $TERMINAL_MODE
    return fullpath.gsub(/ /,'\ ') + "/", (fullpath + "/Aperture.aplib/Library.apdb").gsub(/ /,'\ ')
  end

  def create_new_album
    name = "Duplicates | " << Time.now.asctime << '.apalbum'
    zuuid = Digest::MD5.hexdigest(Time.now.to_f.to_s)
    create_album = "insert into ZRKPERSISTENTALBUM (Z_ENT,Z_OPT,ZDATELASTSAVEDINDATABASE,ZMETADATACHANGEDATE,ZCREATEDATE,ZNAME,ZUUID,ZVERSIONCOUNT,ZISMISSING,ZALBUMSUBCLASS,ZALBUMTYPE,ZFOLDER,Z5_FOLDER) values (11,2,209322883.588766,209322883.587464,209322875.604068,'#{name}','#{zuuid}',0,0,3,1,1,5)"
    send(create_album)
    return send("select Z_PK from ZRKPERSISTENTALBUM where ZNAME = '#{name}'")
  end

  def parse_for_requery(msg)
     msg.split("\n").map! { |e| "'" + e + "'" }.join(',')
  end

  def parse_results(query)
    query.split("\n").map! { |e| e.split(":::") }
  end

end

class MultilineQuery

  attr_reader :query

  def initialize
    @query = "begin; "
  end

  def newline(line)
    @query << " " << line << ";"
  end

  def commit
    newline("commit")
    return @query
  end

end

finder = DuplicateFinder.new

finder.start()

Get Download URLs from Safari


#! /usr/bin/env ruby

`ls ~/Desktop/*.download/*.plist`.split("\n").each { |file| url = File.open(file).grep(/http/)[2].match(/>(.+)</).to_a.last ; `sdcli add #{url}` }

`rm -R ~/Desktop/*.download`

calling super

When working with a subclass, calling super means you're calling the superclass' method OF THE SAME NAME. Thus you never specify anything with 'super', just arguments, if applicable

def child_method(arg1, arg2)
 super(arg1, arg2)
end

Ruby: Apple Aperture API

UPDATED WED Aug 15/07

PLEASE NOTE: requires the following modules "active_record", "rbosa" and "hpricot" and my own Imageshack API to work.

USAGE:

You can include/require this as a module in your own scripts, or as I do, use it directly from irb in the Terminal. Documentation is provided within the script itself, but essentially I use it to get these things done:

With Aperture launched, select the pictures of your choice (one or multiples makes no diff), then entering the following inside irb results in:

1. Aperture.reveal is essentially "Reveal in Finder"

2. Aperture.paths returns the Unix paths to the locations of the pics.

3. Aperture.open opens the pictures with an external default app (usually Preview).

4. If you provide the script with Photoshop's path, then:

Aperture.edit will open the original file directly in Photoshop without creating a separate version inside Aperture.

5. Aperture.ids will give you an array of the unique ID asssigned by Aperture to each pic within the ZRKVERSION table. What this is for is up to you to find out.

6. NEW: Imageshack.us upload/backup

Aperture.upload will upload the pic(s) to Imageshack.us and return the direct link/URL of the pic.

Upon first launch, a new metadata field is created inside Aperture's metadata panel called "Imageshack URL" (if you don't see it, inside Aperture, Ctrl-D --> Others). the uploaded pic's URL will be stored inside this field automatically.

The API directly interrogates Aperture's SQLite DB. Who knows, could be a nice place to start from to building other stuff.



require 'rubygems'
require 'active_record'
require 'rbosa'
require 'hpricot'
require 'open3'
require 'beckett/imageshack'

# --- GLOBALS --- #

HOME = ENV['HOME']
PATH_TO_PHOTOSHOP = "/Applications/Adobe\\ Photoshop\\ CS3/Adobe\\ Photoshop\\ CS3.app/Contents/MacOS/Adobe\\ Photoshop\\ CS3"

Aperture = OSA.app('Aperture')

# --- CONNECT TO CURRENT LIBRARY --- #

class LibraryConnect

  def initialize
    findLibrary
    connect unless $PATH_TO_DB.nil?
  end

  protected

  def findLibrary
  
  aperture_plist = HOME + '/Library/Preferences/com.apple.Aperture.plist'
  plistdump = HOME + '/Library/Caches/' + 'plistdump.tmp'
  plutil_error = Open3.popen3("plutil -convert xml1 -o #{plistdump} #{aperture_plist}") { |stdin,stdout,stderr| stderr.read }

  if plutil_error == ""
      doc = Hpricot(File.open(plistdump)) ; %x( rm #{plistdump} )
      relative_lib_path = (doc/:key).select { |key| key.inner_text == 'LibraryPath' }[0].next_sibling.inner_text
      $PATH_TO_LIB = relative_lib_path =~ /^~/ ? relative_lib_path.gsub(/^~/, HOME) : relative_lib_path
      $PATH_TO_DB = "#{$PATH_TO_LIB}/Aperture.aplib/Library.apdb"
      puts "Current library --> " + $PATH_TO_LIB
  else
      $PATH_TO_DB = nil
      puts "Cannot find library. Goodbye."
  end

  end

  def connect
    ActiveRecord::Base.establish_connection(
      :adapter => "sqlite3",
      :dbfile  => $PATH_TO_DB
    )
  end

end

# --- LIBRARY CLASSES-SQL TABLES MAPPINGS --- #

class Pictures < ActiveRecord::Base         # Contains the majority of non-metadata info on a picture
  set_table_name "ZRKVERSION"
  set_primary_key "ZUUID"
end

class Projects < ActiveRecord::Base         # Every pic only belongs to one project
  set_table_name "ZRKFOLDER"
  set_primary_key "ZUUID"
end

class Masters < ActiveRecord::Base          # Info on master images
  set_table_name "ZRKMASTER"
  set_primary_key "Z_PK"
end

class Files < ActiveRecord::Base            # Info on the actual image file 
  set_table_name "ZRKFILE"
  set_primary_key "Z_PK"
end

class Metadata < ActiveRecord::Base         # Metadata information tagged to every picture in library
  set_table_name "ZRKSEARCHABLEPROPERTY"
  set_primary_key "Z_PK"
end

class Albums < ActiveRecord::Base           # All albums within library
  set_table_name "ZRKPERSISTENTALBUM"
  set_primary_key "Z_PK"
end

class AlbumVersions < ActiveRecord::Base    # Foreign key that links a picture's Z_PK (from ZRKVERSION) to an
  set_table_name "Z_11VERSIONS"             # album's Z_PK in ZRKPERSISTENTALBUM
end

class Properties < ActiveRecord::Base       # Metadata categories
  set_table_name "ZRKPROPERTYIDENTIFIER"
  set_primary_key "Z_PK"
end

class Picture                               # Custom class that contains all relevant info on a picture

attr_reader :id, :project_id, :master_id, :file_id, :version_id, :width, :height, :filesize, :name, :moddate

def initialize(pic_id)

  # Query ZRKVERSION
  
  @id = pic_id
  pic = Pictures.find(pic_id)
  @project_id = pic.ZPROJECTUUID
  @master_id = pic.ZMASTER
  @file_id = pic.ZFILE
  @version_id = pic.Z_PK

  # Query ZRKFILE

  file = Files.find(@file_id)
  @width = pic.ZPIXELWIDTH
  @height = pic.ZPIXELHEIGHT
  @filesize = file.ZFILESIZE
  @name = file.ZNAME
  @moddate = realtime(file.ZFILEMODIFICATIONDATE_before_type_cast)

end

def filepath
    path = $PATH_TO_LIB + '/' + self.projectPath + '/' + self.importGroup + '/' + self.folderName + '/' + self.filename
end

def nixpath
    self.filepath.gsub(/ /,'\ ')
end

def open
  `open #{self.nixpath}`
end

def edit
  if PATH_TO_PHOTOSHOP != ""
    `open -a #{$PATH_TO_PHOTOSHOP} #{self.nixpath}`
  else
    `open #{self.nixpath}`
  end
end

def reveal
    puts nixpath
    `open #{File.dirname(self.nixpath)}`
end

def shack_uri
  pic_meta = Metadata.find( :first, :conditions => { :ZVERSION => @version_id, :ZPROPERTYIDENTIFIER => $SHACKURLPROP } )
  unless pic_meta == nil
    pic_meta.ZPROPERTYSPECIFICSTRING
  else
    return 'Does not exist.'
  end
end

def storeURI(url)
records = Metadata.find( :all, :conditions => { :ZVERSION => @version_id, :ZPROPERTYIDENTIFIER => $SHACKURLPROP } )
if  records.empty? == true
    new_uri = Metadata.create(
        :Z_ENT => 13,
        :Z_OPT => 1,
        :ZPROPERTYSPECIFICNUMBER =>  nil,
        :ZPROPERTYSPECIFICSTRING => url,
        :ZVALUETYPE => 3,
        :ZVERSION => @version_id,
        :ZPROPERTYIDENTIFIER => $SHACKURLPROP )
  new_uri.Z_PK
else
  records.each { |entry| Metadata.destroy(entry.Z_PK) }
  self.storeURI(url)
end

end

def realtime(sqtime)
  t = Time.at(sqtime.to_i + 978307200)      # => # Derives from: Time.utc(2001,"jan",1,0,0,0).to_i
  Time.utc(t.year,t.month,t.day,t.hour,t.min)
end

protected

def projectPath
    Projects.find(@project_id).ZLIBRARYRELATIVEPATH
end

def importGroup
   Masters.find(@master_id).ZIMPORTGROUP
end

def folderName
   Masters.find(@master_id).ZNAME
end

def filename
  Files.find(@file_id).ZNAME
end

end

class Album

def initialize(zpk)
  @album = Albums.find(zpk)
end

def add_count(n=0)
  @album.update_attributes(   :ZDATELASTSAVEDINDATABASE => (Time.now.to_f + 978307200.0),
                              :ZMETADATACHANGEDATE => (Time.now.to_f + 978307200.0),
                              :ZVERSIONCOUNT => @album.ZVERSIONCOUNT + n,
                              :ZCREATEDATE => @album.ZCREATEDATE_before_type_cast.to_f )
end

end

# --- INTERACTING WITH APERTURE FROM IRB --- #
# All operations are performed recursively on image(s) within the array returned by Aperture

class OSA::Aperture::Application

def new_prop(fieldName)

Properties.create(  :Z_ENT => 12,
                    :Z_OPT => 1,
                    :ZPROPERTYKEY => fieldName,
                    :ZPROPERTYTYPE => 7)
                    
return Properties.find_by_ZPROPERTYKEY(fieldName).Z_PK

end

def ids     # Returns the IDs used to query the ZRKVERSION table
  self.selection.collect { |pic| pic.id2 }
end

def paths   # Returns the filepaths of selected images
  self.ids.collect { |id| Picture.new(id).filepath }
end

def reveal  # 'Reveal in Finder' selected images
  self.ids.each { |id| Picture.new(id).reveal }
end

def open    # Opens selected images in Preview
  self.ids.each { |id| Picture.new(id).open }
end

def edit    # Opens the original file in Photoshop CS3 (if path provided or default)
  self.ids.each { |id| Picture.new(id).edit }
end

def upload(reveal=false)  # Uploads the image to Imageshack and returns the direct link to the pic, if called with true, then opens it in browser after upload

  self.ids.each do |id|
    pic = Picture.new(id)
    pic_mirror = ShackMirror.new(pic.filepath)
    pic.storeURI(pic_mirror.url)
    `open #{pic_mirror.url}` if reveal
    puts pic_mirror.url
  end

end

def print(name)
  self.ids.each { |id| puts Picture.new(id).send(name) }
end

end

# --- INITIALIZE --- #

LibraryConnect.new

$SHACKURLPROP = Properties.find_by_ZPROPERTYKEY("Imageshack URL") == nil ? Aperture.new_prop("Imageshack URL") : Properties.find_by_ZPROPERTYKEY("Imageshack URL").Z_PK

Ruby: Conform Sequence Files to Final Cut Pro XML (BETA)


#! /usr/bin/env ruby

# Tested with Apple XML Interchange Format Vr. 4
# The program infers the location of the seq. files by using the offline MOV's name.
# 1. It first looks for subfolders in the location of the MOV file. If a subfolder is found to have the same name as
# the file itself, then the whole folder is treated as a mirror of itself.
# 2. If no matching folders are found, it will use the first non-matching folder it comes across, and then assume
# that the files contained within it are prefixed with a name similar to its own.
# 3. Offline MOVs must run at the same framerate as your editing timebase in FCP! No putting a 24fps MOV into a 30fps timeline!

require 'rubygems'
require 'hpricot'

class Range

def length
  to_a.size
end

end

class Fixnum

def pad(n=8)
  x = to_s
  pad = n - x.length
  x.insert(0,"#{'0'*pad}")
  x
end

end

class Editor

attr_reader :edl

def initialize(file)

  @masters = {}
  @edits = []
  @edl = []
  @doc = Hpricot(open(file))

  find_masters()
  breakdown()

end

def find_masters

@doc.search("//file/pathurl").each do |elem| 
  
  base = File.basename(elem.inner_html).gsub!(/\....$/,'')
  path = abspath(elem.inner_html)

  folders = `ls #{path}`.split("\n").delete_if { |f| f =~ /\..../ }

  if folders.index(base).nil?
    @masters[elem.parent.attributes['id']] = path + "/" + folders.first + "/" + base + "."
  else
    @masters[elem.parent.attributes['id']] = path + "/" + base + "/"
  end

end

end

def breakdown

  @edits = @doc.search("//clipitem/file").each do |elem| 

    cut = []
    file_id = elem.attributes['id']
    seq_location = @masters[file_id]
    places = getpad(seq_location)

    cutin = (elem.parent/"in").inner_html.to_i.pad(places)
    cutout = (elem.parent/"out").inner_html.to_i.pad(places)

    cut.push(Range.new(cutin.succ!,cutout)) # Compensate for off-by-one count in IN-point from XML
    cut.push(seq_location)

    @edl.push(cut)

  end

end

def getpad(path)

  if path =~ /\.$/
    f = `ls #{path}*`.split("\n")[1]
  else
    f = `ls #{path}`.split("\n")[1]
  end
  
  return f.match(/(.+\.)?(.+)\..../).to_a.last.length

end

def abspath(path)

  path.gsub!(/file:\/\/localhost/,'')
  path.gsub!(/%20/,'\ ')

  return File.dirname(path)

end

def print_edl
  @edl.each_with_index do |cut,i|
    puts i.pad(4).succ + "|" + cut[0].first + " -- " + cut[0].last + " ++ " + cut[1]
  end
end

end

class Manager

def initialize

  @subroll = '00'
  @maxslots = 0
  @current_directory = ""
  @current_frame = "00000001"

  refresh_current

end

def refresh_current
  @subroll.succ!
  @maxslots = FRAMES_PER_ROLL
  @current_directory = "#{TARGET}/#{BIGROLL}_#{@subroll}"
  `mkdir -p #{@current_directory}`
  puts "NEW ROLL! #{@current_directory}"
  sleep 5
end

def assemble(cut)

  seq, source = cut[0], cut[1]

  if seq.length+1 > @maxslots
    refresh_current()
  end

  puts "Copying files to temporary folder..."

  seq.each do |frame|
    if source =~ /\/$/
      `cp #{source}/*.#{frame}.dpx #{TEMP}/`
    else
      `cp #{source}#{frame}.dpx #{TEMP}/`
    end
  end

  Dir.chdir(TEMP)
  
  list = Dir.entries(TEMP).delete_if { |x| x =~ /^\./ }
  
  list.map! { |f| File.rename(f,f + "x") ; f + "x" }

  puts "Moving files into roll #{@subroll}"

  list.each do |f|

    `mv -i #{f} #{@current_directory}/`

    Dir.chdir(@current_directory)
    
    `mv -i #{f} #{BIGROLL}_#{@subroll}.#{@current_frame}.dpx`

    puts "Moved #{f}"

    Dir.chdir(TEMP)
    
    @current_frame.succ!
    @maxslots -= 1
    
  end

end

end

## SETUP ##

FRAMES_PER_ROLL = 80
BIGROLL = '03'
TEMP = "/Volumes/Offline/Cache/Rubycut"
TARGET = "/Volumes/Offline/REEL3RC2"
FCP_XML = "/Users/anak/Desktop/edl.xml"

## MAIN ##

editor = Editor.new(FCP_XML)

editor.print_edl

puts "Press ENTER to continue..."

gets

manager = Manager.new

editor.edl.each_with_index do |cut,i|
  
  puts "Assembling #{(i+1).pad(4)} | #{cut[0]} > #{cut[1]}"
  
  manager.assemble(cut)
  
end

puts "CONFORMED: #{FCP_XML}"

Ruby: Apple Shake - Report FileIn Nodes

Another quick and dirty script I wrote when I screwed up my media's filesystem and I had to put it back together and this script simply prints out (nicely) the location of the files of every FileIn node in the Shake script.


#! /usr/bin/env ruby

$SOURCE = "" # Where are the Shake scripts?

$FILE_LIST = %x| ls #{$SOURCE}*.shk |.split("\n")

$FILE_LIST.each do |f|
  
  filein_nodes = File.open(f).grep(/SFileIn/)

  puts " --------- #{f} ------------"

  filein_nodes.map! { |n| n.split(/SFileIn/).last }

  filein_nodes.each { |n| puts n }
  
  puts "\n\n"

end

Ruby: Statistical Arrays


require 'arrayx' # separate post

# Statistical methods for arrays. Also see NArray Ruby library.

class Float

  def roundf(decimel_places)
      temp = self.to_s.length
      sprintf("%#{temp}.#{decimel_places}f",self).to_f
  end

end

class Integer

  # For easy reading e.g. 10000 -> 10,000 or 1000000 -> 100,000
  # Call with argument to specify delimiter.

  def ts(delimiter=',')
    st = self.to_s.reverse
    r = ""
    max = if st[-1].chr == '-'
      st.size - 1
    else
      st.size
    end
    if st.to_i == st.to_f
      1.upto(st.size) {|i| r << st[i-1].chr ; r << delimiter if i%3 == 0 and i < max}
    else
      start = nil
      1.upto(st.size) {|i|
        r << st[i-1].chr
        start = 0 if r[-1].chr == '.' and not start
        if start
          r << delimiter if start % 3 == 0 and start != 0  and i < max
          start += 1
        end
      }
    end
    r.reverse
  end

end

class Array

  def sum
    inject( nil ) { |sum,x| sum ? sum+x : x }
  end

  def mean
    sum=0
    self.each {|v| sum += v}
    sum/self.size.to_f
  end

  def variance
    m = self.mean
    sum = 0.0
    self.each {|v| sum += (v-m)**2 }
    sum/self.size
  end

  def stdev
    Math.sqrt(self.variance)
  end

  def count                                 # => Returns a hash of objects and their frequencies within array.
    k=Hash.new(0)
    self.each {|x| k[x]+=1 }
    k
  end
    
  def ^(other)                              # => Given two arrays a and b, a^b returns a new array of objects *not* found in the union of both.
    (self | other) - (self & other)
  end

  def freq(x)                               # => Returns the frequency of x within array.
    h = self.count
    h(x)
  end

  def maxcount                              # => Returns highest count of any object within array.
    h = self.count
    x = h.values.max
  end

  def mincount                              # => Returns lowest count of any object within array.
    h = self.count
    x = h.values.min
  end

  def outliers(x)                           # => Returns a new array of object(s) with x highest count(s) within array.
    h = self.count                                                              
    min = self.count.values.uniq.sort.reverse.first(x).min
    h.delete_if { |x,y| y < min }.keys.sort
  end

  def zscore(value)                         # => Standard deviations of value from mean of dataset.
    (value - mean) / stdev
  end

end

Ruby: Extended Arrays & Hashes (arrayx)


require 'set'

class Array

# Performs delete_if and returns the elements deleted instead (delete_if will return the array with elements removed).
# Because it is essentially delete_if, this method is destructive. Also this method is kinda redundant as you can simply
# call dup.delete_if passing it the negation of the condition.

def delete_fi
  x = select { |v| v if yield(v) }
  delete_if { |v| v if yield(v) }
  x.empty? ? nil : x
end

# Turns array into a queue. Shifts proceeding n elements forward
# and moves the first n elements to the back. When called with
# a block, performs next! and returns the result of block
# performed on that new first element. This method is destructive.

# a = [1,2,3].next!  => [2,3,1]
# a.next! { |x| x+ 10 } => 13
# a is now [3,1,2]

def next!(n=1)
  n.times do
    push(shift)
  end
  if block_given?
    y = yield(first)
    y
  else
    self
  end
end

# Treats [x,y] as a range and expands it to an array with y elements
# from x to y.

# [1,10].expand => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1,10].expand { |x| x**2 } => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

def expand
  x = (first..last).to_a
  if block_given?
    x.collect { |x| yield(x) }
  else
    x
  end
end

def shuffle!
   each_index do |i|
     j = rand(length-i) + i
     self[j], self[i] = self[i], self[j]
   end
end

def pick(n=1)
  y = Set.new
  until y.size == n
    t = self[rand(size)]
    y.add(t)
  end
  y.to_a
  y.to_a.first if n == 1
end

# ======== MATRIX CRUD ========= #

# Turns [x,y] into a matrix with x rows and y columns and fills them
# with the result of block. Block must be given *without* arguments.
# If no block is given, the method yields a sparse matrix.

# m = [3,3].to_matrix { rand(30) }
# => [[20, 26, 5, 14, 10], [20, 0, 28, 21, 18], [21, 16, 20, 12, 11]]

def to_matrix
  row = first
  col = last
  if block_given?
    x = Array.new(row) { Array.new(col) { yield } }
  else
    x = Array.new(row) { Array.new(col,0) }
  end
  x
end

def each_coordinate
  each_with_index do |row,x|
    row.each_with_index do |col,y|
      yield(x,y)
    end
  end
end

def mx_lookup(row,col)
  if row < 0 || col < 0
    nil
  else
    self[row][col]
  end
end

def mx_assign(row,col,val)
  self[row][col] = val
end

def mx_update(row,col,new_val)
  self[row][col] = new_val
end

end

class Hash

# Performs delete_if and returns the elements deleted. Because
# it is essentially delete_if, this method is destructive.

def delete_fi
  x = select { |k,v| yield(k,v) }
  delete_if { |k,v| yield(k,v) }
  x.empty? ? nil : x
end

def collect
  x = select { |k,v| yield(k,v) }
  h = x.inject({}) { |h,v| h.update x.first => x.last }
  h
end

end

class Range
  
# Returns an array with n random numbers within range.
  
        def pick(n=1)
    y = []
          x = [first,last].expand
          n.times { y << x[rand(x.size)] }
    y
    y.first if n == 1
        end
        
end

Ruby: Barebones Ruby Imageshack API

Usage:

pic_online = ShackMirror.new(local_path_of_pic)
pic_online.url # => returns direct link on Imageshack.

NOTE: if you give it a path beginning with http, then it will transload the image directly to Imageshack. Cool!

require 'rubygems'
require 'hpricot'
require 'net/http'
require 'uri'
require 'cgi'
require 'mime/types'

class ShackMirror

SHACK_ID = "REPLACE WITH YOUR OWN IMAGESHACK ID"
USER_AGENT = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/419 (KHTML, like Gecko) Safari/419.3"
BOUNDARY = '----------PuSHerInDaBUSH_$'

attr_reader :url

def initialize(img)
    raise NonImageTypeError, 'Expected image file.' unless img =~ /jpe?g|png|gif|bmp|tif|tiff|swf$/
    @img = img
    @url, @hosturi, @res = "","",""
    @header, @params = {}, {}
    @header['Cookie'] = "myimages=#{SHACK_ID}"
    @header['User-Agent'] = USER_AGENT
    @params['uploadtype'] = 'on'  
    @params['brand'] = ''
    @params['refer'] = ''
    @params['MAX_FILE_SIZE'] = '13145728'
    @params['optimage'] = '0'
    @params['rembar'] = '1'
    transfer
    getdirect
end

protected

def prepare_multipart ( params )
    fp = []
    params.each do |k,v|
    if v.respond_to?(:read)
      fp.push(FileParam.new(k,v.path,v.read))
      else fp.push(Param.new(k,v)) 
    end
  end
    query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
    return query
end

def prepFile(path_to_file)

  file = File.new(path_to_file)

  @header['Content-Type'] = "multipart/form-data, boundary=" + BOUNDARY + " "

  @params['url'] = 'paste image url here'
  @params['fileupload'] = file
  
  $query = prepare_multipart(@params)
  file.close

end

def locate(path)
  path !~ /^http/ ? "local" : "remote"
end

def upload( query, headers={} )
  Net::HTTP.start(@hosturi.host) do | http |
    http.post(@hosturi.path, query, headers);
  end
end

def transload(url)

  @header['Content-Type'] = 'form-data'

  @params['url'] = url
  @params['fileupload'] = ''
  
  postreq = Net::HTTP::Post.new(@hosturi.path, @header)
  postreq.set_form_data(@params)

  return Net::HTTP.new(@hosturi.host, @hosturi.port).start { |http| http.request(postreq) }

end

def transfer

case locate(@img)
  when "local"
    @hosturi = URI.parse('http://load.imageshack.us/index.php')
    prepFile(@img)
    @res = upload($query,@header)
  when "remote"
    @hosturi = URI.parse('http://imageshack.us/transload.php')
    @res = transload(@img)
end

end

def getdirect
  doc = Hpricot(@res.body)
  @url = (doc/"//input").last['value']
end

end

class Param

  attr_accessor :k, :v

  def initialize( k, v )
    @k = k
    @v = v
  end
  
  def to_multipart
    return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
  end

end

class FileParam

  attr_accessor :k, :filename, :content

  def initialize( k, filename, content )
    @k = k
    @filename = filename
    @content = content
  end
  
  def to_multipart
    return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{filename}\"\r\n" +
    "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" + content + "\r\n"
  end

end

Ruby: Marshal/Serialize Objects the Easy Way

// description of your code here

Serializes an object by simply calling marshal(name,object). When called without the second argument, it deserializes and recalls the object instead.


# save as marshalize.rb in /usr/local/lib/ruby/1.8/ and then require 'marshalize'

TMP_DIR = "/Library/Caches/"

def marshal(filename,data=nil)
  Dir.chdir(TMP_DIR) do
    if data != nil
      open(filename, "w") { |f| Marshal.dump(data, f) }
    elsif File.exists?(filename)
      open(filename) { |f| Marshal.load(f) }
    end
  end
end

def marshal_destroy(filename)
  Dir.chdir(TMP_DIR) do
  if File.exists?(filename)
    File.delete(filename)
  else
    return "File does not exists."
  end
  end
end

def marshal_clone(data)
  filename = srand.to_s << '.tmp'
  marshal(filename,data)
  h = marshal(filename)
  marshal_destroy(filename)
  return h
end

Ruby: Submit Apple Shake Scripts for Batch Render

A quick-n-dirty Ruby script that takes all the Shake scripts in a given folder, checks to make sure they are all set on maximum quality e.g "Base" and then submits them for render.

#! /usr/bin/env ruby

require 'pp'

class Fixnum

def pad(n)
  
  x = self.to_s

  if x.length < n
    pad = "0"*(n - x.length)
    x.insert(0,pad)
  else
    x
  end

end

end

def render(filepath,last_frame)

IO.popen("shake -v xml -exec #{filepath} -t 1-#{last_frame}x1", 'r+')

end

def get_last_frame(file_path)
  
  last_frame = File.open(file_path).grep(/SetTimeRange/).to_s.scan(/\d{2,6}/).first.to_i

end

def get_output_file(file_path)

  out_file = File.open(file_path).grep(/FileOut/).first.gsub(/\"/,"").split(",")[1].lstrip

end

def get_quality(file_path)

  quality = File.open(file_path).grep(/SetUseProxy/).first.match(/\".+\"/).to_a.first

end

# Get location of scripts

$renderQ = {}

puts "Where are the scripts?"
$TARGET = gets.rstrip
$TARGET << "/" if $TARGET !~ /\/$/

$script_list = %x| ls #{$TARGET}*.shk |.split("\n")   # Only files with *.shk extension

# Replace whitespace (if present) in filenames with underscores

$script_list.map! do |f|
    new_name = f.gsub(/\s/,'_')
    unless f == new_name
      puts "Renaming #{f} --> #{new_name}"
      File.rename(f,new_name)
    end
  new_name
end

# Make sure all renders are full-resolution

$script_list.each do |f|

  file,path,filename = File.open(f), File.dirname(f), File.basename(f).split(/\./)

  unless file.read.grep(/SetUseProxy/).first =~ /Base/
    
    new_file = File.open(f).read.gsub!(/^SetUseProxy.+;$/,'SetUseProxy("Base");')
    
    File.open(f,'w') { |f| f.puts new_file }

  end

end

# Get render info on scripts

$script_list.each do |f|
  outfile = get_output_file(f)
  last_frame = get_last_frame(f)
  quality = get_quality(f)
  $renderQ[f] = [last_frame,quality,outfile]
end

# Print report

puts "\n---------| RENDER SCRIPT -- FRAME COUNT -- OUTPUT FILE |---------\n"

$renderQ.sort.each { |k,v| puts "#{k} -- #{v.first} --> #{v.last} | #{v[1]}" }

puts "---------------------------------------------------"

puts "\nPress Enter to continue with render, or force exit."

gets

# Render

$renderQ.each { |k,v| render(k,v.first) }

Download full-resolution images from Photoblog Sites (drrtydown)

Built specifically for these sites I used to frequent cause I couldn't be bothered to click on each and every picture in a 40-pic post.
Tested verified working with Superiorpics, Otvali, Friends.kz, Hollywoodtuna, Tunaflix. Methinks it doesn't work so well with imagevenue anymore.
NOTE: uses wget to download the pics. So I guess, Unix only. I run OS X so...

#! /usr/bin/env ruby

require 'open-uri'

$home_dir = `echo $HOME`.chomp
`mkdir #{$home_dir}/tmp`
`mkdir #{$home_dir}/.tmp`
$tmp_dir = $home_dir + "/.tmp"
Dir.chdir($tmp_dir)        # Where wget will download files before moving.

puts "Files will be stored under -> #{$home_dir}/tmp"

#-- Filters for others -- #

$otvali_re = /http:\/\/img.otvali.ru\/[0-9]{4}\/[0-9]{2}\/[a-z0-9_]+_[0-9]{1,2}\.jpg/
$friendz_re = /thumbs\/([a-z0-9_]+.jpg)/

# -- Superiorpics Filters -- #

$fake_link = /(http:\/\/img[0-9]+.image(shack|venue)+\.(us|com)+\/(my|img).php\?image=(\w+_?)+\.jpg)/
$shack_link = /(http:\/\/img[0-9]+.image(shack|venue)+\.(us|com)+\/(\w_?-?)+\/(\w_?-?)+\/(\w+_?)+\.jpg)/
$av_link = /src="((\w_?-?)+\/(\w_?-?)+\/(\w+_?)+\.jpg)/i

# -- Filters for HollywoodTuna -- #

$tuna_small = /(\/images\/(\w+_?)+\.jpg)/

def makeNewFolder
  puts "OK, where do you want to hide these? Or ENTER and I'll do it for you."
  answer = gets

  if answer !="\n"
    $new_folder_name = answer.gsub(/[\s\W]/, '_').chomp
  else
    $new_folder_name = File.basename($address, ".*").gsub(/[\s\W]/, '_')
  end

  $path_to_new_dir = $home_dir + "/tmp/" + $new_folder_name + "/"
  `mkdir #{$path_to_new_dir}`
  puts "Created: " + $new_folder_name
  puts "Path --> " + $path_to_new_dir
end

def cleanUp
  puts "Moving files to #{$path_to_new_dir}..."
  `mv #{$home_dir}/.tmp/*.jpg #{$path_to_new_dir}`
end

## Main Program ##

$pages = Array.new

puts "Enter URL:"
$address = gets.chomp

if $address =~ /otvali.ru/

  puts "Scanning page..."
  $pages = open($address).read.scan($otvali_re).delete_if { |x| x =~ /_s__/ } # Remove thumbnails. Their URLs contains "_s__"

elsif $address =~ /friends.kz/

  puts "Scanning page..."
  $pages = open($address).read.scan($friendz_re).flatten!.uniq
  $pages.collect! { |path| "http://friends.kz/uploads/posts/" + path }

elsif $address =~ /superiorpics/

  puts "Scanning page..."
  $pages = open($address).read.scan($fake_link).flatten!.delete_if { |i| i !~ /http/ }  # Remove all regex objects save the full URL
  $pages.collect! do |page|
    if page =~ /imageshack/
      puts "Resolving #{page}"
      open(page).read.scan($shack_link)[0][0]   # Returns the actual link buried under two arrays of Regex objects
    elsif page =~ /imagevenue/
      puts "Resolving #{page}"
      path_to_pic = open(page).read.scan($av_link)[0][0]
      av_direct = "http://" + URI.parse(page).host + "/" + path_to_pic
    end
  end

elsif $address =~ /(hollywoodtuna|tunaflix)/

  puts "Who do you want? ENTER to take'em all! Start with OMIT for negative search."
  search_string = gets.chomp.gsub(/ /, "|" ) # Prepare to feed into Regex
  tuna_want = Regexp.new(search_string)
  puts tuna_want
  puts "Scanning page..."
  $pages = open($address).read.scan($tuna_small).flatten!.delete_if { |i| i !~ /(th|tn|small)\.jpg$/ }
  $pages.collect! do |page|
        page.gsub!("images", "images/bigimages")
        page.gsub!(/(th|tn|small)\.jpg$/, "big.jpg")
        tuna_direct = URI.parse($address).host + page
      end
    
    if search_string =~ /^OMIT/
        $pages.delete_if { |i| i =~ tuna_want }
      else
        $pages.delete_if { |i| i !~ tuna_want }
    end
end

## Report total of found images, if nothing then exit the program.

$pages.uniq!

puts $pages

if $pages.length == 0
  puts "Yeah right. Nice try. Off you go!"
  exit
elsif $pages.length <= 20
  puts "What?! #{$pages.length}, is that all?"
elsif $pages.length >= 21
  puts "What're y'fuckin nuts??! #{$pages.length} !!!"
end

makeNewFolder

$threads = []

$down_count = 0

for pic_to_fetch in $pages
    $threads << Thread.new(pic_to_fetch) do |link|
      puts "Fetching #{link}"
      %x{wget --quiet --random-wait #{link}}
      $down_count += 1
      puts "Downloaded " + $down_count.to_s + "/" + $pages.length.to_s
  end 
end

$threads.each {|thr| thr.join }

dwn_actual = Dir.entries($tmp_dir).length-2

cleanUp

dwn_moved = Dir.entries($path_to_new_dir).length-2

if $pages.length == dwn_actual and dwn_actual == dwn_moved
  puts "All completed @ #{Time.now.hour}:#{Time.now.min}. See y'around, dirty boy."
elsif dwn_moved <= dwn_actual
  diff = dwn_actual - dwn_moved
  puts "#{diff} got lost in the moving, baby. Goodbye."
elsif dwn_actual <= $pages.length
  diff = $pages.length - dwn_actual
  puts "#{diff} got lost coming down. Goodbye."
end

random password generation in Ruby

// description of your code here

chars = ("a".."z").to_a + ("1".."9").to_a 
newpass = Array.new(8, '').collect{chars[rand(chars.size)]}.join
« Newer Snippets
Older Snippets »
Showing 21-40 of 128 total