ファイルやディレクトリをSQLライクに検索するコードを書く
ファイルやディレクトリをもっと簡単に検索したいと考える。
やることは簡単だ。
- glob.iglob(glob.glob)でファイルやディレクトリを取得する
- ファイルやディレクトリに関するデータを取得する
- データをSQLiteに投入する
- SQLライクに検索する
import sys
import os
from glob import iglob
import sqlite3
from datetime import datetime
if len(sys.argv) < 2:
print("Usage: python {} 'PATH' ['QUERY']".format(sys.argv[0]))
sys.exit(0)
path = sys.argv[1]
query = None if len(sys.argv) < 3 else sys.argv[2]
print('[INFO] PATH: {}'.format(path))
print('[INFO] QUERY: {}'.format(query))
fields = ['path','is_file','is_dir','name','extension','directory','abspath','atime','ctime','mtime']
def get_info(path):
return {
'path': path,
'is_file': os.path.isfile(path),
'is_dir': os.path.isdir(path),
'name': os.path.split(path)[1],
'extension': os.path.splitext(path)[1][1:],
'directory': os.path.split(path)[0],
'abspath': os.path.abspath(path),
'atime': datetime.fromtimestamp(os.path.getatime(path)),
'ctime': datetime.fromtimestamp(os.path.getctime(path)),
'mtime': datetime.fromtimestamp(os.path.getmtime(path)),
}
co = sqlite3.connect(':memory:')
c = co.cursor()
c.execute('CREATE TABLE data ('+','.join(['{} NUMERIC'.format(x) for x in fields])+')')
q = 'INSERT INTO data VALUES ('+','.join('?'*len(fields))+')'
for path in iglob(path, recursive=True):
info = get_info(path)
c.execute(q,tuple(info.values()))
co.commit()
data = {'hits':0,'docs':[]}
q = 'SELECT {} FROM data'
if query is not None: q += ' WHERE {}'.format(query)
try: data['hits'] = co.execute(q.format('COUNT(*)',query)).fetchone()[0]
except: sys.exit('[ERROR] The query is invalid.')
docs = data['docs']
co.row_factory = sqlite3.Row
for r in co.execute(q.format('*')): docs.append(dict(r))
del co
print(data)
2020/07/14 21:15