삽질2009.04.22 07:11

CakePHP의 paginator는 굉장히 훌륭합니다. ㅠ_ㅠ 번거로운 페이징 작업을 아주 간단하게 해주죠.

필요해서 리스트에서 번호를 보여줄때 순서대로 번호를 매기는 것을 방법을 생각했습니다.
$paging = $paginator->params();
$vid = intval($paging['count']) - (intval($paging['page']) - 1) * intval($paging['options']['limit']);

foreach ($datas as $data):

....

    $vid--; 
endforeach;

View에서 paginator->params([Model]) 을 호출하면 paginator의 옵션과 설정된 값들을 배열로 리턴합니다.

그중에서 전체글수, 현재 페이지, 각 페이지당 글 수를 가져와서 간단한 연산을 통해 현재 페이지의 처음 번호를 구해옵니다.

여기서부터 하나씩 싹싹 빼가면 순서대로 번호가 매겨집니다.
저작자 표시 비영리 변경 금지
신고
Posted by 꿍스
삽질2009.04.19 12:24


ERROR 1140: Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns isillegal if there is no GROUP BY clause


SUM, COUNT, AVG, MIN, MAX 등의 함수와 일반 컬럼을 동시에 사용하기위해서는 GROUP BY 절이 필요합니다. 다음과 같은 SQL도 동일한 에러를 발생시킵니다.


SELECT owner, COUNT(*) FROM pet;


하지만 GROUP BY를 사용하면 각 그룹별로 나누어서 보여주기 때문에, 전체행에 대한 여러 값을 구할 수가 없습니다. 이럴 때는 GROUP BY NULL 을 사용해서 그룹을 만들지 않고 모든 행을 연산할 수 있습니다.


SELECT
COUNT( DISTINCT `Data`.data_id ) AS `used`,
(SELECT COUNT(*) FROM works WHERE place = `Data`.charge_place AND fstate = '신청접수' ) AS `applied`
FROM `users` AS `User` LEFT JOIN
(SELECT `Data`.id as data_id, charge_uid, charge_place, partner_uid, partner_place, fstate, sstate FROM works AS `Data` LEFT JOIN `work_loans` AS `DataLoan` ON `Data`.id = `DataLoan`.data_id WHERE 1=1 ) AS `Data` ON `User`.uid = `Data`.charge_uid
WHERE `User`.role IN ('bm', 'b')
GROUP BY NULL

저작자 표시 비영리 변경 금지
신고
Posted by 꿍스
삽질2009.04.10 17:31
굿모닝 팝스를 매일 들으며 rss를 통해서 팟캐스트로 스마트폰으로 가끔식 듣고 있었는데 어느세 KBS에서 tune이라는 서비스를 하면서 별도의 ActiveX 를 이용해서만 다운이 되더군요. 그래서 오늘 잠깐 독서실을 째고 루비로 만들어 봤습니다.

일단 Wireshark를 이용해서 tune으로 굿모닝 팝스 mp3 url을 패킷캡처해서 알아냈습니다. 아주 간단하더군요. 그리고 우리의 무료 Ruby 호스팅 사이트인 Heroku의 개발용 사이트인 Herokugarden 에서 간단하게 mp3를 다운받을 수 있는 RSS를 만들었습니다.
require 'net/http'
require 'uri'
require 'rexml/document'
 
class RssController < ApplicationController
  
  def gmp
    @article = []
    xml_data = Net::HTTP.get(URI.parse('http://tune.kbs.co.kr/program/rss.php?pgNo=1'))
    doc = REXML::Document.new(xml_data)
    doc.elements.each('rss/channel/lastBuildDate') do | e |
      @lastBuildDate = e.text
    end
    
    doc.elements.each('rss/channel/item/title') do | ele |
      item = Hash.new
      item['title'] = ele.text
      item['url'] = 'http://211.233.94.167/danpod/mp3/2fm/gmp_' + ele.text[-11 .. -2 ].tr('/', '') + '_down.mp3'
      @article << item
    end
    render :layout => false
  end
 
end
View 는 RSS를 생성합니다.
  
    
    http://tune.kbs.co.kr
    KBS RADIO TUNE RSS 서비스
    ko
    
    
      
        
        <a href="">MP3 Download</a>
        Nov, 29 1999 15:00:00 GMT
      
    
  

title 태그를 티스토리에서 거르는군요 -_-;;;  위의 소스코드에서 공백은 RSS의 TITLE태그입니다.

이렇게 해도 되는지 모르겠습니다. http://gmprss.ggungs.com/

