2009年9月27日 星期日

Upgrade Comix Bookmarks from 3.x to 4.x

!! Updated 2009/10/07 for comix 4.0.4 have changed the bookmark path

Comix 由 3.x 升級到 4.0時,會自動偵測之前的書籤,但只能選擇刪除,所以就自己寫程式將舊的書籤更新到新格式,順便學一下 Python 。
怠惰的天性使然,這個小程式花了好幾個月才完成(別打我,當兵的時候每次放假只想玩,沒什麼動力寫程式啊...),所以裡面的縮排和註解很亂,請多包涵,有空我會再花時間去看看 Style Guide for Python Code

使用方法:
1. Save as upbmk.py
2. chmod +x upbmk.py
3. ./upbmk.py OLD_BOOKMARK_FILE


#! /usr/bin/env python
# -*- coding: utf-8 -*-
# upbmk.py - Upgrade Comix bookmarks form 3.x to 4.x
# Usage : upbmk.py [ OLD_BOOKMARK_FILE ]

import os, sys, shutil, re
import cPickle
import subprocess

import zipfile, tarfile

if len(sys.argv)==2 :
ob_path=sys.argv[1]
else:
ob_path="./bookmarks_data"

# open current / old book mark file , make backups
# updated 2009/10/07 , for comix 4.0.4 changed bookmark path
# tStr = os.path.expanduser("~/.comix/bookmarks.pickle")
data_path = os.getenv("XDG_DATA_HOME", os.path.expanduser("~/.local/share") )
tStr = os.path.join(data_path,"comix","bookmarks.pickle")
shutil.copyfile( ob_path, "./backup_old_bookmarks_data")
shutil.copyfile( tStr, "./backup_current_bookmarks.pickle")
cbf = open(tStr,'r')
obf = open(ob_path,'r')

#load current and old bookmarks
cbk = []
cbk.append(cPickle.load(cbf))
cbk.append(cPickle.load(cbf))
odata = cPickle.load(obf)
odata2 = cPickle.load(obf)
obk = []
cbf.close()
obf.close()

for num in range(len(odata)):
temp = odata[num],odata2[num]
obk.append( temp )

del cbf,obf,odata,odata2

# distinguish file types
ZIP, RAR, TAR, GZIP, BZIP2 = range(5)
def what_type( filepath ):
try:
if not os.access( filepath , os.R_OK ):
print " You don't have the permission to read ",filepath,\
" ,you better check it out !! "
sys.exit()
if zipfile.is_zipfile( filepath ):
return ZIP
# use magic numbers to distinguish type
opf = open( filepath , 'r' )
magic = opf.read(8)
opf.close
if magic.startswith('\x52\x61\x72\x21\x1a\x07\x00'):
return RAR
if magic.startswith('\x1f\x8b\x08'):
return GZIP
if magic.startswith('\x42\x5a\x68'):
return BZIP2
# this can also read tar.gz , tar.bz2 ,so put it to the last one
if tarfile.is_tarfile( filepath ):
return TAR
# No of above , check it later
else:
return None
except Exception:
print " Error when reading ",filepath
return None

# test if command "rar" ,"unrar" exist or not
rcmd = None
for testcmd in ["rar","unrar"]:
try:
subprocess.Popen( [testcmd], stdout=subprocess.PIPE)
rcmd = testcmd
except Exception:
pass

# count how many image files in the archive
def get_pages( filepath , archive_type ):
all_files=[]
if archive_type == ZIP :
zfile = zipfile.ZipFile( filepath , 'r' )
all_files = zfile.namelist()
elif archive_type in ( TAR , GZIP , BZIP2 ) :
tfile = tarfile.open( filepath , 'r')
all_files = tfile.getnames()
elif archive_type == RAR :
if rcmd != None:
rout=subprocess.Popen([ rcmd,"vb",filepath],stdout=subprocess.PIPE)
# may contain one newline character
all_files = rout.stdout.readlines()
#print all_files
else:
print ' Unable to extract '+ filepath +' with "rar" or "unrar" '
# not an archive , just a image , scan the directory
elif re.search(r"\.(jpg|jpeg|png|gif|tif|tiff)\s?$", filepath, re.I):
all_files = os.listdir( os.path.dirname(filepath) )
# Error on reading files
else:
print ' Unable to handle" '+ filepath +'" , sorry'
return 0
imgs = 0
#count image files
for name in all_files:
if re.search(r"\.(jpg|jpeg|png|gif|tif|tiff)\s?$",name,re.I):
imgs = imgs + 1
# return number of total image files
return imgs

# convert tuple to list for manipulation
# insert filename,total pages,aechive type
obklist = []
for num in range(len(obk)):
obklist.append( list(obk[num]) )
obklist[num].insert( 0 , os.path.basename( obklist[num][0] ) )
file_type = what_type( obklist[num][1] )
obklist[num].append( get_pages( obklist[num][1], file_type) )
obklist[num].append( file_type )

for bmk in obklist:
cbk[1].append( tuple( bmk))

cbf = open(tStr,'wb')
cPickle.dump( cbk[0], cbf, cPickle.HIGHEST_PROTOCOL)
cPickle.dump( cbk[1], cbf, cPickle.HIGHEST_PROTOCOL)
cbf.close()

print " Upgrade Complete !! After Checking the new bookmarks,\n\
remember to delete backup files "

####### print out data inside bookmarks #########

#print len (cbk[1][0]) // 5
#for num in range(len(cbk[1][1])):
# print cbk[1][1][num-1]
#print cbk[1]
#print len(obk)
#print obk

######### bookmark file format ###########

# cbk = [ 'version',('cbookmarks') ]
# cbookmarks = [ (cbmk1),(cbmk2),....]
# cbmk = [ filename , path , bmk_page , total_pages , archive type]
# obk = [ oldbmk1 , oldbmk2 ...]
# oldbmk = [ path , bmk_page ]

沒有留言: