Hatena::ブログ(Diary)

読んでる?開発ブログ

2010-12-07

本の詳細ページに、はてなの検索結果を追加しました。

| 03:12

本の詳細ページからBaiduを削除してしまい、しばらくブログレビューが寂しい状態でしたが、本日はてなからの検索結果を表示するよう更新しました。

久しぶりにマイナーバージョンアップしました「読んでる?」、ぜひお試しください。

2010-10-05

不具合修正のお知らせ

| 01:47

読んでる?の各書籍詳細ページがしばらくエラーで表示できない状態になっていました。

なかなかメンテナンスできずにこれまで放置してしまっていたのですが、確認したところBaiduブログ検索サービスが終了していたためデータが取得できない不具合が起きていました。

応急処置として、Baiduデータは取得せずに詳細ページを表示するよう修正しましたので、現在はまたページが閲覧できるようにはなりました。

ブログレビューの右列部分が常に何も出ない状態になってしまいましたので、これを機会に時間を見つけて近いうちにバージョンアップできればと思います。

2010-03-10

Twitterにつぶやくボタンを追加しました

| 00:34

見ている本の詳細ページをTwitterにつぶやけるボタンを追加しました。

詳細ページはこんな感じです。

f:id:yonderu:20100311002508p:image

リンクをクリックするとこうなります(Twitterログインが必要です)。

f:id:yonderu:20100311002509p:image


Twitterにつぶやくリンクを作るには、「http://twitter.com/home?status=」のURLパラメータにurlencodeした文字列を付けるだけでした。

とても簡単です。この敷居の低さがまたTwitterの良い所ですね。

なお、使用したアイコンはこちらのサイトからお借りしました。ありがとうございます。

http://www.webdesignerdepot.com/2009/07/50-free-and-exclusive-twitter-icons/

2010-03-09

iPhoneのQuickMarkを使ってバーコードからアクセスする

| 00:21

読んでる?で各書籍の詳細ページは、

http://yonderu.net/book/4774141593

のように、ISBN-10がキーになるURLになってます。

これを利用して、iPhoneバーコードリーダー機能を使ったアクセスができます。

今回紹介するのは、バーコードリーダアプリとして「QuickMark」を使った方法です。

読み取り性能に優れたQR/バーコードリーダーアプリ『QuickMark』

なお、iPhone 3GSだと問題無いですが、3Gだと付属のカメラがマクロ撮影非対応のため、素の状態ではバーコードの読み取りは難しいです。

3Gの場合はマクロレンズ付きケースを付ける、カメラにルーペを重ねて撮影するといった対応が必要になります。ちなみに私は下記のマクロレンズ付きケースを使っています。

Griffin Technology Clarifi for iPhone 3G


操作の手順は以下の通りです。

  • QuickMarkを起動したら、下部メニューの「セットする」より1次元バーコードの種類を“EAN 8/13”に設定します。

f:id:yonderu:20100309234653p:image

  • 次に「転送サイトの設定」から、転送サイト機能を“オン”、アドレスを“http://yonderu.net/book/”に設定します。

f:id:yonderu:20100309234654p:image

  • デコード」をクリックして、バーコードの読み取りを行います。本の裏に2つバーコードが付いてますが上の方を読み取ってください。下のバーコードは指などで隠すと読み取りやすいです。

f:id:yonderu:20100309234649p:image

  • 読み取りができたら、読み取ったISBNコード上をクリックしてください。

f:id:yonderu:20100309234650p:image

f:id:yonderu:20100309234652p:image

ちょっと手元の本の情報を調べたい時などに便利かもしれません。ぜひお試しください。

2010-02-10

キャッシュ機能追加しました

| 01:44

http://yonderu.net/

読んでる?は、PHPフレームワークCodeIgniterを使用して作られています。

同じURLでもアクセス元のユーザエージェントにより、PC・携帯向けページを切り替えて出力するようにしていますが、CodeIgniterのデフォルトキャッシュ機能では同一URLで一つのキャッシュを生成してしまうためそのままでは使えません。

まあキャッシュは必須機能では無いし、、と後回しにしていましたが、どうもサイトのレスポンスが良くないことが気になったので、CodeIgniterに手を入れてキャッシュ機能を追加してみました。

