# -*- coding: utf-8 -*- import os import platform import json from operator import itemgetter from distribusi.ignore import Ignore class Fragment: def __init__(self, index, update, directory, artist, file): self.index = index self.update = update self.directory = directory self.artist = artist self.file = file def __repr__(self): return repr((self.index, self.update, self.directory, self.artist, self.file)) class Fragments: def __init__(self): self.json_data = {} self.index = {} self.indextable = [] self.timetable = [] self.ignore = Ignore() self.index_file = 'index.json' def init_json(self, directory): self.index_path = index_path = os.path.join(directory, self.index_file) if os.path.isfile(self.index_path): with open(self.index_path) as json_file: self.json_data = json.load(json_file) self.temp_data = {"fragments":[]} self.count = len(self.json_data) def creation_date(self, path_to_file): """ Try to get the date that a file was created, falling back to when it was last modified if that isn't possible. See http://stackoverflow.com/a/39501288/1709587 for explanation. """ if platform.system() == 'Windows': return os.path.getctime(path_to_file) else: stat = os.stat(path_to_file) try: return stat.st_mtime except AttributeError: return stat.st_birthtime def occupancy(self, directory, file): f = file + ".meta" meta_path = os.path.join(directory, f) with open(meta_path) as json_file: meta = json.load(json_file) try: occupation = meta["occupation"] except KeyError: return if occupation > -1: origin_path = os.path.join(directory, file) date = self.creation_date(origin_path) arr = directory\ .split("/") if arr.__len__() == 2: artist = arr[1] else: artist = arr[2] self.index[occupation] = Fragment(occupation, date, directory, artist, file) def is_meta(self, file): fa = file.split(".") i = len(fa)-1 if i>0 and fa[i] == "meta": return True else: return False def has_meta(self, directory, file): f = file+".meta" meta_path = os.path.join(directory, f) if os.path.isfile(meta_path): return True else: return False def preindex(self, directory): self.init_json(directory) for root, dirs, files in os.walk(directory): self.ignore.add(root) arr = root.split("/") if self.ignore.test(arr[2]): pass # ignore 폴더 처리 else: # 2뎁스까지만 인덱스 함. if arr.__len__() < 4: # files index for f in files: if self.is_meta(f): pass elif self.ignore.test(f): pass elif self.has_meta(root, f): self.occupancy(root, f) else: self.add_timetable(root, f) if arr.__len__() > 2 and arr[2]: # dirs index for d in dirs: if self.has_meta(root, d): self.occupancy(root, d) elif self.ignore.test(d): pass else: self.add_timetable(root, d) def postindex(self): self.timetable = sorted(self.timetable, key=lambda fragment: fragment.update) print("----------- INDEXING ------------") # indexing for f in self.timetable: f.index = self.get_lastindex() self.index[f.index] = f self.update_indextable() self.save() def update_indextable(self): self.indextable = [] for f in self.index: self.indextable.append(self.index[f]) self.indextable = sorted(self.indextable, key=lambda fragment: fragment.index) def get_lastindex(self): last = 0 self.update_indextable() for f in self.indextable: if f.index == last: last = last + 1 return last def add_timetable(self, directory, file): path = os.path.join(directory, file) date = self.creation_date(path) arr = directory.split("/") if arr.__len__() > 2: artist = arr[2] self.timetable.append(Fragment(-1, date, directory, artist, file)) ''' # [deprecated] preindex 하기 전 소소 def add(self, artist, fragment): temp = { "index" : 0, "update" : 0, "file" : { "artist": artist, "fragment": fragment } } added = False for f in self.json_data['fragments']: # 기존 조각과 비교 if f['file'] == temp['file']: added = True if added: print("Already added - artist:", artist, ", fragment: ", fragment) else: self.count = self.count + 1 print("Add fragment - artist:", artist, ", fragment: ", fragment) temp["index"] = self.count temp["update"] = int(time.time()) self.temp_data['fragments'].append(temp) ''' def save(self): #print(json.dumps(self.indextable, cls=CustomEncoder)) with open(self.index_path, 'w') as outfile: json.dump(self.indextable, outfile, indent=4, cls=CustomEncoder) self.count = len(self.indextable) def get_fragments(self): return self.indextable def get_count(self): return self.count def get_index(self, artist, name): for f in self.indextable: if f.artist == artist and f.file == name: return ("{}".format(f.index)).zfill(4) return -1; class CustomEncoder(json.JSONEncoder): def default(self, o): return {'__{}__'.format(o.__class__.__name__): o.__dict__} if __name__ == "__main__": freg = Fragments()