저작자 표시 비영리 변경 금지
신고
Posted by 꿍스
삽질2009.03.07 23:32
오늘 CakePHP의 AuthComponent 덕분에 하루종일 삽질을 하게 되었습니다. CakePHP, Ruby on Rails 빠르게 웹 개발이 가능한 MVC 프레임워크는 관례를 중요시 하고 그 관례로 인해 빠르게 개발이 가능합니다. 하지만 관례만 따르기는 뭔가 답답한 감이 들기도 합니다. 그래서 오늘의 삽질이 시작되었습니다. CakePHP역시 Ruby on Rails 처럼 비슷한 관례가 있습니다. 예를 들어 CakePHP도 Rails처럼 Model은 단수 Controller는 복수입니다. CakePHP에서 맘에드는 점은 Table 즉 DB를 쓰지않는 Model을 사용할 수도있습니다. Model에 $useTable 변수를 변경하는 것만으로 Model을 데이터베이스가 아닌 다른 것들로 채울 수 있는 방법이 있습니다. 또 한 Controller를 단수로 만들 수도 있습니다. Controller에서 $uses 변수로 여러가지 모델을 한번에 컨트롤러에서 사용할 수 있는 방법도 있습니다. 제 생각에는 Rails 보다는 좀더 유연한 프레임워크 같습니다. ( 언어를 말하는 것이 아닙니다. ) 물론 Rails도 CakePHP보다 좋은 점이 많습니다.

오늘의 삽질은 사용자 인증을 위해 CakePHP의 AuthComponent를 사용하면서 발생 했습니다. CakePHP의 관례대로 데이터베이스의 테이블은 users, 모델은 user, 컨트롤러는 users로 이름을 짓고 로그인과 로그아웃을 간단하게 구현했습니다. users 컨트롤러에는 scaffold로 구현한 사용자 관리 로직도 있으므로 로그인을 따로 분리하기 위해 Login(단수입니다.) 컨트롤러를 만들어서 기존의 코드를 이용했습니다.
여기서 부터 로그인이 아무리 해도 안되는 것입니다. AuthComponent의 useModel 옵션으로 모델도 user로 잡았는 데도 값은 있는데 도무지 인증처리가 되지않아서 무려 5시간이나 삽질을 했습니다. 도저히 안되어서 AuthComponent의 소스를 뒤지기 시작했습니다.

소스를 10분정도 뒤지니 순간 멍해졌습니다. 

create('User', array('action' => 'login')); ?>
input('uid', array( 'label' => '로그인 ID')); ?>
input('password', array( 'label' => '로그인 암호')); ?>
end('Login'); ?>
CakePHP에서 Form 헬퍼로 이렇게 폼을 만들면 폼의 input 엘리먼트들이 컨트롤러에 넘어올때는 data[User][uid] 처럼 넘겨집니다. 이것이 관례 입니다. 즉 위의 코드는 Login 컨트롤러에서 부르더라도 Model에 해당하는 data[User][uid] 을 찾는 것입니다. 저는 data[Login][uid]으로 넘어갈 줄 알았는데 말입니다.  저는 이 관례를 깨트리고 좀더 유동적으로 만들고 싶었는데 말이지요.

이것이 관례를 따르는 프레임워크의 함정입니다. 처음 CakePHP로 scaffold 된 페이지들을 보았을때 아주 간단하게 CRUD 페이지와 로직이 모두 만들어 지는것이 정말 신기했고 정말 빠른 개발이 가능할 것이라고 생각했습니다. 하지만 정작 개발을 시작했을때 당황하지 않을 수 없었습니다. scaffold 는 뭔가 미리 약속한 듯한 코드일 뿐 나머지 것들은 다 숨겨져 있기 때문입니다.
저작자 표시 비영리 변경 금지
신고
Posted by 꿍스
삽질2009.03.01 16:04

Heroku는 무료 Rails 호스팅 사이트 입니다. 다만 일반 호스팅과는 다르게 Git를 이용해서 Rails 어플리케이션을 갱신합니다. Heroku에 가입을 하고 로그인을 하면 http://heroku.com/pages/quickstart 화면이 나옵니다. 이제 자신이 만든 어플리케이션을 heroku에 등록해 봅시다. 