http://codeigniter.jp/user_guide_ja/general/hooks.html

http://codeigniter.jp/user_guide_ja/general/core_classes.html

始め、フックポイントcache_overrideを変更してキャッシュファイル名の生成ルールをいじれば何とかなるかな、と試しましたがどうにも想定する動きができなかったので、フックはやめベタにOutputの拡張クラスを作成して対応してみました。

system/application/libraries/MY_Output.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class MY_Output extends CI_Output {

	function CI_Output()
	{
		log_message('debug', "MY_Output Class Initialized");
	}
	
	// --------------------------------------------------------------------
	
	function _get_cache_param()
	{
		$param = "p";
		
		if ( ! @include(APPPATH.'config/user_agents'.EXT))
		{
			return $param;
		}
		if (!$mobiles)
		{
			return $param;
		}
		
		$agent = trim($_SERVER['HTTP_USER_AGENT']);
		
		if (is_array($mobiles) AND count($mobiles) > 0)
		{		
			foreach ($mobiles as $key => $val)
			{
				if (FALSE !== (strpos(strtolower($agent), $key)))
				{
					$param = "m";
					break;
				}
			}
		}
		
		return $param;
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Write a Cache File
	 *
	 * @access	public
	 * @return	void
	 */	
	function _write_cache($output)
	{
		$CI =& get_instance();	
		$path = $CI->config->item('cache_path');
	
		$cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
		
		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
		{
			return;
		}
		
//		$uri =	$CI->config->item('base_url').
//				$CI->config->item('index_page').
//				$CI->uri->uri_string();
		$cache_param = $this->_get_cache_param();
		$uri =	$CI->config->item('base_url').
				$CI->config->item('index_page').
				$CI->uri->uri_string().
				$cache_param;
		
		$cache_path .= md5($uri);

		if ( ! $fp = @fopen($cache_path, 'wb'))
		{
			log_message('error', "Unable to write cache file: ".$cache_path);
			return;
		}
		
		$expire = time() + ($this->cache_expiration * 60);
		
		flock($fp, LOCK_EX);
		fwrite($fp, $expire.'TS--->'.$output);
		flock($fp, LOCK_UN);
		fclose($fp);
		@chmod($cache_path, 0777);

		log_message('debug', "Cache file written: ".$cache_path);
	}

	// --------------------------------------------------------------------
	
	/**
	 * Update/serve a cached file
	 *
	 * @access	public
	 * @return	void
	 */	
	function _display_cache(&$CFG, &$RTR)
	{
		$URI =& load_class('URI');
	
		$cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path');
			
		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
		{
			return FALSE;
		}
		
		// Build the file path.  The file name is an MD5 hash of the full URI
//		$uri =	$CFG->item('base_url').
//				$CFG->item('index_page').
//				$URI->uri_string;
		$cache_param = $this->_get_cache_param();
		$uri =	$CFG->item('base_url').
				$CFG->item('index_page').
				$URI->uri_string.
				$cache_param;
				
		$filepath = $cache_path.md5($uri);
		
		if ( ! @file_exists($filepath))
		{
			return FALSE;
		}
	
		if ( ! $fp = @fopen($filepath, 'rb'))
		{
			return FALSE;
		}
			
		flock($fp, LOCK_SH);
		
		$cache = '';
		if (filesize($filepath) > 0)
		{
			$cache = fread($fp, filesize($filepath));
		}
	
		flock($fp, LOCK_UN);
		fclose($fp);
					
		// Strip out the embedded timestamp		
		if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
		{
			return FALSE;
		}
		
		// Has the file expired? If so we'll delete it.
		if (time() >= trim(str_replace('TS--->', '', $match['1'])))
		{ 		
			@unlink($filepath);
			log_message('debug', "Cache file has expired. File deleted");
			return FALSE;
		}

		// Display the cache
		$this->_display(str_replace($match['0'], '', $cache));
		log_message('debug', "Cache file is current. Sending it to browser.");		
		return TRUE;
	}


}
// END Output Class
?>

キャリア判定ロジックをuser_agentクラスからコピってきたものを使っていたりして、全くいけてませんが、ともかく同一URLでPC・携帯対応のキャッシュ機能が使えるようになりました。快適、快適。

以前よりレスポンスが改善された読んでる?、ぜひお試しください。