はてなキーワード: GEMとは
仕事で3ヶ月ほどRuby on Railsに触れる機会があったので、色々と調べているうちにRailsでエロサイトを作るのが流行っているというのを知りました。
そこで、自分でも作ってみようかと思いました。
2番煎じなのは重々承知ですが、とにかく作ってみることが重要なのです。
今回のエントリでは、個人的にエロサイトを作成して公開するまで自分でやった方法を紹介します。
※公開後の状況なども書き込みします。
CuteClipper : http://cuteclipper.night-generations.info/
既にあるものなら新しく作る必要はないわけで、、、今回は自分の使いたい機能を作ってみました。
Xvideosの動画サイトの多くは、動画を選択すると他のサイト(ブログみたいなやつ)に飛ばされてしまい、
そのサイトで、動画のある場所を探さないといけないことが多くてめんどくさい。
自分で作るのならh300さんのように分かりやすいサイトにしたいと思いました。
たくさんの動画を観て廻るものの、本当にいいと思う動画は大体3本くらいです。(自分の場合)
なので、3本まで動画をストックする機能があるといいなと思いました。
本番環境のherokuはドメインの設定も簡単で助かりました。
rails newしてdb作成して、基本的なアプリを作成しました。
動画情報の解析のため、RailsのGemのnokogiriを使用しました。
nokogiriはhtmlなどの解析をして、情報を取得することができます。
Ruby - Nokogiriでスクレイピング - Qiita [キータ]
//localStrage.setItem("key","value"); localStorage.setItem("test","テスト"); //localStrage.getItem("key"); localStorage.getItem("test"); //"テスト"
レイアウトにはあまり時間を掛けず、bootstrapを利用しました。
twitter bootstrap railsを使ったら職が見つかり彼女も出来て背も3センチ伸びました。 - ppworks blog
タグクラウドはacts-as-taggable-onで簡単に実装できます。
ということで、ここまでで出来上がったものを本番環境にアップします。
herokuはgitでpushをするだけで簡単に本番環境にデプロイ出来ます。
とにかく動かすという目標のためにはherokuはベストチョイスです。
スピードに関しては、海外サーバという点が難点ですが、今回はjavascriptをメインにしたことで、それほど問題はありませんでした。
解析の仕方を覚えるためにもGoogle Analyticsを使用しました。
公開の準備として以下の作業をしました。
ただ、公開することを最優先にしたので、しっかり作りこんではいないです。
公開します。
今の投稿方法だとエラーが発生しやすいので修正してからじゃないとなぁ
後は、並び替えるだけなんですが、まずはカウントが貯まるまではソートも何もないので・・・
ストック回数だけじゃ物足りないので、評価をつけれるようにしたいです。
でも、たくさんの人に使ってもらえるものを作るというのは、とても大変ですね。
今回、CuteClipperを作りながら、他のWebアプリを観てきました。
そういうアプリの中で、自分のアプリを埋もれさせない努力を続けていかないといけないですね。
がんばります。というやる気がでました。
ども。
以前、はてな匿名ダイアリーで日記を書いた者です。
→【Ruby on Rails勉強】 xvideosまとめサイトっておいしいの?
上の記事でも書いていますが、Railsはおろか、Rubyを初めて触った人間がゼロからWebサービスをリリースするために利用しているGemを公開したいと思います。
サイト名 | onalife(オナライフ) |
---|---|
URL | http://www.onalife.com |
説明 | xvideos動画の共有・ユーザー参加型のまとめサイト |
developmentモードで起動する際のデータベースはsqlite3を使うようにしています。
コーディング→サーバー起動→動作確認→コーディング…という流れになりますが、サーバーを起動する際に、
$ rails s
と実行するだけでサーバーが起動できるため大変手軽です。
サーバー起動後はブラウザで http://localhost:3000/ でアクセスすれば開発用のサイトを確認できます。
productionモード(本番環境)で利用するのはMySQLを使うようにしています。
理由は他のWebサイトで推奨されていたため。
sqliteの場合だと、単純にDBのデータをファイルとして扱っており、同時に複数アクセスがあった際、最初のアクセス中にファイルがロックされてしまう仕様との記事をどこかで見たため、MySQLを使うようにしています。
developmentとproductionで動作を分けるには、 config/database.ymlで分けることができます。
development:
database: db/development.sqlite3
pool: 5
timeout: 5000
production:
encoding: utf8
pool: 5
timeout: 5000
よくWebサービスのページ下にある [1][2]・・・[X]といったリンクが表示されている、あれです。
http://memo.yomukaku.net/entries/238
https://github.com/amatsuda/kaminari
Unicorn + Nginx + Rails で構築しています。
効果の違いなどはGoogle先生に質問すると大量に返答がありますのでこちらでは割愛。
ONALIFE(オナライフ)では、xvideosの動画URLや画像パスを抜き出す為に、こちらのGemを使っています。
http://himaratsu.hatenablog.com/entry/2013/04/27/002249
自作するとなるとかなり労力使いますから…こういったところは極力他の人が作ってくれたものを流用してもバチはあたらんでしょう。
https://github.com/mbleigh/acts-as-taggable-on
通常だと管理画面も rails g xxx とかやって controller 作って、 view 作って…とかやらないといけませんが、こちらのGemを使うと一瞬で終わります。
素晴らしい!!
当サイトでは、投稿していただいたxvideosの動画が不適切な場合などに消去する必要があるため、どうしても管理者向けの画面が欲しかったのでこちらを使いました。
データベースを直接操作して delete とかできちゃいます。
http://www.func09.com/wordpress/archives/1136
自分のサイトのアクセス傾向を解析して、どうすればアクセスが伸ばせるか、ということを考察するのに必要不可欠な機能です。
通常、Google Analytics にサイトを登録すると、Javascript のコードが生成されるので、それをWebサービスに貼り付けるだけで完了ですが、こちらのGemを使うと、Google Analytics で生成されるID番号のみを登録するだけで自動的に挿入されるようになります。
まだONALIFE(オナライフ)は発展途上のサービスです。
機能を拡張していくうえで、先人たちのありがたいGemをどんどんこれからも活用していければ、と思っています。
みなさんもこれは便利!というお勧めのGemがあれば是非教えて頂ければと思います。
以上、ONALIFE(オナライフ)で利用しているGem一覧の紹介でした。
http://anond.hatelabo.jp/20101206224349
http://anond.hatelabo.jp/20101203150748
http://anond.hatelabo.jp/20120914214121
どっかで作ってほしいみたいなの見かけたので作りました。
※以下、開発系の話
主な使用gem) New Relic, Nokogiri, twitter bootstrap
参考)
最近iOS、Android向けの「神界のヴァルキリー」というゲームをやっている。いわゆる「ソーシャルゲーム」に属するもので、数百枚に上るカードを武器に一本道のシナリオをこなすというタイプのゲームだ。これが最近バージョンアップしたのだが、その中で、今まで無制限に上昇可能だった能力値を19999に制限するという措置がとられることになったのだが、ところが、この際に既に制限値を超えたプレイヤーに付いては値を引き下げないと発表した。まだ始まってそれほどでもないゲームだが、このために、スタートダッシュでアイテムを購入して能力値を上げた一部のプレイヤーが事実上最強の状態にとどまることになり、単に強いだけならともかく、ランダムマッチのPvPや魔女を倒す協力プレイがあることなどから、プレイヤーの間で反発を買うことになった。通常こうしたゲームでは、最初にある程度制限を行い、徐々にそれを解放していくのだが、サービス運営側はなぜか最初に制限を設けておらず、その点は十分問題がある。ただ、これは、そもそも運営の問題ではなくて、ゲームの仕様の問題ではないかと思うのだ。
先日App Annieというサイトが発表した数字で、日本のガンホーによるパズルズ&ドラゴンズが売り上げ一位になったと話題になった( http://blog.appannie.com/app-annie-index-social-networking/ )。ここで二位になり、その前までは一位だった"Clash of clans"は、日本で流行っている(とされる)カード収集型ソーシャルゲームとは全く違う。プレイヤーは防衛用に街を作り、兵士を生産し、その兵士でゴブリン村攻略のシナリオを進めたり、ランダムマッチのPvPを行う。いわゆるFree2Playなので、参加は無料だが、ゲーム内通貨であるGemを有償で購入することでゲームを優位に進めることが出来る。ただ、ゲームに出てくるキャラクターはバーバリアンだとかアーチャーだとかごく普通のものが10種類ほどあるだけ、街作りも壁や砲台を立てる地味なものだ。ゲーム開始当初の難易度は高くなく、設備や兵士の生産は短い時間で出来る。レベルが上がれば利用できる設備も増え、その代わり時間もかかるようになる。基本的に無料でも進められるが、Gemを利用するとこれらの生産が短時間に行えるようになるという仕組みだ。逆に言えば、Gemにはそれしか機能がない。レベルが上がると街作りに必要な条件が厳しくなるのでGemが必要だが、それ以外は特に利用することもない。ランダムマッチもレベルに合わせて行われるし、選択権もあるので、突然強いプレイヤーを倒さなければいけないこともないし、そこからの修復も簡単に出来る。要するに、金をかけた所で、他のプレイヤーを圧倒することはほとんどないのだ。
その一方、「神界のヴァルキリー」や、それに近いゲーム(この前に「海賊ファンタジア」という、同じくカードの強さがものを言うゲームもやっていた)は、金をかけた分が、そのまま強さに反映する。通常入手できるカードはほとんど能力が無いに等しく、R(レア)とかSR、HSRと呼ばれるカードを入手するかしないかが、プレイヤーのゲーム進行を左右することになる。「神界のヴァルキリー」に至っては、強化用のアイテムも有償で購入することも出来る。強力なアイテムの入手はプレイヤーのレベルと関係なく機能するため、ゲーム開始時点からいきなり最強になることも可能だ。
こういう仕様は一見筋が通っているように見えるが、課金システムとゲームが強く絡んでいるため、一歩舵取りを間違えるととても面倒なことになる。レベルの解放やカードの入手率の変更が、そのままダイレクトにプレイヤーに影響を与え、どういう変更を施そうが、大抵の場合に有利/不利がどこかで発生してしまう。発生するだけならまだしも、有償サービスの利用者まで巻き込んでしまうため、センシティブな不満が出やすくなる。つまり、ゲームの仕様変更で不満が出るのは、単に「運営が悪い」という話だけではなくて、ゲームの根本的な所に欠陥があると思わざるを得ないのだ。
正直言って、こういうゲームばかり開発されている現状は、少し心許ない。パズドラをやれば認識は変わるのかもしれないけど、それでも、しばらくこの波は止まりそうも無いし、こうした欠陥に気づかない限り、残念ながら疲れるような騒動はしばらく続くのだろう。
例に漏れず件のエントリーに影響を受けまして、Ruby on Rails を利用したサービスを作ってみました。
一つもアクセスがないため宣伝ついでに利用したgemや作成する際に参照したサイトを載せますので、「Rails初心者っす」とか、自分と同じく「そもそもプログラミングとか知らねっす」という方はちょっとしたナレッジとしてご活用くださいまっせ。開発ガンガンやってる方には価値ある情報たぶんないよー。
最初はMac標準のエディタで書いてたけど、どこかの記事を読んでからは「Sublime Text 2 (http://www.sublimetext.com/)」に乗り換えました。すごく…便利です…。ターミナルはMac標準のアレです。オススメがあったら教えてください。
完成までにやったこと、実装するために参考にしたサイトを並べます。
RubyとRailsの環境を構築する。(http://www.oiax.jp/rails/rails3/install.html)
簡単にウェブアプリの土台を作れるScaffoldという機能を使って遊んでみる。(http://www.techscore.com/tech/Ruby/Rails/quick-start/Rails4/4-1)
行き詰まったので本を買う。(たのしいRuby、Ruby on Rails 3 アプリケーションプログラミング、Rails 3 レシピブック)(※ 同タイミングで買ったわけではないです。簡単にウェブアプリを作るだけなら「Ruby on Rails 3 アプリケーションプログラミング」とインターネットに接続できる環境があれば十分だと思います。ていうか他の二冊はまだ全部読んでない。)
ひと通り分かった気になり、作りたいものを作る作業へ。
$ rails new sicolip
色んなgemがあって迷う。
・Device(https://github.com/plataformatec/devise) ・omniAuth(https://github.com/intridea/omniauth)
でも、
・Deviceはメールアドレスでの認証 ・omniAuthはtwitter/fb認証
個人的に
・エロサイトにメアドを登録したくない ・エロサイトの認証がtwitter/fbってなんか怖い
ということで、自前で実装。has_secure_password(gem:bcrypt-ruby) を利用する。
サイトをクリップ(URLを投稿)したときに該当するサイトのタイトルとか内容を取得する処理。
Nokogiri::HTML(open(target_url))
こんな感じでNokogiriオブジェクトを取得して、
return doc.xpath('//title').text
こんな感じでタイトルを取得する。こちらでxpathほかのお勉強。
ログインしている人にしかクリップ(URLの投稿)をさせたくない。そんなときに使える認可処理。
クリップしたサイトの情報をタグで管理したい。タグ機能の実装を手抜きできるのがこのgem。
・https://github.com/mbleigh/acts-as-taggable-on
・http://prototype-beta.com/tags/acts-as-taggable-on
上記を参考に。
クリップしたサイトの情報をタイトルや内容、またはタグから検索したい。
その処理を手抜きさせてくれるのがsunspotさん。サーバにデプロイしたあとに
$ rake sunspot:solr:start
・http://railscasts.com/episodes/278-search-with-sunspot?language=ja&view=asciicast
・http://outoftime.github.com/sunspot/docs/
will_pagenateっていうgemもあるんだけど、kaminariが最近の流行りらしい。
・https://github.com/richardiux/sunspot_with_kaminari
ということで、はてなブックマークみたいなブックマークレットを作る。
・http://d.hatena.ne.jp/ky2009/20090108/1231405893
herokuとやらが設定周りの色々めんどくさいことを肩代わりしてくれるという噂。しかも無料。
→ sunspotが有料オプションでした。やめる。
AWSというAmazonのサービスが設定によっては無料らしい。
→ ほんとに無料だった。AWS内のElastic Beanstalkというサービスが、herokuみたいにめんどくさいことを色々やってくれる。
・http://blog.serverworks.co.jp/tech/2012/06/28/aws-elastic-beanstalk/
・http://qiita.com/items/811cd9b614d8d300628e
そんなこんなで出来上がったものは陳腐なものかもしれませんが、まがいなりにもひとつのサービスができました。ここ1カ月だらーっとRubyとRailsをさわってみて感じたことは、ウェブアプリを作るのって特別なことじゃないんだなーっていう。どこかで誰かも言ってましたけど、開発している最中はパズルを解いてる感覚でした。ウェブに転がるピースを探して、フレームワークにあてはめていくようなそんな感覚。
おしまい!
書き捨て
https://github.com/tdtds/massr
bundle install --path vendor/bundle Gemfile syntax error: /h/massr/Gemfile:14: syntax error, unexpected ':', expecting kEND gem 'sinatra-reloader', require: 'sinatra/reloader' ^ /h/massr/Gemfile:16: syntax error, unexpected ':', expecting kEND gem 'pit', require: 'pit' ^ sudo gem install sinatra Successfully installed sinatra-1.3.3 1 gem installed Installing ri documentation for sinatra-1.3.3... unrecognized option `--encoding=UTF-8' For help on options, try 'rdoc --help' ERROR: While generating documentation for sinatra-1.3.3 ... MESSAGE: exit ... RDOC args: --ri --op /Library/Ruby/Gems/1.8/doc/sinatra-1.3.3/ri --line-numbers --inline-source --title Sinatra --main README.rdoc --encoding=UTF-8 lib README.de.rdoc README.es.rdoc README.fr.rdoc README.hu.rdoc README.jp.rdoc README.ko.rdoc README.pt-br.rdoc README.pt-pt.rdoc README.rdoc README.ru.rdoc README.zh.rdoc LICENSE --title sinatra-1.3.3 Documentation --quiet
アホか
Rails3 と jQuery で、真面目にオシャレなエロサイトをつくってみました。 - h300
http://d.hatena.ne.jp/inouetakuya/20120331/1333192327
に触発されて、オシャレエロサイトを作ってみました。
オシャレエロサイトを作ろうと思ったのはいいのですが、デザインは苦手なので途方に暮れていました。
h300の方はペパボのソフトウェアエンジニアらしいのですが、こっちはただの素人プログラマー。
そこで何か裏ワザみたいなものはないかとググっていると、Twitter Bootstrapという文字が目にとまりました。
Bootstrapの名前は知っていましたが、深い内容までは知りませんでした。
ですが、紹介記事を読んでみると自分の理想に近かったので早速使ってみることにしました。
Twitter Bootstrapはある程度有名だと思うんですが知らない方のために説明すると、
CSSフレームワークの一つで、ウェブデザインの作成を手助けしてくれるものです。
色々なCSSフレームワークを見ましたがTwitter Bootstrapが一番完成度が高いと感じました。
ウィキを見ると最初のリリースが2011年8月なので比較的最近のものですね。
普段、みなさんがウェブサイトを作る時、HTML + CSSで作られるかなと思うんですよね。
この時、CSSが事前に用意されているとすごく楽じゃないですか?
CSSフレームワークはCSSの大部分を前もって用意してくれているんですよ。(フレームワークによりますが)
ですので基本的にCSSに合わせてHTMLを記述するだけでウェブサイトが出来てしまいます。
CSSに合わせてHTMLを記述するとはどういうことでしょうか?
この文章は薄い青色でハイライトされていますよね? Bootstrapで似たようなことをする場合 <div class="well"> ハイライトしたい文章 </div> という感じになります。
classにwellと指定しているだけですね。
なぜそうするだけで文章がハイライトされるかというと、
divのclassにwellが付いていたら、いい感じでハイライトしてねっていう指示が
Twitter BootstrapのCSSに書いてあるからです。
BootstrapのCSSには、divのclassにalert alert-errorっていうのがあったら警告文だしてねとか、
button class="btn"ってあったらボタン表示させてねとか色んなことが最初から書いてくれています。
もちろん見栄えがよくなるように記述されていますので、classを指定するだけでモダンなデザインになるわけですよ。
CSSに合わせてHTMLを記述するだけでウェブサイトが出来るというのはこういうことです。
でも、最近のウェブサイトは HTML + CSS + JQueryという場合も多いですよね。
安心してください。Twitter Bootstrapの場合はJQueryの基本的な部分も用意してくれています。
ですのでドロップダウンメニューやタブ、スライドショーなどの実装も簡単にできます。
それに加えてBootstrapはよく使うアイコン数百種類まで用意してくれています。
至れり尽くせりですよ。
神様ですね。
CSSが固定化されていると、HTMLも自動的に固定化されます。
CSSに合わせて記述するので当たり前といえば当たり前ですね。
CSSの記述は一定、HTMLもある程度一定なので、メンテナンスが格段にやりやすくなります。
個人プログラマーの方だと、サイトごとにHTMLもCSSもグチャグチャという方も多いのではないでしょうか?
フレームワークを使えばそういうこともなくなるということです。
Twitter Bootstrapの凄さはそれだけではありません。
現在、ユーザーがどんなデバイスでウェブサイトにアクセスしてくるか分かりません。
PC、スマートフォン、iPad、TV、3dsなど全てのデバイスに合わせてデザインを作るのは時間がかかりすぎます。
でもTwitter Bootstrapならbootstrap-responsive.cssというCSSを選ぶだけで、
デバイスの横幅に合わせてデザインが変わるレスポンシブなウェブサイトができます。
もちろんデメリットもありまして、サイトのデザインが似てしまうというのが難点です。
ですが基本はBootstrapを使って、ちょっと自分でカスタマイズしてオリジナルっぽくすることもできますので、
一度Twitter Bootstrapを使ってみる価値はあると思います。
http://twitter.github.com/bootstrap/
Bootstrapの説明が長くなってしまいましたね…。
1.エロいサイトを巡って、XVIDEOSやFC2動画などのリンク、embedされたものがあれば取得。
3.データベースに登録。
一連の作業をクローラーにやらせるプログラムをRubyで書く。
RailsでBootstrapを使うにはtwitter bootstrap railsというgemを使うらしいです。
しかし、使おうと思ったのですが、windowsでは上手くインストールできませんでした。
仕方なく、代わりにsass-rails-bootstrapというものを使いました。
違いはcssにLESSをつかっているかsass(scss)を使用しているかだと思います。
http://d.hatena.ne.jp/tkawa/20120219/p1
の記事が参考になりました。
ちなみにLESSとかSassってのはcssを効率的に書けるすぐれたものです。
最近、webクリエイターボックスさんでも紹介されていました。
http://www.webcreatorbox.com/tech/css-sass/
railsでは3.1からcoffee scriptと共にsassがデフォルトで使えます。
このあたりがRailsの素晴らしさですね。
Bootstrapは画像を綺麗に並べて表示することにも向いているので、
アダルトサイトと相性がいいなと感じました。
AV女優名とか女子校生、人妻などのジャンルのタグがあれば便利ですよね。
Railsではacts-as-taggable-onというgemを使い実装しました。
動画のタイトルが事前に用意したAV女優名リスト、ジャンルリストと合致すればタグ付けするという感じです。
AV女優リストはDMMから、ジャンルリストは大手アダルトサイトから作成しました。
タグ付けするときに あおいそら-蒼井そら みたいな感じでタグ付けするようにしました。
もっとスマートな方法があるはずですが思いつかなかったので仕方ないです。
ア行、カ行…のように行別にわけて、なおかつアイウエオ順で表記してますので
クッキーを使ってログイン不要のブックマーク機能を作りました。
jquery.cookie.jsを使って、cookieを配列に直してごにょごにょしてという感じで実装しました。
削除ボタンを押すと非同期で通信して…などいろいろ面倒でした。
でも、動画の数はかなり増やしていこうと思っていましたので頑張って実装しました。
動画の下のブックマークするボタンを押していただければブックマークできます。
ブックマークするボタンの表示などにBootstrapの便利さを感じました。
実はこれが一番やりたいことでした。
多くのアダルトサイトは広告だらけで、肝心の動画がポツンと小さくあるだけというのが多いです。
戦場で疲れた兵士たちに、そんなせせこましい画面でアダルト動画見ろって?
そんな野暮なこと言いませんよ。
PCスクリーンの画面いっぱいに、大画面で、ドカーンとエロ動画を楽しんで下さいよ。
動画はできるだけ大きく表示しています。もちろんレスポンシブです。
全画面表示にすりゃいいじゃん…っていうのは違うんですよ。
全画面表示だと逃げれないじゃないですか!
不意に誰かが部屋に入ってきたらどうするんですか?
そう考えております。
Bootstrapでデザイン面はスマホ対応にはなっているのですが、
加えてjpmobileというh300で紹介されていたgemを使って、
CPU 2.66GHz、メモリ 2.2GB HDD200GBです。
Railsは遅いので少しでも速くするためにApacheの代わりにNginx使おうと思ったのですが、
PC用のキャッシュとスマホ用のキャッシュを別々に保存して使う
ということがどうしてもできませんでした。
PC用のキャッシュがある場合、スマホ用のキャッシュがなくてもキャッシュがあると認識されるなど、
もともとNginxとrailsのページキャッシュは相性が悪いようです。
Nginx側でキャッシュする、もしくはスマホ用のアドレスを別にすればできるかもしれないですが、
http://m.サイト名 みたいにするのが嫌だったので最終的にNginxを使うことをやめました。
Nginxに関するネット上の記述も少ないので運用するのは危険かな、ということもあります。
Nginxを少しだけ使ってみた感触はかなり速いというものだったので残念でした。
バージョンが変われば、また挑戦したいですね。
【追記】
やっぱNginxでもいけるかもしれないですね。
紹介しないと終わらないということで紹介します。
http://nukisen.com (エロ注意)
サイト名はオシャレに横文字でNukisenにしました。読み方はヌキセンです。
http://bootswatch.com でダウンロードできるBootstrapのテーマそのままですが、
Bootstrapを使うと自動的に細部まで凝ったデザインになるので最高ですね。
下にスクロールしていくと背景のグラデーションが変化したりとか、とても一人ではできないですよね。
長々と説明してきましたが、
ぜひNukisenで大画面のアダルト動画を体感してほしいです。
しばらくは一日30本ぐらいの更新でいく予定です。
アダルトサイト同士の相互リンクでアクセス増やしてなどはしない方向です。
新しいことに挑戦すると得られるものが多いなと感じました。
ウェブサイトを作る際、無意識のうちに自分のできる範囲の技術で構築しがちだと思うんですが、
そうすると成長はないですね。
長文失礼しました。
週末に行ってきたイベントだが、ちょっとインパクトが強すぎて、あとたぶん昼から通しで追っかけてるのは自分だけなので、この話誰かに伝えたい!と柄にもなく思ってしまった。
ここまで、日本語でウケを取り、アメリカ人にしか聞こえない英語をしゃべりつつの話。まじありえないレベルの覚悟と実践なんだが・・・!
この人のセッション、ブラジル事情の紹介みたいな話で大ホール側のセッションも覗いてみようかなと思っていた所にこれで、ただちに絶対参加すべきレベルのセッションに格上げされた。こんな人がいるとは。
で、昼休み後の問題のセッション。結局ツイートどころじゃなかったが、こんな感じ:
Javaはあれが酷いとかPHPがとかいう態度でRubyを使うのも無駄だ。
なんという激熱トーク。本当に小さかった南米のRubyコミュニティを仲間と共に成長させ、いまやRubyConf Brazilとか南米で何個もイベントが立ち上がるまでに育てた。この伝道のため、ここ数年で80箇所は回って普及に努めたとかとか。ブラジル事情への関心と関係なく、この熱量を体験できてよかった。
最後の時間オーバー後の「あと一言だけ(本当はあと1分だけと本人は言っていたのだが、わざと誤訳してタイマー役の人に会場から叫んだ自分w)」でどんなにダメだとされていても、諦めずに進めという、過去の偉人が貶められたり失意にあった時代の動画もよかった(もっとも、この話は知っていたのでインパクト自体は薄めだった)。
この後はLTとクロージング。
インパクト強すぎw
これ漫画系展開をバックボーンにしたエンタテイニングなスタイルだと理解せずに真に受けると大変だなと心配になったり。なにしろ上は三行だけど全部通しで書くと
真面目に受け取ったらヤバイ発言多すぎだろ・・・
こ れ が 締 め の 講 演 か よ !
そういえば途中にまどマギネタも入ってた記憶があるのだが、上のインパクトが強すぎてどこかに飛んでった。
その後の高橋さんの最後の挨拶とスタッフを集めてのスタンディングオベーションはちょっとうるっと来た。初参加だから今回の運営自体への思い入れはないのだけど、この回だけでも感激することが多かった。この完成度に達するまでどれだけの努力と熱意が投入されていたかと考えると。
隣の席が実はtdtdsさんでびびってたのだが、最初に立ち上がったのを見て、続く二人目のタイミングが大事!とすぱっと立ち上がってみてよかった。その後前列の人がみんな!立とうよ!みたいにやって一気に雪崩状態。
これで会議は閉幕したのだが、さらにherokuの緊急パーティーが開催され、思い切って行ってみた。まあ、懇親会に輪をかけたリア充な雰囲気でまともに話せなかったのだが、
こんな一日だった。熱かった・・・
結構苦労したので健忘録として。。
環境は以下のとおり
yum install mysql-server
/etc/init.d/mysqld start
mysql_secure_installation
jruby -S gem install rails jruby -S gem install warbler jruby -S gem install activerecord-jdbc-adapter jruby -S gem install activerecord-jdbcmysql-adapter jruby -S gem install jdbc-mysql
mysql -u root -p mysql> create database redmine character set utf8; mysql> grant all privileges on redmine.* to 'redmine'@'localhost' identified by 'redmine'; mysql> exit
(任意の場所にRedmineを解凍して、解凍先のディレクトリに移動した後)
cp config/database.yml.example config/database.yml vi config/database.yml
database.yml
production: adapter: jdbcmysql database: redmine host: localhost username: redmine password: redmine encoding: utf8 #development: # # #test: # #
後のwarbleでのエラーを防ぐため、developmentとtestをコメントアウト
jruby -S rake generate_session_store jruby -S rake db:migrate RAILS_ENV=production jruby -S rake load_default_data RAILS_ENV=production
script/serverで起動し、http://localhost:3000 にアクセスして正常に動作するか確認する
jruby script/server -e production
vi config/environments/production.rb config.logger = Logger.new(config.log_path) config.logger.level = Logger::INFO
warble.rbを生成
jruby -S warble config
warble.rbを修正
vi config/warble.rb config.dirs = %w(app config lib log vendor tmp extra files lang) config.gems = ["jdbc-mysql", "activerecord-jdbcmysql-adapter", "activerecord-jdbc-adapter"] config.gems["rails"] = "2.3.5" config.gems["rack"] = "1.0.1" config.webxml.rails.env = "production"
jruby -S warble
できたwarファイルをTomcatに配置して、Tomcatを起動する
mv redmine-0.9.3.war /usr/local/tomcat/webapps/redmine.war /usr/local/tomcat/bin/startup.sh
warblerのバグ(?)でwarに入らないファイルをコピーして入れる
cp vendor/gems/rubytree-0.5.2/.specification /usr/local/tomcat/webapps/redmine/WEB-INF/vendor/gems/rubytree-0.5.2
WinXP機に、ruby on rails インストール中(gem使用中)に下記のエラーが発生した。
ERROR: http://gems.rubyonrails.org/ does not appear to be a repository
一時間ほど格闘した結果、プロキシの設定をしてないだけだった。環境変数HTTP_PROXYを作り、URLを設定する必要があるらしい。
Goto the cmd line
set HTTP_PROXY=http://mycache:8080
http://wiki.openqa.org/display/WTR/FAQ#FAQ-HowdoIgeminstallWatirbehindaproxyserver%3F
Campingのコアはたったの4kb程度しかありません
(ただ約4kbというのはコメントと改行を除いたcamping.rbのサイズで、
コメント付きのcamping-unabridged.rbは約26kbあります)。
これなら誰でも全てのコードに目を通せるはずですし、
私でも一時間くらいで出来ました。
Camping, the Documentation » File: README
gem install camping
sudo gem install camping
gem install sinatra
sudo gem install sinatra
Lightweight Webservices with Sinatra and RestClient - SlideShare
Slide 17:
A commitment to small
Rails 87,990
Merb-core 12,417
Ramaze 11,796
Camping 1,704
Sinatra 1,576
lib/sinatra.rb at master from bmizerany's sinatra — GitHub
sinatra.rb
1471 lines (1282 sloc) 45.402 kb
せっかく書いたから匿名でのせてみるよ
使い方は
必要なものを gem で取ってくるにはこうすればいいよ
長すぎてelispが消えたから続きがあるよ
@echo off setlocal set WD=%~dp0 cd /d %WD% ruby get_movies.rb ruby get_images.rb ruby create_m3u.rb
user: ユーザID password: パスワード ids_file: ids.txt done_file: ids_done.txt movies_dir: movies log4r_config: pre_config: global: INFO loggers: - name: app type: Log4r::Logger level: INFO outputters: - STDOUT - FILE outputters: - name: STDOUT type: Log4r::StdoutOutputter formatter: type: Log4r::PatternFormatter pattern: "%d [%l] %C - %M" date_pattern: "%H:%M:%S" - name: FILE type: Log4r::FileOutputter filename: "#{LOGDIR}/sangels.log" formatter: type: Log4r::PatternFormatter pattern: "%d [%l] %C - %M" date_pattern: "%Y-%m-%d %H:%M:%S"
require 'fileutils' require 'logger' require 'mechanize' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" require "#{BASEDIR}/sangels" $config = load_config(BASEDIR) prepare_logger(BASEDIR) $log = new_logger("get_movies") WWW::Mechanize.log = new_logger("mechanize") WGet.log = $log class IDFile def initialize(file) @file = file unless File.exist?(@file) Fileutils.touch(@file) end end def ids(contains_comment = nil) File.open(@file) {|io| io.to_a.map {|x| x.chomp }.select {|x| if x.empty? nil elsif contains_comment true else not /^\s*\#/ =~ x end } } end def add(id) ids = ids(true) unless ids.any? {|x| x == id} write(ids + [id]) end end def delete(id) ids = ids(true) if ids.any? {|x| x == id} write(ids - [id]) end end def write(ids) File.open(@file, "w") {|io| ids.each {|x| io.puts x} } end end $log.info("BEGIN #{$0} ================") exit_code = 0 begin ids_file = IDFile.new($config.ids_file) done_file = IDFile.new($config.done_file) movies_dir = $config.movies_dir wget = WGet.new sangels = SAngels.new sangels.login($config.user, $config.password) ids_file.ids.each {|id| begin movies = sangels.movies(id) rescue SAngels::Movies::InvalidMoviesError $log.warn("invalid movie id: #{id}") next end dir = File.expand_path(id, movies_dir) movies.each {|link| wget.retrieve(link.href, dir) } expected = movies.movie_links.map{|x| File.basename(x.href)} actual = Dir.glob("#{dir}/*").map {|x| File.basename(x)} if (expected - actual).empty? done_file.add(id) ids_file.delete(id) end } rescue => e $log.error(e) exit_code = 1 end $log.info("END #{$0} (#{exit_code}) ================") exit exit_code
require 'fileutils' require 'logger' require 'mechanize' require 'ostruct' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" require "#{BASEDIR}/sangels" $config = load_config(BASEDIR) prepare_logger(BASEDIR) $log = new_logger("get_images") WWW::Mechanize.log = new_logger("mechanize") WGet.log = $log $log.info("BEGIN #{$0} ================") exit_code = 0 begin movies_dir = $config.movies_dir sangels = SAngels.new sangels.login($config.user, $config.password) thumbnails = sangels.thumbnails Dir.glob("#{movies_dir}/*").each {|dir| next unless File.directory? dir id = File.basename(dir) url = thumbnails.url(id) unless url $log.warn("#{id} is not found") next end path = File.expand_path("00_thumbnail#{File.extname(url)}", dir) next if File.exist? path $log.info("retrieving #{url}") thumbnail = thumbnails.get_file(id) File.open(path, "wb") {|io| io.write(thumbnail)} } rescue => e $log.error(e) exit_code = 1 end $log.info("END #{$0} (#{exit_code}) ================") exit exit_code
BASEDIR = File.dirname($0) require "#{BASEDIR}/util" $config = load_config(BASEDIR) movies_dir = $config.movies_dir Dir.glob("#{movies_dir}/*") {|dir| next unless File.directory? dir name = File.basename(dir) files = Dir.glob("#{dir}/*.wmv").sort File.open("#{movies_dir}/#{name}.m3u", "w") {|io| files.each {|file| io.puts "#{name}/#{File.basename(file)}" } } File.open("#{dir}/00_movies.m3u", "w") {|io| files.each {|file| io.puts "#{File.basename(file)}" } } }
require 'mechanize' require 'hpricot' BASEDIR = File.dirname($0) require "#{BASEDIR}/util" class SAngels HOST = "real2.s-angels.com" LOGIN_URL = "http://#{HOST}/member/" INFO_URL = "http://#{HOST}/teigaku/item.php" THUMBNAILS_URL = "http://#{HOST}/teigaku/" THUMBNAIL_URL = "http://#{HOST}/images/default/thumb/" def initialize() @agent = WWW::Mechanize.new end def login(user, password) login_form = @agent.get(LOGIN_URL).forms.find {|form| form.fields.any? {|field| field.name == "frmLoginid"} } login_form.frmLoginid = user login_form.frmPw = password @agent.submit(login_form) end def movies(id, no_validate = nil) Movies.new(@agent, id, !no_validate) end def thumbnails Thumbnails.new(@agent) end class Thumbnails def initialize(agent) @agent = agent doc = Hpricot(@agent.get_file(THUMBNAILS_URL)) elems = doc.search("div[@class=realthum]/a") @links = Hash( elems.map {|elem| href = elem["href"] id = $1 if /ID=(.+)/ =~ href url = elem.search("img")[0]["src"] [id, url] }) end def get_file(id) @agent.get_file(url(id)) end def url(id) @links[id] end def exist?(id) url(id) end end class Movies class InvalidMoviesError < StandardError end def initialize(agent, id, no_validate) @agent = agent @id = id if !no_validate && !valid? raise InvalidMoviesError end end def info_page_url "#{INFO_URL}?ID=#{@id}" end def info_page @agent.get(info_page_url) end def movies_page @agent.click(info_page.links.find {|link| /P=10/ =~ link.href}) end def movie_links movies_page.links.select {|link| /wmv$/ =~ link.href }.sort {|a, b| File.basename(a.href) <=> File.basename(b.href) } end def valid? info_page.uri.to_s == info_page_url end def each(&block) orig_links = movie_links orig_links.each {|orig_link| link = movie_links.find {|l| File.basename(l.href) == File.basename(orig_link.href)} block.call(link) } end end end
require 'log4r' require 'log4r/yamlconfigurator' require 'singleton' require 'fileutils' require 'ostruct' def Hash(a) Hash[*a.flatten] end def load_config(basedir) OpenStruct.new(File.open("#{basedir}/config.yaml") {|io| YAML.load(io)}) end def new_logger(name) Log4r::Logger.new("app::#{name}") end def prepare_logger(basedir, logdir = nil) logdir ||= basedir Log4r::YamlConfigurator["LOGDIR"] = logdir Log4r::YamlConfigurator.load_yaml_file("#{basedir}/config.yaml") end class NullObject include Singleton def method_missing(message, *arg) NullObject.singleton end end class WGet class << self attr_accessor :log def initialize super @log = NullObject.singleton end end def log self.class.log end def retrieve(url, dir) FileUtils.mkdir_p(dir) file = File.expand_path(File.basename(url), dir) if File.exist?(file) log.info("already retrieved #{url}") return true end tmp = "#{file}.part" log.info("retrieving #{url}") ret = system("wget", "-c", "-O", tmp, url) if ret log.info("retrieving succeeded #{url}") File.rename(tmp, file) else if $? == 0x020000 # Ctrl-C exit($?) else log.error("retrieving failure #{url} (#{$?})") end end return ret end end
と、いう謳い文句にそそのかされてRubyとRuby on Railsをインストールして、説明通りにセットしてみた。動きゃしねぇ。調べてみると、バージョンが変わっているのでデフォルトのDBが違うらしい。あと、環境プログラムのGEMも微妙に動きが変で、今は「ワンクリックで動く便利なインストーラー」があるのだとか。試してみる。なぜか「gemが古い」と言い出す。指示通りアップデート。
で、もう一度紹介されていたサンプルを組んでみるが、scaffoldという呪文を、メソッド実行時に受け付けてくれずloadErrorが出る。検索して、コマンドラインからscaffoldを生成してみたが、今度はエラーを吐いた後、サーバーすら立ち上がらなくなった。
Ruby使えねぇ。などとは言わない。「簡単に使えるというのはマーケティング上の嘘で、トラブルを回避するためのバッドノウハウをたくさん勉強しなければならないらしい」という、至極あたりまえな、うすうす予想していた結果。
TWTR: Summary for Twitter, Inc. Common Stock- Yahoo! Finance
Twitterの株式公開初日。株価は74%上昇して45.10ドル。時価総額は318億ドル | TechCrunch Japan
Twitter、今年6月にユーザー5億人超か―ブラジル急成長、ツイート数では日本語が依然英語に次いで2位 | TechCrunch Japan
GOOG: Summary for Alphabet Inc.- Yahoo! Finance
Railsにある20%のソリューションで問題の80%を解決できるようにしています。
http://www.atmarkit.co.jp/news/200711/16/twitter.html
ウィリアム氏がOdeo内で始めた小さなプロジェクトが「Twitter」だ。
Ruby on Railsを使って2週間で最初の動くバージョンを 作り上げた
はてなブックマーク - Route 477 - Ruby基礎文法最速マスター&Ruby書籍紹介
Ruby on Railsで10分で作るTwitterもどき
Ruby on Railsをすぐ使う - Ruby on Rails 2.0アプリを1分で作る:ITpro
Ruby on Rails 2.0アプリを10秒で作る2.0
katoy: cocolog: Rails 2.0.2 は 5 行でアプリ雛形作成/起動ができる!
Ruby on Rails チュートリアル:実例を使ってRailsを学ぼう - Michael Hartl (マイケル・ハートル)
クックパッド株式会社 に行ってきた! - 941::blog
Ruby on Railsで1億PVのサイトの開発が出来て、エンジニアは5人しかいない
クックパッド(株)【2193】:株式/株価 - Yahoo!ファイナンス
ウォンテッドリー株式会社 に行ってきた! - 941::blog
ココロオドル仕事を見つける方法 | 仲 暁子 | 本 | Amazon.co.jp
Wantedly 航海日誌 — 私のようなの素人のためのHacker Way
はてなブックマーク - アイディアに価値はない by 仲 暁子
http://anond.hatelabo.jp/20130101082333
Focus on Technology:Ruby on Railsとエンタープライズを結び付ける「Merb」 (1/2) - ITmedia エンタープライズ
「Rubyに恋をし、Rubyが長きにわたって存在すると感じた人はたくさんいる。そして彼らはもっと強力なものを求めたのだ」
Merb 1.0 リリース記念に、Merb がどんだけすごいのかを紹介した海外の記事を翻訳してみた
速報: Merb と Rails が統合 - kwatchの日記
http://www.google.com/webhp?hl=en
http://www.google.com/search?hl=en&q=ruby&btnG=Google+Search
ブラウザで Ruby on Rails 開発! Heroku を使ってみよう - WebOS Goodies
ブラウザでRails開発が完了する衝撃の簡単さ - builder by ZDNet Japan
CやPerl、Python、Rubyをブラウザ上で実行できる「codepad」:phpspot開発日誌
C言語をブラウザで実行、Ruby/Python/Perlも然り | マイナビニュース
Odeo内で始めた小さなプロジェクトが「Twitter」だ。Ruby on Railsを使って2週間で最初の動くバージョンを作り上げたという。
Ruby on Railsで1億PVのサイトの開発が出来て、エンジニアは5人しかいない
http://blog.kushii.net/archives/1350951.html
http://d.hatena.ne.jp/gamella/20081027/1225119262
3ヶ月、わずか3名程度のエンジニアチームで、彼らはPHPで実装が完了していたレベルに追いつきました。またコード量はPHPの1/5以下にまで削減されており、よりシンプルな構成も実現できました。
Gregg PollackとScaling Railsのハウツー
1つには、Railsアプリケーションをうまくスケーリングするために必要なすべての情報をRails開発者に与えること。
しかし、できれば、開発者がビデオを見て、何百万人の同時ユーザーを扱うRailsアプリケーションを
作成できます、とクライアントに言える自信を持ってもらいたいのです。
2番目に、Railsアプリケーションをスケーリングすることがどれほど簡単かを、他の言語の開発者に示すこと。
http://www.infoq.com/jp/articles/gregg-pollack-scaling-rails
Ruby on Railsで10分で作るTwitterもどき - ZDNet Japan
http://japan.zdnet.com/video/screencast/story/0,3800079413,20354695,00.htm
Rails 2.0.2 は 5 行でアプリ雛形作成/起動ができる!: katoy: cocolog
http://youichi-kato.cocolog-nifty.com/blog/2008/01/rails_202_5_9198.html
Ruby on Rails 2.0アプリを1分で作る - Ruby on Railsをすぐ使う:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20080606/306873/
30分で Rails youtubeアプリ - 脱・下流エンジニア (仮)
hp12c - Railsでブログを作ろう!(Creating a Weblog in 15 minutes)
Ruby on Railsで10分で作るTwitterもどき - ZDNet Japan
Rails Pocket Reference (Pocket Reference (O'Reilly)): Eric Berry: 0636920520702: Amazon.com: Books
http://127.0.0.1/phpmyadmin/ http://127.0.0.1/mysql/
http://127.0.0.1:3000 http://localhost:3000/entries/
http://127.0.0.1/cgi-bin/c.cgi
C:\InstantRails\cgi-bin\c.cgi
キーワード「ruby」を含む新着エントリー Ruby Inside: The Ruby Blog
Ruby関連MLの自動翻訳サイトが公開 - JRubyのNutter氏に触発 | マイナビニュース
Rails Forum - the ultimate Ruby on Rails community
gem install hpricot
gem install mechanize
http://rubyforge.org/projects/masuda/
作った。
gem install masuda
require 'rubygems' require 'masuda' diary = Masuda::Diary.new diary.entries.each {|entry| puts entry.content } entry = diary.entry('20070712231804') puts <<EOS #{entry.title} #{entry.content} EOS entry.trackbacks.each {|trackback| puts trackback.snippet } diary.login('my_id', 'my_pass') diary.my_entries.each {|entry| puts entry.content } diary.post('Ruby is ...', <<EOS) A dynamic, open source programming language with a ... EOS session[:diary] = diary.raw ... diary = Masuda::Diary.restore(session[:diary])