처음으로 Git 를 설치해야 합니다. 여기서는 msysgit를 설치 합니다. 홈페이지(http://code.google.com/p/msysgit/)에 가면 윈도우즈용 인스톨러가 있습니다. 설치합니다.

설치하는 중간에 Bash를 이용할 것인지 윈도우즈의 CMD를 이용할 것인지 묻는 창이 나옵니다. 저는 여기서 기본 윈도우즈의 CMD를 사용할 것이라서 두번째를 선택 했습니다. 

 SSH로 어떤것을 선택할지 묻는 옵션입니다. OpenSSH를 선택합니다.

Git 설치 후에 quickstart네 나온대로 실행하면 오류부터 발생합니다.

C:\myapp> heroku keys:add
No ssh public key found in C:\Users\Administrator/.ssh/id_[rd]sa.pub.  You may want to specify the full path to the keyfile.

일단 SSH 키를 생성해야 합니다. Git 설치시 후에 Git 시작메뉴아래에 잇는 Git Gui를 실행하고 Help 메뉴의 Show SSH Key 를 실행하면 아래 와 같은 화면이 나옵니다. 현재 키가 없다고 화면에 나옵니다. 옆의 Generate Key버튼을 누르면 키를 생성할 수 있습니다. 키 생성을 마친후 다시 명령을 내려 봅시다.

키에 한글 명이 있다면 한글을 영어로 바꾸어 줍니다. 생성된 Key의 끝에 유저명@컴퓨터 명이 붙습니다. 컴퓨터 명이 한글로 되어있으시면 파일 편집해서 영문으로 변경해 주세요.

한글로 되어있으면 Internal server error 라는 오류메세지가 표시됩니다.

C:\myapp>heroku keys:add
Uploading ssh public key C:\Users\Administrator/.ssh/id_rsa.pub
Enter your Heroku credentials.
Email: ggungs@gmail.com
Password:
Uploading ssh public key C:\Users\Administrator/.ssh/id_rsa.pub
    이 다음부터 QuickStart에 나온대로 진행하면 됩니다.
    C:\> cd myapp
    C:\myapp> git init
    C:\myapp> git add .
    C:\myapp> git commit -m "first commit"
    C:\myapp> heroku create --remote
    Created http://growing-water-46.heroku.com/ | git@heroku.com:growing-water-46.git
    Git remote heroku added
    
    C:\myapp>git push heroku master
    The authenticity of host 'heroku.com (75.101.145.87)' can't be established.
    RSA key fingerprint is 8b:48:5e:67:0e:c9:16:47:32:f2:87:0c:1f:c8:60:ad.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'heroku.com,75.101.145.87' (RSA) to the list of known hosts.
    Enter passphrase for key '/c/Users/Administrator/.ssh/id_rsa': -> 키를 만들때 입력한 값을 넣습니다.
    Counting objects: 132, done.
    Compressing objects: 100% (118/118), done.
    Writing objects: 100% (132/132), 284.08 KiB | 45 KiB/s, done.
    Total 132 (delta 17), reused 0 (delta 0)
    -----> Heroku receiving push
    -----> Verifying repository integrity... done
    Compiled slug size is 0.2MBTo git@heroku.com:growing-water-46.git
    * [new branch] master > master-----> Launching......... done
    App deployed to Heroku
    
    C:\myapp>heroku rake db:migrate
    (in /mnt/home/slugs/4850_80a52d1_39b6/mnt)
    == CreateComments: migrating =================================================
    -- create_table(:comments)
     -> 0.0145s
    == CreateComments: migrated (0.0146s) ========================================
    C:\myapp>heroku open
    Opening http://growing-water-46.heroku.com/
    

    호스팅된 2차 도메인이름이 이해하기 어렵울 것입니다. 이럴땐 이름을 바꿀 수 있는 rename 명령어가 있습니다.

    C:\myapp>heroku rename testapp growing-water-46
    http://testapp.heroku.com/comments | git@heroku.com:testapp.git
    Git remote heroku updated
    

    호스팅된 Rails 어플리케이션 입니다. http://testapp.heroku.com/comments

    Heroku의 또다른 서비스인 http://herokugarden.com/ 을 이용하면 더 쉽게 레일즈 어플리케이션을 만들고 웹에서도 편집할 수 있다고 합니다. 

     

    신고
    Posted by 꿍스
    삽질2009.02.27 00:04

    Rails RJS에서 기존의 Prototype과 Scriptaculous를 사용하던 것을 jQuery와 jQuery-ui로 대채할 수 있도록 하는 것이 jRails 입니다.

    현재 jRails의 버전은 0.4 이며 jQuery 1.2.6과 jQuery-ui 1.5버전이 포함되어 있습니다.

    jRails 를 설치 합니다. ( http://ennerchi.com/projects/jrails ) ruby script/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails 컨트롤러에 javascript를 받을 수 있도록 response_to에 js를 추가 합니다.
    respond_to do | format |   format.html { redirect_to :action => "index" }   format.js end
    jRails Javascript를 불러오도록 뷰에 추가합니다.
    <%= javascript_include_tag :defaults %>
    이제 Action이름.js.erb 파일을 생성하고 폼 처리후에 실행할 자바스크립트를 작성합니다.
    $("#comments").append("<%= escape_javascript( render(:partial => "comment",  :locals => { :comment => @comment})) %>;");
    뷰에서 form_for 대신에 remote_form_for 를 사용합니다.
    <% remote_form_for :comment, :id => "comment_form", :html => { :id => "comment_form" }, :url => { :action => "create" } do | f | %>;
    폼 태그에 다음과 같은 jQuery를 사용한 javascript 코드가 삽입됩니다.
    onsubmit="$.ajax({data:$.param($(this).serializeArray()) + '&authenticity_token='+ encodeURIComponent('a8067d5dbc597158d932610793a977f2637abdf0'), dataType:'script',type:'post', url: '/comments/create'}); return false;"
    jRails를 처음 받으면 JQuery버전이 1.2.6 이지만 최신버전인 1.3.2로 jQuery.js 를 변경하더라도 문제가 발생하지 않았습니다. 구글링을 하다보니 jQuery-ui 1.6에서는 오류가 발생한다고 하니 참고하시기 바랍니다.

     

    신고
    Posted by 꿍스
    삽질2009.02.23 13:17
    RoR 설치 및 시연

    1. 루비 설치

    2. 루비설치 후 Gem으로 레일즈 인스톨

    gem install rails --include-dependencies

    3. 루비 mysql 설치

    gem install mysql

    4. 레일즈 어플리케이션 생성

    rails 어플리케이션명

    5. 데이터베이스 설정 config/database.yml

    development, test, productive를 각각 설정

    6. 기존의 db로 모델 생성

    ruby script/generate model table 명

    7. 컨트롤러 생성

    ruby script/generate controller 이름

    혹은 스캐폴딩을 이용할 수도있다.

    ruby script/generate scaffold table 명

    8. 레일즈 웹 서버 시작

    ruby script/server
    신고
    Posted by 꿍스
    삽질2009.01.29 13:29
    구글맵에서 제공하는 주소에서 좌표변환은 구글맵의 GClientGeocoder 클래스를 보통 사용하지만 여러개를 받을때는 직접 Geocoding 를 사용하는 것이 좋다고 구글 맵스의 API에 나와있다.

    방법은 보통의 OpenAPI와 같다. http://maps.google.com/maps/geo? 로 인자를 보내면 결과를 json, xml, kml, csv 중의 한 형태로 출력한다.

    Geocoding 의 설명은 여기를 참고하면 된다.

    http://code.google.com/intl/ko/apis/maps/documentation/geocoding/index.html

    이를 사용하다가 생긴 의문점은 보통 한국 지도를 보기위해 http://maps.google.co.kr 로 요청을 보내지만 이상하게 http://maps.google.co.kr/maps/geo? 이나 Gecoding Request시의 Country Code를 KR로 입력하면 결과값이 http://maps.google.com/maps/geo? 에 비해서 작다. '시흥' 으로 검색하면서 확실히 알 수 있었다.

    이렇게 한번 검색해보자. 여러 시에 북구 라는 구가 있다.

    http://maps.google.com/maps/geo?q=북구&output=xml&key=
    http://maps.google.com/maps/geo?q=북구&gl=KR&output=xml&key=
    http://maps.google.co.kr/maps/geo?q=북구&output=xml&key=

    입력해 보면 밑의 두개는 하나만 나타난다. KR로 명확히 정해지면 적게 나온다.

    또한 결과 주소가 영문으로 나올때는 HTTP 헤더의 ACCEPT LANGUAGE 를 ko-KR를 앞에 붙이면 한글로 주소를 출력해준다.
    신고
    Posted by 꿍스
    삽질2009.01.14 06:51
    에뮬레이터 버전이 1.0 일 경우 Vista에서는 DMA및 가상 네트워크 설정이 전혀 먹히지 않음..
    ( 이것 때문에 정말 삽질 많이 함 ㅜㅜ ) 최신버전인 3.0으로 설치해 줍시다.


    액티브싱크 없이 에뮬레이터에서 바로 인터넷 연결하는 방법 ( 가상 네트워크 드라이버 이용 )


    가상 네트워크 드라이버는 현재 더이상 별도로 제공되지 않고 Virtual PC 2007 설치하면 된다. 비스타의 경우 Virtual PC 2007 SP1 권장
    신고
    Posted by 꿍스
    삽질2009.01.07 01:51