面白いデスクトップの壁紙を探して
theotaku.comを見ると、タグではなく壁紙自体に自動的にタグを付けるソフトウェアを作成するのがいいと思った。 私は
Mac OS Xをメインのオペレーティングシステムとして使用しているという事実に基づいて、ソフトウェアはこのプラットフォームにも対応している必要があり、
Cocoaインターフェースが必要です。 何らかの理由で、私はこれらすべてをJavaで書きたくありませんでした。 もちろん、多くの選択肢がありましたが、何らかの理由で他のことを試して、同時に何か新しいことを学びたかったのです。 私はすぐに
MacRubyと
Cocoaとの密接な統合を思い出しました。 このアイデアを武器に、すぐに
http://www.macruby.org/にアクセスして、最新の安定バージョン0.10をダウンロードしました。 インストール後、お気に入りの
Xcodeを起動し、
AnimeWallpaperDownloaderという新しいプロジェクトを作成しました
MacRubyプロジェクトは、
Xcodeが作成するいくつかのファイルで構成されています。 最初のファイルは
main.mで、
MacRubyスクリプト
rb_main.rbを実行するだけ
です
rb_main.rbはかなり単純なスクリプトで、他のすべての
Rubyスクリプトをロードして実行します
NSApplicationMain framework 'Cocoa'
すでに作成した最後のファイルは
AppDelegate.rbで 、これは
NSApplicationDelegateの役割を
果たします。 これには、プログラムの起動が終了したときに呼び出される空の
applicationDidFinishLaunchingメソッドが含まれています。
class AppDelegate attr_accessor :window def applicationDidFinishLaunching(a_notification)
ここで
attr_accessor:windowは
IBOutlet * windowの役割を果たし、すでにプログラムのウィンドウに関連付けられています
MainMenu.xibを開き、壁紙ダウンローダー用のシンプルなインターフェイスを作成します

