def main(args, opts): jdb.reset_encoding(sys.stdout, 'utf-8') errs = [] try: form, svc, dbg, cur, sid, sess, parms, cfg = jmcgi.parseform() except Exception as e: jmcgi.err_page([str(e)]) # The filesystem path of the directory containing editdata files. filesdir = cfg['web']['EDITDATA_DIR'] # The URL for the directory containing editdata files. httpdir = cfg['web']['EDITDATA_URL'] fv = lambda x: (form.getfirst(x) or '').decode(Enc) is_editor = jmcgi.is_editor(sess) allfiles = sorted(os.listdir(filesdir)) editfiles = [x for x in allfiles if re.search(r'[0-9]{5}\.dat$', x)] logfiles = [x for x in allfiles if re.search(r'((ok)|(bad))\.log$', x)] jmcgi.jinja_page('jbedits.jinja', parms=parms, filesdir=filesdir, httpdir=httpdir, editfiles=editfiles, logfiles=logfiles, svc=svc, dbg=dbg, sid=sid, session=sess, cfg=cfg, this_page='jbedits.py')
def main (args, opts): jdb.reset_encoding (sys.stdout, 'utf-8') errs = [] try: form, svc, dbg, cur, sid, sess, parms, cfg = jmcgi.parseform() except Exception as e: jmcgi.err_page ([str (e)]) # The filesystem path of the directory containing editdata files. filesdir = cfg['web']['EDITDATA_DIR'] # The URL for the directory containing editdata files. httpdir = cfg['web']['EDITDATA_URL'] fv = lambda x:(form.getfirst(x) or '').decode(Enc) is_editor = jmcgi.is_editor (sess) srcs = sorted (jdb.KW.recs('SRC'), key=lambda x: x.kw.lower()) # Get the filename url parameter, and validate it. fn = fv ('fn') if not re.search (r'[0-9]{5}\.dat$', fn) or '/' in fn: err_page (["Bad 'fn' url parameter"]) fullname = os.path.join (filesdir, fn) # Open the file, get the data. try: e, ref, comment, name, email = read_editdata (cur, fullname) except Exception as e: err_page (["Bad file data, unable to unserialize: %s" % str(e)]) extra = {'ref':ref, 'comment':comment, 'name':name, 'email':email} e.NOCORPOPT = '' # This seems to be required by template, see edform.py jmcgi.jinja_page ('edform.jinja', parms=parms, entrs=[e], extra=extra, srcs=srcs, is_editor=is_editor, svc=svc, dbg=dbg, sid=sid, session=sess, cfg=cfg, this_page='jbedit.py')
def main(args, opts): global Svc, Sid jdb.reset_encoding(sys.stdout, 'utf-8') errs = [] dbh = svc = None try: form, svc, dbg, dbh, sid, sess, parms, cfg = jmcgi.parseform() except ValueError as e: jmcgi.err_page([str(e)]) # Svc and Sid are used in function url() and are global in # in order to avoid having to pass them through several layers # of function calls. Svc, Sid = svc, sid L('cgi.edsubmit').debug("started: userid=%s, sid=%s" % (sess and sess.userid, sess and sess.id)) fv = form.getfirst # disp values: '': User submission, 'a': Approve. 'r': Reject; disp = fv('disp') or '' if not sess and disp: errs.append("Only registered editors can approve or reject entries") if errs: jmcgi.err_page(errs) try: entrs = serialize.unserialize(fv("entr")) except Exception: jmcgi.err_page(["Bad 'entr' parameter, unable to unserialize."]) added = [] # Clear any possible transactions begun elsewhere (e.g. by the # keyword table read in jdb.dbOpen()). Failure to do this will # cause the following START TRANSACTON command to fail with: # InternalError: SET TRANSACTION ISOLATION LEVEL must be # called before any query L('cgi.edsubmit.main').debug("starting transaction") dbh.connection.rollback() dbh.execute("START TRANSACTION ISOLATION LEVEL SERIALIZABLE") # FIXME: we unserialize the entr's xref's as they were resolved # by the edconf.py page. Should we check them again here? # If target entry was deleted in meantime, attempt to add # our entr to db will fail with obscure foreign key error. # Alternatively an edited version of target may have been # created which wont have our xref pointing to it as it should. for entr in entrs: # FIXME: submission() can raise a psycopg2 # TransactionRollbackError if there is a serialization # error resulting from a concurrent update. Detecting # such a condition is why run with serializable isolation # level. We need to trap it and present some sensible # error message. e = submission(dbh, entr, disp, errs, jmcgi.is_editor(sess), sess.userid if sess else None) # The value returned by submission() is a 3-tuple consisting # of (id, seq, src) for the added entry. if e: added.append(e) if errs: L('cgi.edsubmit.main').info("rolling back transaction due to errors") dbh.connection.rollback() jmcgi.err_page(errs) else: L('cgi.edsubmit.main').info("doing commit") dbh.connection.commit() jmcgi.jinja_page("submitted.jinja", added=added, parms=parms, svc=svc, dbg=dbg, sid=sid, session=sess, cfg=cfg, this_page='edsubmit.py') L('cgi.edsubmit.main').debug("thank you page sent, exiting normally")
def main(args, opts): jdb.reset_encoding(sys.stdout, 'utf-8') errs = [] chklist = {} try: form, svc, dbg, cur, sid, sess, parms, cfg = jmcgi.parseform() except Exception as e: jmcgi.err_page([str(e)]) fv = form.getfirst fl = form.getlist KW = jdb.KW # 'eid' will be an integer if we are editing an existing # entry, or undefined if this is a new entry. pentr = None eid = url_int('id', form, errs) if eid: # Get the parent entry of the edited entry. This is what the # edited entry will be diff'd against for the history record. # It is also the entry that will be pointed to by the edited # entry's 'dfrm' field. pentr = jdb.entrList(cur, None, [eid]) #FIXME: Need a better message with more explanation. if not pentr: errs.append("The entry you are editing has been deleted.") else: pentr = pentr[0] # Desired disposition: 'a':approve, 'r':reject, undef:submit. disp = url_str('disp', form) if disp != 'a' and disp != 'r' and disp != '' and disp is not None: errs.append("Invalid 'disp' parameter: '%s'" % disp) # New status is A for edit of existing or new entry, D for # deletion of existing entry. delete = fv('delete') makecopy = fv('makecopy') if delete and makecopy: errs.append( "The 'delete' and 'treat as new'" " checkboxes are mutually exclusive; please select only one.") if makecopy: eid = None # FIXME: we need to disallow new entries with corp.seq # that matches an existing A, A*, R*, D*, D? entry. # Do same check in submit.py. seq = url_int('seq', form, errs) src = url_int('src', form, errs) notes = url_str('notes', form) srcnote = url_str('srcnote', form) # These are the JEL (JMdict Edit Language) texts which # we will concatenate into a string that is fed to the # JEL parser which will create an Entr object. kanj = (stripws(url_str('kanj', form))).strip() rdng = (stripws(url_str('rdng', form))).strip() sens = (url_str('sens', form)).strip() intxt = "\f".join((kanj, rdng, sens)) grpstxt = url_str('grp', form) # Get the meta-edit info which will go into the history # record for this change. comment = url_str('comment', form) refs = url_str('reference', form) name = url_str('name', form) email = url_str('email', form) if errs: jmcgi.err_page(errs) # Parse the entry data. Problems will be reported # by messages in 'perrs'. We do the parse even if # the request is to delete the entry (is this right # thing to do???) since on the edconf page we want # to display what the entry was. The edsubmit page # will do the actual deletion. entr, errs = parse(intxt) # 'errs' is a list which if not empty has a single item # which is a 2-seq of str's: (error-type, error-message). if errs or not entr: if not entr and not errs: errs = ([], "Unable to create an entry from your input.") jmcgi.err_page([errs[0][1]], prolog=errs[0][0], cssclass="errormsg") entr.dfrm = eid entr.unap = not disp # To display the xrefs and reverse xrefs in html, they # need to be augmented with additional info about their # targets. collect_refs() simply returns a list Xref # objects that are on the entr argument's .xref list # (forward xrefs) if rev not true, or the Xref objects # on the entr argument's ._xrer list (reverse xrefs) if # rev is true). This does not remove them from the entry # and is done simply for convenience so we can have # augment_xrefs() process them all in one shot. # augment_xrefs add an attribute, .TARG, to each Xref # object whose value is an Entr object for the entry the # xref points to if rev is not true, or the entry the xref # is from, if rev is true. These Entr objects can be used # to display info about the xref target or source such as # seq#, reading or kanji. See jdb.augment_xrefs() for details. # Note that <xrefs> and <xrers> below contain references # to the xrefs on the entries; thus the augmentation done # by jdb.augment_xrefs() alters the xref objects on those # entries. if pentr: x = jdb.collect_xrefs([pentr]) if x: jdb.augment_xrefs(cur, x) # Although we don't allow editing of an entry's reverse # xref, we still augment them (on the parent entry) # because we will display them. x = jdb.collect_xrefs([pentr], rev=True) if x: jdb.augment_xrefs(cur, x, rev=True) x = jdb.collect_xrefs([entr]) if x: jdb.augment_xrefs(cur, x) if delete: # Ignore any content changes made by the submitter by # restoring original values to the new entry. entr.seq = pentr.seq entr.src = pentr.src entr.stat = KW.STAT['D'].id entr.notes = pentr.notes entr.srcnote = pentr.srcnote entr._kanj = getattr(pentr, '_kanj', []) entr._rdng = getattr(pentr, '_rdng', []) entr._sens = getattr(pentr, '_sens', []) entr._snd = getattr(pentr, '_snd', []) entr._grp = getattr(pentr, '_grp', []) entr._cinf = getattr(pentr, '_cinf', []) else: # Migrate the entr details to the new entr object # which to this point has only the kanj/rdng/sens # info provided by jbparser. entr.seq = seq entr.src = src entr.stat = KW.STAT['A'].id entr.notes = notes entr.srcnote = srcnote entr._grp = jelparse.parse_grp(grpstxt) # This form and the JEL parser provide no way to change # some entry attributes such _cinf, _snd, reverse xrefs # and for non-editors, _freq. We need to copy these items # from the original entry to the new, edited entry to avoid # loosing them. The copy can be shallow since we won't be # changing the copied content. if pentr: if not jmcgi.is_editor(sess): jdb.copy_freqs(pentr, entr) if hasattr(pentr, '_cinf'): entr._cinf = pentr._cinf copy_snd(pentr, entr) # Copy the reverse xrefs that are on pentr to entr, # removing any that are no longer valid because they # refer to senses , readings or kanji no longer present # on the edited entry. Note that these have already # been augmented above. nuked_xrers = realign_xrers(entr, pentr) if nuked_xrers: chklist['xrers'] = format_for_warnings(nuked_xrers, pentr) # Add sound details so confirm page will look the same as the # original entry page. Otherwise, the confirm page will display # only the sound clip id(s). #FIXME? Should the following snd augmentation stuff be outdented # one level so that it is done in both the delete and non-delete # paths? snds = [] for s in getattr(entr, '_snd', []): snds.append(s) for r in getattr(entr, '_rdng', []): for s in getattr(r, '_snd', []): snds.append(s) if snds: jdb.augment_snds(cur, snds) # If any xrefs were given, resolve them to actual entries # here since that is the form used to store them in the # database. If any are unresolvable, an approriate error # is saved and will reported later. rslv_errs = jelparse.resolv_xrefs(cur, entr) if rslv_errs: chklist['xrslv'] = rslv_errs if errs: jmcgi.err_page(errs) # Append a new hist record details this edit. if not hasattr(entr, '_hist'): entr._hist = [] entr = jdb.add_hist(entr, pentr, sess.userid if sess else None, name, email, comment, refs, entr.stat == KW.STAT['D'].id) if not delete: check_for_errors(entr, errs) if errs: jmcgi.err_page(errs) pseq = pentr.seq if pentr else None check_for_warnings(cur, entr, pseq, chklist) # The following all expect a list of entries. jmcgi.add_filtered_xrefs([entr], rem_unap=False) serialized = serialize.serialize([entr]) jmcgi.htmlprep([entr]) entrs = [[entr, None]] # Package 'entr' as expected by entr.jinja. jmcgi.jinja_page("edconf.jinja", entries=entrs, serialized=serialized, chklist=chklist, disp=disp, parms=parms, svc=svc, dbg=dbg, sid=sid, session=sess, cfg=cfg, this_page='edconf.py')
def main(args, opts): jdb.reset_encoding(sys.stdout, 'utf-8') errs = [] entrs = [] try: form, svc, dbg, cur, sid, sess, parms, cfg = jmcgi.parseform() except Exception as e: jmcgi.err_page([str(e)]) fv = form.getfirst fl = form.getlist is_editor = jmcgi.is_editor(sess) dbg = fv('dbg') meth = fv('meth') def_corp = fv('c') # Default corpus for new entries. defcorpid = None if def_corp: try: def_corp = int(def_corp) except ValueError: pass try: defcorpid = jdb.KW.SRC[def_corp].id except KeyError: errs.append("Bad url parameter: c=%s" % def_corp) force_corp = fv('f') # Force default corpus for new entries. sentrs = fl("entr") for sentr in sentrs: try: entrs = serialize.unserialize(sentr) except Exception as e: errs.append("Bad 'entr' value, unable to unserialize: %s" % str(e)) else: entrs.append(entr) jentrs = fl('j') for jentr in jentrs: try: entr = edparse.entr(jentr) except Exception as e: errs.append("Bad 'j' value, unable to parse: %s" % str(e)) else: entr.src = None entrs.append(entr) elist, qlist, active = fl('e'), fl('q'), fv('a') if elist or qlist: entrs.extend( jmcgi.get_entrs(cur, elist or [], qlist or [], errs, active=active, corpus=def_corp) or []) cur.close() if (elist or qlist or jentrs or sentrs) and not entrs: # The caller explictly specified and entry to edit but we # didn't find it (or them). Rather than treating this as # though no entries were given and displaying a blank edit # form, show an error message. errs.append("No matching entries were found") if errs: jmcgi.err_page(errs) srcs = sorted(jdb.KW.recs('SRC'), key=lambda x: x.kw.lower()) #srcs.insert (0, jdb.Obj (id=0, kw='', descr='')) if not entrs: # This is a blank new entry. # The following dummy entry will produce the default # text for new entries: no kanji, no reading, and sense # text "[1][n]". entr = jdb.Entr( _sens=[jdb.Sens(_pos=[jdb.Pos(kw=jdb.KW.POS['n'].id)])], src=None) entrs = [entr] for e in entrs: if not is_editor: remove_freqs(e) e.ISDELETE = (e.stat == jdb.KW.STAT['D'].id) or None # Provide a default corpus. if not e.src: e.src = defcorpid e.NOCORPOPT = force_corp if errs: jmcgi.err_page(errs) for e in entrs: e.ktxt = fmtjel.kanjs(e._kanj) e.rtxt = fmtjel.rdngs(e._rdng, e._kanj) e.stxt = fmtjel.senss(e._sens, e._kanj, e._rdng) if errs: jmcgi.err_page(errs) jmcgi.jinja_page('edform.jinja', parms=parms, extra={}, entrs=entrs, srcs=srcs, is_editor=is_editor, svc=svc, dbg=dbg, sid=sid, session=sess, cfg=cfg, this_page='edform.py')