manywaypark's Blog
개발, 검색, 함수

delicious.com firefox extension data 파일에서 링크 정보 추출하기에 관해 설명한다.

opt in 어쩌구 하는 메시지는 가볍게 무시했었는데, 어느날 부터 서비스가 안되는 것이었다. Orz.
메시지 뿌려대기 시작할 때 무지무지 바빴는데, 바쁜게 끝났을 때는 메시지 무시하는 것이 버릇이 되어있었다.

서비스가 안되는 시점에 여러 검색을 해봤지만 뾰족한 방법이 없었다.
이상한 베타 블로그(http://deliciousengineering.blogspot.com/2011/09/welcome-to-delicious-beta-status-blog.html)에서 곧 조치를 취할거니 기다려 달라는 이야기만 있었다.

그래서 기다리는 중에 또 정신 없이 바빠졌다. 
시간이 좀 지나서 검색해보니 방법들이 있었다.
그런데 아래 링크대로 해봤지만 안됐다.
한시적인 서비스인 것도 있었고, dns 속여서 이전 서비스 접속하는 것도 안됐다.
http://www.avos.com/how-to-get-old-bookmarks-from-yahoo/
http://gabrielleabelle.livejournal.com/337468.html
https://www.delicious.com/settings/ws/import/bookmarks

욕이 나오기 시작했다.
한국 욕을 하면 못알아먹으니 영어로해야할것만 같은 생각도 두어번 들었다.

약간의 오기로 조금 뒤지기 시작했다.
의외로 간단히 firefox의 데이터 파일을 찾을 수 있었다.
C:\Documents and Settings\[UserId]\Application Data\Mozilla\Firefox\Profiles\rwiin5gt.default\ybookmarks.sqlite

혹시 모르니 데이터 파일 백업후 플러그인만 업글해보기로했다.
nsYDelLocalStore.js가 신나게 돌며 전부 삭제해버렸다. 미치기 직전이다.

ybookmarks.sqlite를 delicious.com의 import/export 에 쓰는 html(대충 보니 netscape 형식인듯)로 변환해서 해결하기로 방향을 정하고 다음과 같은 erlang 프로그램으로 모든 link들을 html 파일로 변경한 다음에 import 하니 해결되었다.

출력파일을 보면 제대로 동작해야할 것같은데 현재로서는 다음과 같은 문제가 있다:
  1. 한글이 모조리 없어지는 문제. 
  2. utf-8로 인코딩된 url이 delicious.com에서 redirect될 때 제대로 되지 않는 문제
    (%EC가 URL 내에 있다면, 실제 제목에 걸린 링크에서 redirect시키면서 %25EC로 된다).
일단 상기 문제는 delicious.com에 problem으로 등록했다.

%%%-------------------------------------------------------------------
%%% File    : to_html.erl
%%% Author  : M.W. Park <manywaypark@gmail.com>
%%% Description : converts delicious bookmark data file into html file for import.
%%%   1. install sqlite-erlang3(https://github.com/alexeyr/erlang-sqlite3).
%%%   2. copy ybookmarks.sqlite as delicious.db in current dir.
%%%   3. elrc to_html.erl
%%%   4. erl -noshell -pa [path/to/sqlite-erlang/ebin/] -run to_html doIt -run init stop
%%%   5. import output file(delicious.html) at http://export.delicious.com/settings/bookmarks/import
%%%
%%% Known Problems (for now) :
%%%   1. Hangul(Korean letters) is ignored by delicious (i registered ths issue).
%%%   2. UTF-8 encoded urls are not working (an odd 25 is added(%EC->%25EC) when delicious redirects it, so can't connect to the right url).
%%%
%%% Created : 2011-12-09 Friday by M.W. Park
%%%-------------------------------------------------------------------

-module(to_html).
-export([doIt/0]).

doIt() ->
    {ok,Output}=file:open("delicious.html",[write]),
    io:format(Output, "~s~n", [prefix()]),
    sqlite3:open(delicious), % open 'delicious.db'
    [{columns, _Columns}, {rows, Bookmarks}] = sqlite3:sql_exec(delicious, "select rowid,name,url,added_date,shared,description from bookmarks;"), % for all bookmarks
    lists:foreach(fun(Bookmark) ->
 %%io:format("row=~p~n", [Bookmark]),
 io:format(Output, "~s~n", [xmerl_ucs:to_utf8(bookmark(Bookmark))])
 end,
 Bookmarks),
    sqlite3:close(delicious),
    io:format(Output, "~s~n", [postfix()]),
    file:close(Output).

bookmark(Bookmark) ->
    {RowId, Name, Url, Date, Shared, Desc} = Bookmark,
    io_lib:format("<DT><A HREF=\"~s\" ADD_DATE=\"~ts\" PRIVATE=\"~p\" TAGS=\"~ts\">~ts</A>
<DD>~ts", [Url, re:replace(integer_to_list(Date), "000000$", "", [{return,list}]), if <<"true">> =:= Shared -> 0; true -> 1 end, get_tags(RowId), xmerl_ucs:from_utf8(Name), xmerl_ucs:from_utf8(Desc)]).

get_tags(RowId) ->
    Q = io_lib:format("select * from tags where rowid in (select tag_id from bookmarks_tags where bookmark_id=~p);", [RowId]),
    [{columns, _Columns}, {rows, Tags}] = sqlite3:sql_exec(delicious, Q),
    string:join(lists:map(fun({Tag}) -> xmerl_ucs:from_utf8(Tag) end, Tags), ",").

prefix() ->
    io_lib:format("<!DOCTYPE NETSCAPE-Bookmark-file-1>~n"
     "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">~n"
     "<!-- This is an automatically generated file.~n"
     "It will be read and overwritten.~n"
     "Do Not Edit! -->~n"
     "<TITLE>Bookmarks</TITLE>~n"
     "<H1>Bookmarks</H1>~n"
     "<DL><p>", []).

postfix() ->
    io_lib:format("</DL><p>", []).

 happy hackin'
예전에 원작자인 ttyerl에게 패치를 보낸적이 있는데 적용되지 않았다. 그래서 그냥 포크했다.
또한 새로운 버그도 발견!!
davisp이 ttyerl의 원본을 좀 매끄럽게 돌게 고쳤는데 버그는 그대로였다.
그래서 davisp의 fork를 내가 fork해서 수정했다.

버그들:
  1. table_info 버그
  2. query timeout 버그

작업 내역:
  1. 상기 버그 퇴치
  2. eunit test case 추가


URL: http://github.com/mwpark/sqlite-erlang/tree/master

happy hackin'
평소에 간편히 잘 사용하던 SQuirreL SQL Client에서 sqlite3 DB를 사용해보려 했는데 driver 목록에 sqlite3 용은 없었다. 대충 적당한 것을 찾아서 넣어 볼까 했는데 공식 driver가 아닌 것도 있었고, JNI등을 사용해서 복잡하게 컴파일을 해야되는 것들도 있었다. 나는 간단히 레코드 하나만 변경하면 되는데 일이 너무 복잡해지고 있는 느낌이었다. 그때 내 눈에 들어온 것은 driver 목록의 JDBC ODBC bridge!!

시스템 설치/설정
당연한 이야기지만 ODBC package가 안깔려있다면 깔아야한다(sudo apt-get install unixodbc).
SQLite3 ODBC Driver는 그냥 컴파일 하고 설치하면 되는 프로그램이었다 (./configure && makemake install).
컴파일/설치에 관한 자세한 것은 여기.
일단 컴파일/설치 후에는 dll(libsqlite3odbc.so)만 필요로한다.

이제 설정 파일 두개만 손보면 된다.

/etc/odbcinst.ini
[SQLite]
Description=SQLite ODBC Driver
Driver=/usr/local/lib/libsqlite3odbc.so
Setup=/usr/local/lib/libsqlite3odbc.so
Threading=2

~/.odbc.ini
[db1]
Description=test database 1
Driver=SQLite
Database=/tmp/db1.db
[db2]
Description=test database 2
Driver=SQLite
Database=/tmp/db2.db

SQuirreL SQL Client 설정
이제 SQuirreL SQL Client 설정(Aliases에 추가)시에,
Name: blahblah
Driver: JDBC ODBC Bridge
URL: jdbc:odbc:db1
으로 설정하고 연결하면 /tmp/db1.db sqlite3 파일을 사용할 수 있다.

happy hackin'
1 
분류 전체보기 (306)
잡담 (20)
함수형 언어 (65)
emacs (16)
java (18)
tips & tricks (154)
사랑 (1)
가사 (0)
독서 (4)
mobile (6)
비함수형 언어 (2)

공지사항

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

05-07 09:22