次に、
AppDelegateにメソッドと
アウトレットを追加します
class AppDelegate attr_accessor :window attr_accessor :tags attr_accessor :size attr_accessor :number attr_accessor :saveInto attr_accessor :startButton attr_accessor :output attr_accessor :downprogress attr_accessor :downloader attr_accessor :img def applicationDidFinishLaunching(a_notification) @startButton.setEnabled(false) @downprogress.setStringValue('') @output.setStringValue('') @saveInto.stringValue = NSHomeDirectory()+"/Pictures" end def windowWillClose(a_notification) NSApp.terminate(self) end def controlTextDidChange(notification) sender = notification.object if sender == tags @startButton.setEnabled(@tags.stringValue.size > 0) elsif sender == number begin @number.setIntValue(@number.intValue) if @number.intValue < 0 @number.setIntValue(-@number.intValue) elsif @number.intValue == 0 @number.setIntValue(20) end rescue @number.setIntValue(20) end end end def browse(sender) dialog = NSOpenPanel.openPanel dialog.canChooseFiles = false dialog.canChooseDirectories = true dialog.allowsMultipleSelection = false if dialog.runModalForDirectory(nil, file:nil) == NSOKButton @saveInto.stringValue = dialog.filenames.first end end def startStop(sender) if @downloader == nil @downloader = Downloader.new(@tags.stringValue,@size.selectedItem.title,@number.stringValue,@saveInto.stringValue,self) @downloader.start @startButton.setTitle("Stop Download") else @downloader.stop @downloader = nil @startButton.setTitle("Start Download") end end def changeImage(file) @img.setImage(NSImage.alloc.initByReferencingFile(file)) end def clearStatus @downprogress.setStringValue('') end def setStatus(i,m) @downprogress.setStringValue("Downloading "+i.to_s()+" of "+m.to_s()) end def setStatusEnd(i) @downprogress.setStringValue("Downloaded "+i.to_s()+" wallpapers") end def puts(val) $stdout.puts val @output.setStringValue(val) end def stopped @startButton.setTitle("Start Download") down = @downloader @downloader = nil down.stop end end
ここではすべてが非常に簡単です。
windowWillCloseメソッドと
controlTextDidChangeメソッドは、プログラムウィンドウと最初のテキストフィールドのデリゲートメソッドにすぎません(タグを入力するまで何もダウンロードできません)。
参照メソッドは、壁紙を保存するディレクトリを選択するダイアログボックスを開き、[
参照 ]ボタンに添付します。
startStopメソッドはジャンプを
開始するため、
[ダウンロードの
開始 ]ボタンにアタッチします。 残りのメソッドは補助的なものであり、
Downloaderクラスによって使用されます。これは、リンクの検索と壁紙のダウンロードに使用します
require 'thread' require 'net/http' class Downloader attr_accessor :tags, :size, :number, :saveTo, :thread attr_accessor :app, :exit def initialize(tags, size, number, saveTo, app) @tags = tags.sub(' ','_') @size = size == 'Any' ? '' : size.sub('x','_') @number = number @saveTo = saveTo @app = app @exit = false end def getIndexPage(page) walls = {} url = 'http://www.theotaku.com/wallpapers/tags/'+tags+'/?sort_by=&resolution='+size+'&date_filter=&category=&page='+page.to_s() @app.puts 'getting index for page: '+page.to_s() @app.puts url response = Net::HTTP.get_response(URI.parse(url)) res = response.body res.each_line { |line| f = line.index('wallpapers/view') while f != nil b = line.rindex('"',f) e = line.index('"',b+1) u = line[b+1,eb].gsub('"','') walls[u] = u line = line.sub(u,'') f = line.index('wallpapers/view') end } @app.puts 'got '+walls.size.to_s()+' wallpapers' return walls.keys end def downloadWall(url) @app.puts 'downloading '+url response = Net::HTTP.get_response(URI.parse(url)) res = response.body b = res.index('src',res.rindex('wall_holder'))+5 e = res.index('"',b) img = res[b,eb] self.downloadFile(img) end def downloadFile(url) name = url[url.rindex('/')+1,1000] if File.exists?(@saveTo+'/'+name) @app.puts 'wallpaper already saved '+name @app.changeImage(@saveTo+'/'+name) else @app.puts 'downloading file '+url response = Net::HTTP.get_response(URI.parse(url)) open(@saveTo+'/'+name, 'wb') { |file| file.write(response.body) } @app.puts 'wallpaper saved '+name @app.changeImage(@saveTo+'/'+name) end end def getWallUrl(i,url,size) sizes = {} i = i+1 @app.puts 'getting '+url+' sizes' response = Net::HTTP.get_response(URI.parse(url)) res = response.body res.each_line { |line| f = line.index('wallpapers/download') while f != nil b = line.rindex('\'',f) e = line.index('\'',b+1) u = line[b+1,eb] u = u.gsub('\'','') sizes[u] = u line = line.sub(u,'') f = line.index('wallpapers/download') end } sizef = @size.sub('_','-by-') sizes = sizes.keys() if sizef == '' maxi = 0 max = 0 i = 0 sizes.each { |s| f = s.rindex('/') l = s[f+1,100] l = l.sub('-by-',' ') l = l.split(' ') rs = l[0].to_i()*l[1].to_i() if rs > max maxi = i max = rs end i = i+1 } return sizes[maxi] else sizes.each { |s| if s =~ /
巨大なクラスは本当ですか? はい、ロジックが詰め込まれていますが、実際にはすべてが非常に簡単です。
startメソッドは、壁紙をダウンロードする別のスレッドを開始し、
停止するだけです。 メソッド
getIndexPage 、
getWallUrl 、
downloadWallは theotaku.comに固有であり、多くのロジックを含んでいますが、基本的に簡単で、タグで壁紙を検索し、目的の壁紙サイズへの目的のリンクを選択し、これらの壁紙をダウンロードするために使用されます
結果は日曜日の夜に費やされ、自己満足の良さ、そして
Mac OS Xの代替開発プラットフォームとしての
MacRubyの将来についての多くの興味深い考えがありました
。 もちろん、
レーキがあり、いくつかのことができませんでしたが、
MacRubyプラットフォームが人気を集め始めており、明るい未来があると思います。
ここで結果を見ることができますが、
ここ から完成したビルド
をダウンロードできます(
MacRubyがインストールされている必要があります)
ご清聴ありがとうございました
バイバイ

UPD:パーサーをリファクタリングして
くれたEstheteに
感謝します