| 217 | | " 編集ページを取得 |
| 218 | | let content = system(s:curl_cmd . ' "' . base_url . user . '/edit?date=' . year . month . day . '" -b "' . cookie_file . '"') |
| 219 | | if base_url =~ 'g.hatena' |
| 220 | | let content = iconv(content, 'utf-8', &enc) |
| 221 | | let fenc = 'utf-8' |
| 222 | | else |
| 223 | | let content = iconv(content, 'euc-jp', &enc) |
| 224 | | let fenc = 'euc-jp' |
| 225 | | endif |
| | 227 | let content = HatenaLoadContent(base_url,user,year,month,day,cookie_file) |
| 268 | | |
| | 266 | set nomodified |
| | 267 | endfunction |
| | 268 | |
| | 269 | "指定先から一日分のエントリを取得。 |
| | 270 | "return: dictionary { |
| | 271 | " diary_title, day_title, timestamp, rkm, body, fenc |
| | 272 | "} |
| | 273 | function! HatenaLoadContent(base_url,user,year,month,day,cookie_file) |
| | 274 | " 編集ページを取得 |
| | 275 | let content = system(s:curl_cmd . ' "' . a:base_url . a:user . '/edit?date=' . a:year.a:month.a:day . '" -b "' . a:cookie_file . '"') |
| | 276 | if a:base_url =~ 'g.hatena' |
| | 277 | let content = iconv(content, 'utf-8', &enc) |
| | 278 | let fenc = 'utf-8' |
| | 279 | else |
| | 280 | let content = iconv(content, 'euc-jp', &enc) |
| | 281 | let fenc = 'euc-jp' |
| | 282 | endif |
| | 283 | let result=s:HatenaParseContent(content) |
| | 284 | let result['fenc']=fenc |
| | 285 | let result['year']=a:year |
| | 286 | let result['month']=a:month |
| | 287 | let result['day']=a:day |
| | 288 | return result |
| | 289 | endfunction |
| | 290 | |
| | 291 | function! s:HatenaParseContent(content) |
| | 292 | let diary_title = matchstr(a:content, '<title>\zs.\{-}\ze</title>') |
| | 293 | let day_title = matchstr(a:content, '<input .\{-}name="title" .\{-}value="\zs.\{-}\ze"') |
| | 294 | let timestamp = matchstr(a:content, 'name="timestamp"\s*value="\zs[^"]*\ze"') |
| | 295 | let rkm = matchstr(a:content, 'name="rkm"\s*value="\zs[^"]*\ze"') |
| | 296 | let body = s:HtmlUnescape(matchstr(a:content, '<textarea.\{-}name="body"[^>]*>\zs.\{-}\ze</textarea>')) |
| | 297 | let result={} |
| | 298 | let result['diary_title']=diary_title |
| | 299 | let result['day_title']=day_title |
| | 300 | let result['timestamp']=timestamp |
| | 301 | let result['rkm']=rkm |
| | 302 | let result['body']=body |
| | 303 | return result |
| 305 | | |
| | 334 | let diary={'timestamp':b:timestamp, 'rkm':b:rkm, 'year':b:year, 'month':b:month, 'day':b:day, 'day_title':b:day_title} |
| | 335 | |
| | 336 | let result=HatenaPost(base_url,user,cookie_file,diary,body_file) |
| | 337 | |
| | 338 | echo '更新しました' |
| | 339 | endfunction |
| | 340 | |
| | 341 | function! HatenaPost(base_url,user,cookie_file,diary,body_file) |
| | 342 | if a:body_file == "" |
| | 343 | let body_file=tempname() |
| | 344 | execute 'new '.body_file |
| | 345 | call append(0,a:diary['body']) |
| | 346 | write |
| | 347 | hide |
| | 348 | let &modified=0 |
| | 349 | "bdelete |
| | 350 | else |
| | 351 | let body_file=a:body_file |
| | 352 | endif |
| | 353 | " まずは全消去 |
| 307 | | \ . ' -F timestamp=' . b:timestamp . ' -F rkm=' . b:rkm |
| 308 | | \ . ' -F year=' . b:year . ' -F month=' . b:month . ' -F day=' . b:day |
| 309 | | \ . ' -F date=' . b:year . b:month . b:day |
| | 355 | \ . ' -F year=' . a:diary.year . ' -F month=' . a:diary.month . ' -F day=' . a:diary.day |
| | 356 | \ . ' -F rkm=' . a:diary.rkm |
| | 357 | \ . ' -F body= -F title=' |
| | 358 | call system(s:curl_cmd . ' ' . a:base_url . a:user . '/edit -b "' . a:cookie_file . '"' . post_data) |
| | 359 | |
| | 360 | " ポスト |
| | 361 | let post_data = ' -F mode=enter' |
| | 362 | \ . ' -F timestamp=' . a:diary['timestamp'] . ' -F rkm=' . a:diary['rkm'] |
| | 363 | \ . ' -F year=' . a:diary['year'] . ' -F month=' . a:diary['month'] . ' -F day=' . a:diary['day'] |
| | 364 | \ . ' -F date=' . a:diary['year'].a:diary['month'].a:diary['day'] |
| | 403 | "returns array of dictionaries. |
| | 404 | "[entry1,entry2,...] |
| | 405 | "each item is |
| | 406 | "{ 'eid':entry-id, 'title':title, 'body':body } |
| | 407 | " TODO: タイトルのない冒頭部 |
| | 408 | function! HatenaParseEntries(body) |
| | 409 | new |
| | 410 | if type(a:body)==type('') |
| | 411 | let body=split(a:body,"",1) |
| | 412 | else "expect is list |
| | 413 | let body=a:body |
| | 414 | endif |
| | 415 | call append(0,body) |
| | 416 | call cursor(1,1) |
| | 417 | let l:es=[] |
| | 418 | let l:e=s:FindNextEntry() |
| | 419 | while l:e |
| | 420 | let l:next_e=s:FindNextEntry() |
| | 421 | call add(l:es,[l:e,next_e?next_e-1:line('$')]) |
| | 422 | let l:e=l:next_e |
| | 423 | endwhile |
| | 424 | let l:result=[] |
| | 425 | for [l:st,l:ed] in l:es |
| | 426 | call add(result,HatenaParseEnrty(getline(l:st),getline(l:st+1,l:ed))) |
| | 427 | endfor |
| | 428 | let &modified=0 |
| | 429 | close |
| | 430 | return l:result |
| | 431 | endfunction |
| | 432 | |
| | 433 | function! HatenaParseEnrty(title,body) |
| | 434 | let [eid,title]=matchlist(a:title,'^\*\%(\(\%(\w\|-\)\+\)\*\)\?\(.*\)$')[1:2] |
| | 435 | let body=a:body |
| | 436 | return {'eid':eid, 'title':title, 'body':body} |
| | 437 | endfunction |
| | 438 | |
| | 439 | "エントリのリストを文字列に直す HatenaParseEntriesの逆 |
| | 440 | "諸般の事情(appendの仕様?)により、各行を要素に持つリストを返す。 |
| | 441 | function! HatenaExpandEntries(entries) |
| | 442 | new |
| | 443 | for e in a:entries |
| | 444 | call append(line('$'),'*'.e['eid'].'*'.e['title']) |
| | 445 | call append(line('$'),e['body']) |
| | 446 | endfor |
| | 447 | execute '1delete' |
| | 448 | let result=getline(1,'$') |
| | 449 | let &modified=0 |
| | 450 | bdelete |
| | 451 | return result |
| | 452 | endfunction |
| | 453 | |
| | 454 | "カーソル位置以降のエントリを探す |
| | 455 | function! s:FindNextEntry() |
| | 456 | while 1 |
| | 457 | "skip super pre |
| | 458 | if search('^>|\w*|$','ce',line('.')) |
| | 459 | if !search('^||<$','ce') "broken spre |
| | 460 | return 0 |
| | 461 | endif |
| | 462 | endif |
| | 463 | "find next entry |
| | 464 | let entry=search('^\*\(\%(\w\|-\)\+\)\*\(.*\)$','ce',line('.')) |
| | 465 | if entry || line('.') >= line('$') |
| | 466 | call cursor(line('.')+1,1) |
| | 467 | return entry |
| | 468 | endif |
| | 469 | call cursor(line('.')+1,1) |
| | 470 | endwhile |
| | 471 | endfunction |
| | 472 | |