ninix-install コマンドでインストール可能なファイルは、プラグイン
本体 (実行可能なプログラムファイル) と plugin.txt ファイルを含む
-アーカイブファイル (zip 形式または lha 形式) です。
+アーカイブファイル (zip 形式または lha 形式(*注3)) です。
plugin.txt はプラグインの名称や起動方法を記述したテキストファイ
-ルです。文字コードは EUC-JP です。(*注3) 例:
+ルです。文字コードは EUC-JP です。(*注4) 例:
# sstpnews plugin 1.0
name: SSTP News
の本体が動いている可能性がありますので、NINIX_SSTP_PORT で指定さ
れた以外のポート番号は使わないようにして下さい。
-(*注3) ninix-ayaでの仕様拡張:
+(*注3) ninix-aya 4.0.7以降はzip形式のみです.
+
+(*注4) ninix-ayaでの仕様拡張:
plugin.txt の中で "charset" を指定することでそれ以降の行では
EUC-JP 以外の文字コードの使用が可能になります。指定をしなかった
場合には EUC-JP であると仮定して処理されます。
-Python 栞モジュール(*注4)
+Python 栞モジュール(*注5)
-------------------
-(*注4) ninix-aya 2.1.5以降削除されました.
+(*注5) ninix-aya 2.1.5以降削除されました.
栞モジュールを shiori.py というファイル名でゴーストのアーカイブ
ファイルに入れることにより、Python で栞モジュールを自作すること
#
# env.var: NINIX_HOME, NINIX_USER, NINIX_ARCHIVE, TMPDIR
-# command: cp, mv, rm, mkdir, lha, zip, find, chmod
+# command: cp, mv, rm, mkdir, zip, find, chmod
import getopt
if filename.lower().endswith('.nar') or \
filename.lower().endswith('.zip'):
archiver = 'unzip -o %(f)s -d %(d)s'
- elif filename.lower().endswith('.lzh'):
- archiver = 'lha xfw=%(d)s %(f)s'
else:
fatal('unknown archive format')
# extract files from the archive
if filename.lower().endswith('.nar') or \
filename.lower().endswith('.zip'):
archiver = 'unzip -t'
- elif filename.lower().endswith('.lzh'):
- archiver = 'lha t'
else:
fatal('unknown archive format')
if os.system('%s %s >/dev/null 2>&1' % (archiver, escape(filename))):
return entry.get(key) # XXX
# updates etc
- def network_update(self):
+ def network_update(self, updatehook):
last_update = self.last_update
self.last_update = time.strftime('%Y-%m-%d %H:%M:%S')
if self.cgi:
priority = self.cgi.keys()
priority.sort()
- url = self.cgi[priority[-1]]
+ url = self.cgi[priority[-1]][-1]
else:
url = MASTERLIST_URL
try:
{'time': '"%s"' % last_update, 'charset': 'UTF-8'}))
except:
return ## FIXME
- self.import_from_fileobj(f)
+ for _ in self.import_from_fileobj(f):
+ updatehook()
self.save_MasterList()
f.close()
def load_MasterList(self):
try:
f = open(os.path.join(self.datadir, 'MasterList.xml'), 'r')
- self.import_from_fileobj(f)
+ for _ in self.import_from_fileobj(f):
+ pass
f.close()
except IOError:
return
new_entry = {}
set_id = None
node = []
+ re_list = re.compile('<GhostList>')
+ re_setid = re.compile('<FileSet ID="?([0-9]+)"?>')
+ re_set = re.compile('</FileSet>')
+ re_priority = re.compile('<RequestCgiUrl Priority="?([0-9]+)"?>(.+)</RequestCgiUrl>')
+ re_misc = re.compile('<(.+)>(.+)</(.+)>')
for line in fileobj:
+ yield
assert nest >= 0
line = unicode(line, encoding, 'ignore').encode('utf-8')
if not line:
continue
- m = re.compile('<GhostList>').search(line)
+ m = re_list.search(line)
if m:
nest += 1
continue
- m = re.compile('<FileSet ID="?([0-9]+)"?>').search(line)
+ m = re_setid.search(line)
if m:
nest += 1
set_id = int(m.group(1))
continue
- m = re.compile('</FileSet>').search(line)
+ m = re_set.search(line)
if m:
nest -= 1
new_entry[set_id] = self.create_entry(node)
node = []
continue
- m = re.compile('<RequestCgiUrl Priority="?([0-9]+)"?>(.+)</RequestCgiUrl>').search(line)
+ m = re_priority.search(line)
if m:
g = m.groups()
priority = int(g[0])
else:
self.cgi[priority] = [url]
continue
- m = re.compile('<(.+)>(.+)</(.+)>').search(line)
+ m = re_misc.search(line)
if m:
g = m.groups()
if set_id is not None:
d = os.path.join(self.datadir, p)
return d if os.path.exists(d) else None
- def retrieve_image(self, set_id, side):
+ def retrieve_image(self, set_id, side, updatehook):
p = '%s_%d.png' % (self.TYPE[side], set_id)
d = os.path.join(self.datadir, p)
if not os.path.exists(d):
url = self.url['SakuraPreviewBaseUrl'] if side == 0 else \
self.url['KeroPreviewBaseUrl']
try:
- urllib.urlretrieve(''.join((url, p)), d)
+ urllib.urlretrieve(''.join((url, p)), d, updatehook)
except:
return ## FIXME
self.statusbar.show()
def network_update(self):
- self.callback['network_update']()
+ self.window.set_sensitive(False)
+ def updatehook(*args):
+ while gtk.events_pending():
+ gtk.main_iteration()
+ self.callback['network_update'](updatehook)
self.update()
+ self.window.set_sensitive(True)
def open_search_dialog(self):
self.search_dialog.show(default=self.search_word)
def close(self):
self.window.hide()
self.opened = 0
+ return True
class NGM:
def open_preference_dialog(self):
pass
- def network_update(self):
- self.catalog.network_update()
+ def network_update(self, updatehook):
+ self.catalog.network_update(updatehook)
for set_id in self.catalog.data:
for side in [0, 1]:
- self.catalog.retrieve_image(set_id, side)
+ self.catalog.retrieve_image(set_id, side, updatehook)
def open_mask_dialog(self):
pass