from flask import render_template, request, jsonify from www import app import json, logging, os, glob from lxml import etree as et import config from collections import OrderedDict def list_all(d, ext): if not os.path.isdir(d): logging.error(d + " is not a valid directory.") return None return [os.path.basename(f) for f in glob.glob(os.path.join(d, "*." + ext))] @app.route('/') def top(): return render_template("index.html") ''' INDEX ''' def read_index(d, fn): fp = os.path.join(d, fn) if not os.path.isfile(fp): return None with open(fp) as f: index_data = json.load(f, object_pairs_hook=OrderedDict) return index_data # def add_selected_kw_index(d, fn, kw): # fp = os.path.join(d, fn) # if not os.path.isfile(fp): # return False # with open(fp) as f: # index_data = json.load(f) # if kw not in index_data['orphan']: # return False # v = index_data['orphan'].pop(kw) # if kw not in index_data['selected']: # index_data['selected'][kw] = [] # index_data['selected'][kw] += v # with open(fp, 'w') as fout: # json.dump(index_data, fout, indent=4, sort_keys=True, ensure_ascii=False) # return True def modify_selected_kw_index(d, fn, kw, action="add"): fp = os.path.join(d, fn) if not os.path.isfile(fp): return False with open(fp) as f: index_data = json.load(f) if action == 'add': in_dic = index_data['selected'] out_dic = index_data['orphan'] elif action == 'delete': out_dic = index_data['selected'] in_dic = index_data['orphan'] else: return False if kw not in out_dic: return False v = out_dic.pop(kw) if kw not in in_dic: in_dic[kw] = [] in_dic[kw] += v with open(fp, 'w') as fout: json.dump(index_data, fout, indent=4, sort_keys=True, ensure_ascii=False) return True @app.route('/index', methods = ['GET']) def index(): if request.method == 'GET': li = list_all(config.index['path'], 'js') li = sorted(li, key=lambda x: int(x.split('.')[0])) return render_template("list_files_all.html", title="INDEX [all]", prefix="/index/", files=li) @app.route('/index/', methods = ['GET', 'POST']) def indexfn(fn): if request.method == 'GET': data = read_index(config.index['path'], fn) if data is not None: return render_template("indx.html", fn=fn, selected=data['selected'], orphan=data['orphan']) else: return "File: " + fn + "does not exist." elif request.method == 'POST': data = request.form a = data.get('action') if a == "add": logging.info("POST ADD " + fn + " -- " + data.get('kw') + " ++ " + data.get('list')) if modify_selected_kw_index(config.index['path'], fn, data.get('kw')): return "ok" elif a == "delete": logging.info("POST DELETE " + fn + " -- " + data.get('kw') + " ++ " + data.get('list')) if modify_selected_kw_index(config.index['path'], fn, data.get('kw'), action="delete"): return "ok" return "-" ''' XML ''' def read_xml(d, fn): fp = os.path.join(d, fn) if not os.path.isfile(fp): return None root = et.parse(fp).getroot() xml_data = [] for m in root.findall('mails/mail'): nbr_str = m.find('nbr').text date_str = m.find('date').text from_str = m.find('from').text subject_str = m.find('subject').text xml_data.append({'nbr': nbr_str, 'date': date_str, 'from': from_str, 'subject': subject_str}) # sort xml_data[:] = sorted(xml_data, key=lambda x: parse_nbr_xml(x['nbr'])) return xml_data def parse_nbr_xml(nbr_str): if '-' in nbr_str: nbr_str = nbr_str.split('-')[0] # split number and return a tuple # ex. 15.4 -> (15, 4) tok = nbr_str.split('.') tup = (int(tok[0]), int(tok[1])) return tup def update_nbr_xml(d, fn, nbr, new_nbr, date): fp = os.path.join(d, fn) if not os.path.isfile(fp): return False tr = et.parse(fp) m = tr.xpath(".//nbr[text()='" + nbr + "']") if m is None: return False mm = None for k in m: if k.getparent().find('date').text == date: mm = k break if mm is None: return False # replace nbr mm.text = new_nbr # order all mails according to their nbr mails = tr.find('mails') mails[:] = sorted(mails, key=lambda x: parse_nbr_xml(x.find('nbr').text)) tr.write(fp) return True def delete_nbr_xml(d, fn, nbr, date): fp = os.path.join(d, fn) if not os.path.isfile(fp): return False tr = et.parse(fp) m = tr.xpath(".//nbr[text()='" + nbr + "']") if m is None: return False mm = None for k in m: if k.getparent().find('date').text == date: mm = k break if mm is None: return False mail = mm.getparent() mail.getparent().remove(mail) tr.write(fp) return True @app.route('/xml', methods = ['GET']) def xml(): if request.method == 'GET': li = list_all(config.xml['path'], 'xml') li = sorted(li, key=lambda x: int(x.split('.')[0])) return render_template("list_files_all.html", title="XML [all]", prefix="/xml/", files=li) @app.route('/xml/', methods = ['GET', 'POST']) def xmlfn(fn): if request.method == 'GET': data = read_xml(config.xml['path'], fn) if data is not None: return render_template("xml.html", fn=fn, data=data) else: return "File: " + fn + "does not exist." elif request.method == 'POST': data = request.form a = data.get('action') if a == "update": logging.info("POST UPDATE " + fn + " -- " + data.get('nbr') + " ++ " + data.get('new_nbr')) if update_nbr_xml(config.xml['path'], fn, data.get('nbr'), data.get('new_nbr'), data.get('date')): return "ok" elif a == "delete": logging.info("POST DELETE " + fn + " -- " + data.get('nbr')) if delete_nbr_xml(config.xml['path'], fn, data.get('nbr'), data.get('date')): return "ok" return "-"