K.Sasada's Home Page

こめんとのついか

こめんとこめんと!

message

please set comment :).

_14(Thu)

停滞中。


先日、OSC2005 のために作った(http://www.namikilab.tuat.ac.jp/~sasada/diary/200503.html#d21)写真を動画っぽく見るためのスクリプト。

まとめるのは面倒なので、貼っておく。

写真をアップロードするスクリプト。

UploadURL = 'どっか'

##########################
require 'net/http'
require 'uri'

Net::HTTP.version_1_2

def upload uri, file
  uri      = URI.parse(uri)
  if block_given?
    boundary = yield
  else
    boundary = '--------------------------' +
      Time.now.to_i.to_s(36) + '--' + rand(10000).to_s(36)
  end
  
  Net::HTTP.start(uri.host){|http|
    header = {
      'content-type' => "multipart/form-data; boundary=#{boundary}"
    }
    data = []
    data << '--' + boundary
    data << "content-disposition: form-data; name=\"upload_file\"; filename=\"#{file}\""
    data << 'content-type: application/octet-stream'
    data << ''
    data << open(file, 'rb'){|f| f.read}
    data << "--#{boundary}--"
    data << ''
    
    data = data.join("\r\n")
    res = http.post(uri.path, data, header)
    res.body
  }
end

while true
  begin
    Dir.glob("*.jpg"){|file|
      puts upload(UploadURL, file)
      p file
      File.unlink(file)
    }
  rescue Exception => e
    p e
    p e.backtrace
  end
  sleep 0.5
end

ファイルを受信する奴とかファイル名を送信するサーバとか。

#!/usr/bin/env ruby18

require 'cgi'
require 'erb'

class ThroughFlow < Exception
end

MAX_FILES = 10

class Mgr
  def initialize
    @cgi    = CGI.new
    dmy, @mode, @arg, *@args = (@cgi.path_info || '').split('/')
    @mode ||= 'view'
  end

  def start
    @cgi.out{
      dispatch.to_s
    }
  end

  def dispatch
    # [@mode, @arg, @args].inspect
    if self.respond_to? @mode
      self.__send__ @mode
    else
      raise "Unkown mode: #{@mode}"
    end
  end

  def view
    ERB.new(File.read('view.html')).result(binding)
  end

  def upload
    data, = @cgi.params['upload_file']
    fdata = data.read
    filename = 'ul/' + Time.now.to_i.to_s + '.jpg'
    open(filename, 'wb'){|f|
      f.write fdata
    }
    files = ul_files
    while files.size > MAX_FILES
      File.unlink(files.pop)
    end
    test_page "upload: #{fdata.size}", files.join(',')+''#fdata.inspect
  end

  def check
    files = ul_files
    file  = files[0]
    begin
      children = files.map{|child|
        "<file filename='#{child}' date='#{File.mtime(child).to_s}' />"
      }.join
    rescue Exception => e
      children = ''
    end
    @cgi.out('content-type' => 'text/xml',
             'Pragma' => 'no-cache',
             'Cache-Control' => 'no-cache'){
<<EOS
<?xml version="1.0" encoding="Shift_JIS"?>
<check id='check' filename='#{files[0]}' date='#{File.mtime(file).to_s}'>
#{children}
</check>
EOS
}
    raise ThroughFlow
  end

  def ul_files
    Dir.glob('ul/*.jpg').sort{|a, b| b <=> a}
  end
  
  def test_page title, content
    <<-EOS
    <html>
    <title> #{CGI.escapeHTML title} </title>
    <body>
    <pre>#{CGI.escapeHTML content}</pre>
    </body>
    </html>
    EOS
  end
end

begin
  Mgr.new.start
rescue ThroughFlow
  
rescue Object => e
  CGI.new.out{
    <<-EOS
    <html>
    <title> Error </title>
    <body> <h1> Error: #{CGI.escapeHTML(e.inspect)} </h1>
    <p> #{CGI.escapeHTML(e.to_s)} </p>
    <pre>#{CGI.escapeHTML(e.backtrace.join("\n"))}
    </pre>
    </body>
    </html>
    EOS
  }
end

ブラウザにみせるためのテンプレート。

<html>
  <title> View </title>
  
  
<script type='text/javascript'>
<!--
  
function setstate(st){
  document.getElementById('text1').innerHTML = st;
}

function loadXMLFile(url){
  var req = createXMLHttpRequest();
  req.open("GET", url, false);
  req.send(null);

  if (req.status == 200){
    var xmldoc = req.responseXML;
    var filename = xmldoc.documentElement.getAttribute('filename');
    var date     = xmldoc.documentElement.getAttribute('date');
    loaded(filename, date);
  }
  else{
   setstate("error");
  }
}

function createXMLHttpRequest() {
   return this.XMLHttpRequest ? 
      new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
}

  
function all_properties(obj){
  var names="attrs: ";
  for(var i in obj)
    names+=i+"\n";
  return(names);
}
  
  
function check(){
  loadXMLFile('./test.cgi/check');
}
  
var counter = 0;
  
function loaded(filename, date){
  document.image1.src = filename;
  setstate((counter ++) + ": " + 
    filename + " (" + date + ")");
}

function setCheckTimer(obj){
  var interval = Number(obj.value);
  if(!interval || interval < 1){
    interval = 1;
  }
  obj.value = interval;
  window.clearInterval(timerID);
  timerID = window.setInterval("check();", interval * 1000);
}

function setImgSize(obj){
  if(obj.checked){
    document.image1.width = 640;
  }
  else{
    document.image1.width = 320;
  }
}
  
  // -->
</script>
  <body
    onload   = 'timerID = setInterval("check();", 2000);'
    onunLoad = 'clearInterval(timerID);'>
    <p>
      <img src='start.jpg' name='image1' boarder='1'/>
    </p>
    
    <div id='text1'> start </div>
    <input type='button' onClick='check();' value='reload image' />
    <div>
    check interval (sec): 
    <input type='text'   name='checktimerinterval' 
      onChange='setCheckTimer(this);' value='2' />
    <input type='button' value='reflect' />
    <br>
    double size?
      <input type='checkbox' name='doublesize' 
             onChange='setImgSize(this);' />
    </div>
    
    <div id='children'></div>
    
  </body>
</html>

こいつらで、簡易動画配信ができる。帯域は食いまくるわけですが。

JavaScript の使えるブラウザさえあれば、動画っぽいものが見ることができる。


今回の投票は他の方からネタを貰いました。


積年のバグがなおった。

\" を escapeHTML すると \&quote; になって、そいつを gsub 第二引数にしてアボーン。


うう、29件か。激戦だ。


鼠と竜のゲームを読んでるんですが、なんか終わり方がよくわからない。


shiro さんが出るとかいうドラマ、みそこねた orz


好きにコメントを編集してください。ただし、あまり他の人のコメントを書き換えることは感心しません。



back

tton 記述が使えます。YukiWikiな記述してりゃ問題ありません。

「行頭に#code」 と、「行頭に#end」 で挟むと、その間の行は pre で囲まれます。プログラムのソースを書くときに使ってください。

例:

#code

(なんかプログラム書く)

#end

リンクは

[[なまえ|http://www.example.org]]

とか

[[http://www.example.org]]

で貼れます。

$Date: 2003/04/28 10:27:51 $