def categories(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' db = jodb.connect() results = db.query("SELECT coalesce(info, ''), count(*) FROM raw_word " + "WHERE processed = FALSE " + "GROUP BY coalesce(info, '') " + "ORDER BY coalesce(info, '') ") if results.ntuples() == 0: joheaders.error_page(req, _(u'There are no words to be added')) return '\n' joheaders.page_header_navbar_level1(req, _(u"Add words"), uid, uname) jotools.write(req, u"<p>%s:</p>\n" \ % _(u'Choose a category from which you want to add words')) jotools.write(req, u"<table><tr><th>%s</th><th>%s</th></tr>\n" \ % (_(u'Category'), _(u'Words left'))) for result in results.getresult(): cat = unicode(result[0], 'UTF-8') if cat == u'': cats = u'(' + _(u'no category') + u')' else: cats = cat jotools.write(req, (u'<tr><td><a href="add_from_db?category=%s">%s</a></td>' + u'<td>%i</td></tr>\n') \ % (jotools.escape_url(result[0]), jotools.escape_html(cats), result[1])) jotools.write(req, u"</table>\n") jotools.write(req, u'<p><a href="add_from_db">%s ...</a></p>\n' % _(u'All words')) joheaders.page_footer_plain(req) return '\n'
def _html(req, db, query): offset_s = `jotools.toint(jotools.get_param(req, 'offset', u'0'))` limit_s = `jotools.toint(jotools.get_param(req, 'limit', u'200'))` if limit_s == u'0': limit_s = u'ALL' param_s = u'' for field in req.form.list: if not field.name in ['limit', 'offset'] and jotools.checkid(field.name): param_s = param_s + field.name + u'=' + jotools.get_param(req, field.name, u'') + u'&' results = db.query("%s LIMIT %s OFFSET %s" % (query, limit_s, offset_s)) if results.ntuples() == 0: joheaders.error_page(req, _(u'No matching words were found')) return "\n" elif results.ntuples() == 1: joheaders.redirect_header(req, _config.WWW_ROOT_DIR + "/word/edit?wid=%i" \ % results.getresult()[0][0]) return "\n" else: (uid, uname, editable) = jotools.get_login_user(req) joheaders.page_header_navbar_level1(req, _('Search results'), uid, uname) jotools.write(req, u'<table><tr><th>%s</th><th>%s</th></tr>\n' \ % (_("Word"), _("Word class"))) for result in results.getresult(): jotools.write(req, _print_html_line(db, result[0], unicode(result[1], 'UTF-8'), unicode(result[2], 'UTF-8'))) jotools.write(req, u"</table>\n") if not limit_s == u'ALL' and results.ntuples() == jotools.toint(limit_s): jotools.write(req, (u'<p><a href="wlist?%soffset=%i&limit=%s">' + u"%s ...</a></p>\n") % (param_s, int(offset_s)+int(limit_s), limit_s, _(u'More results'))) joheaders.page_footer_plain(req) return '\n'
def passwdform(req): (uid, uname, editable) = jotools.get_login_user(req) if uid == None: joheaders.error_page(req, _(u'You must be logged in to do this')) return '\n' joheaders.page_header_navbar_level1(req, _(u'Change password'), uid, uname) jotools.write(req, u''' <form method="post" action="changepasswd"> <table> <tr><td>%s</td><td><input type="password" name="oldpw" /></td></tr> <tr><td>%s</td><td><input type="password" name="newpw" /></td></tr> </table> <input type="submit" value="%s" /> </form> ''' % (_(u'Old password'), _(u'New password'), _(u'Change password'))) joheaders.page_footer_plain(req) return '\n'
def add_manual(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' if req.method != 'GET': joheaders.error_page(req, _(u'Only GET requests are allowed')) return '\n' db = jodb.connect() words_per_page = 15 joheaders.page_header_navbar_level1(req, _(u"Add words"), uid, uname) jotools.write(req, u'<form method="post" action="add">\n' + u'<table class="border">\n<tr><th>%s</th><th>%s</th></tr>\n' \ % (_(u'Word'), _(u'Word class'))) _add_entry_fields(req, db, None, words_per_page) jotools.write(req, u'</table>\n' + u'<p><input type="submit" value="%s"></p></form>\n' % _(u"Add words")) joheaders.page_footer_plain(req) return '\n'
def _print_error_forbidden(req): "Print an error, if adding new words is no longer possible" jotools.write(req, u''' <p>Et voi (enää) ehdottaa uusia lisättäviä sanoja. Tarkista seuraavat asiat:</p> <ul> <li>Oletko jo ehdottanut 20 sanaa tämän päivän aikana? Väärinkäytösten estämiseksi rekisteröitymättömät käyttäjät eivät voi tehdä enempää ehdotuksia yhden vuorokauden aikana. Jos sinulla on enemmän ehdotuksia lisättäviksi tai poistettaviksi sanoiksi, yritä huomenna uudelleen, tai lähetä ehdotuksesi sähköpostitse yhteystiedoissa mainittuun osoitteeseen.</li> <li>Onko joku muu käyttänyt tänään tätä palvelua samalta koneelta kuin sinä, tai onko Internet-selaimesi asetettu käyttämään välityspalvelinta? Rekisteröitymättömien käyttäjien rajoitukset tehdään koneen ip-osoitteen perusteella, joten joku muu on ehkä jo käyttänyt päivittäisen lisäyskiintiösi. Pahoittelemme ongelmaa, mutta meillä ei ole mahdollisuutta käyttää älykkäämpiä rajoitusmenetelmiä. Voit lähettää lisäysehdotuksesi sähköpostitse.</li> </ul> <p>Jos sinulla on käyttäjätunnus Joukahaiseen, kirjautumalla sisään pääset käyttämään tätä palvelua rajoituksetta. Rekisteröityneiden käyttäjien tulisi kuitenkin mieluummin lisätä sanat suoraan sanastotietokantaan.</p>''')
def addform(req): (uid, uname, editable) = jotools.get_login_user(req) if not jotools.is_admin(uid): joheaders.error_page(req, _(u'You must be an administrator to do this')) return '\n' joheaders.page_header_navbar_level1(req, _(u'Add user'), uid, uname) jotools.write(req, u''' <form method="post" action="add"> <table> <tr><td>%s</td><td><input type="text" name="firstname" /></td></tr> <tr><td>%s</td><td><input type="text" name="lastname" /></td></tr> <tr><td>%s</td><td><input type="text" name="uname" /></td></tr> <tr><td>%s</td><td><input type="text" name="email" /></td></tr> <tr><td>%s</td><td><input type="text" name="passwd" /></td></tr> </table> <input type="submit" value="%s" /> </form> ''' % (_(u'First name'), _(u'Last name'), _(u'Username'), _(u'Email address'), _(u'Password'), _(u'Add user'))) joheaders.page_footer_plain(req) return '\n'
def _page_header_internal(req, title, h1, uid, uname, wid): req.content_type = "text/html; charset=UTF-8" req.send_http_header() jotools.write(req, u"""<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi" lang="fi"> <head> <title>%s</title> <link rel="stylesheet" type="text/css" href="%s/style.css" /> <link rel="icon" type="image/png" href="%s/joukahainen-small.png" /> <link rel="search" type="application/opensearchdescription+xml" title="Joukahainen" href="%s/searchplugin-fullsearch-re.xml" /> <script type="text/javascript" src="%s/jscripts.js"></script> </head> <body onload="initPage()"> <div class="topbar">""" % (title, _config.WWW_ROOT_DIR, _config.WWW_ROOT_DIR, _config.WWW_ROOT_DIR, _config.WWW_ROOT_DIR)) jotools.write(req, u"\n<h1>%s</h1>" % h1) if uid == None: jotools.write(req, u""" <div class="login"> <form method="post" action="%s/user/login"><p> <label>%s: <input type="text" size="12" name="username" /></label> <label>%s: <input type="password" size="12" name="password" /></label> <input type="hidden" name="wid" value="%i" /> <input type="submit" value="%s" /> </p></form> </div> """ % (_config.WWW_ROOT_DIR, _(u'Username'), _(u'Password'), wid, _(u'Log in'))) else: jotools.write(req, u""" <div class="login"> <form method="post" action="%s/user/logout"><p> <input type="hidden" name="wid" value="%i" /> <input type="submit" value="%s %s" /> </p></form> </div> """ % (_config.WWW_ROOT_DIR, wid, _(u'Log out user'), uname)) jotools.write(req, u'<div class="clear"></div></div><div class="main">\n')
def work(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' tid = jotools.toint(jotools.get_param(req, "tid", "0")) if tid == 0: joheaders.error_page(req, _(u'Parameter %s is required') % u'tid') return '\n' joheaders.frame_header(req, u"Joukahainen > %s %i" % (_(u'task'), tid)) jotools.write(req, u'<frameset cols="20%, 80%">\n') jotools.write(req, u'<frame name="left" src="show?tid=%i" />\n' % tid) jotools.write(req, u'<frame name="right" />\n') jotools.write(req, u'</frameset>\n') joheaders.frame_footer(req) return '\n'
def index(req): db = jodb.connect() privdb = jodb.connect_private() (uid, uname, editable) = jotools.get_login_user(req) joheaders.page_header_navbar_level1(req, u"Ehdota uusia sanoja", uid, uname) word = jotools.get_param(req, "word", u"").strip() wtype = jotools.get_param(req, "type", u"").strip() comment = jotools.get_param(req, "comment", u"").strip() if word != u"": if not jotools.checkword(word): jotools.write(req, u'<p class="error">Sanassa on kiellettyjä merkkejä.</p>') _print_entry_form(req, db) else: db.query("BEGIN") error = _is_old_word(req, db, word) if error != None: jotools.write(req, u'<p class="error">%s</p>' % error) _print_entry_form(req, db) elif not (editable or _allow_new_word(req, privdb, True)): _print_error_forbidden(req) else: db.query("INSERT INTO raw_word(word, info, notes) " + "VALUES('%s', '%s', '%s')" % \ (jotools.escape_sql_string(word), jotools.escape_sql_string(wtype), jotools.escape_sql_string(comment))) jotools.write(req, u'<p class="ok">Ehdotuksesi on tallennettu. ' + u'Kiitos avusta!</p>') _print_entry_form(req, db) db.query("COMMIT") elif editable or _allow_new_word(req, privdb, False): _print_entry_form(req, db) else: _print_error_forbidden(req) joheaders.page_footer_plain(req) return '\n'
def _print_entry_form(req, db): "Prints an entry form for word suggestions" jotools.write(req, u'''<p>Joukahainen on Voikko-oikolukuohjelmiston kehittäjien yhteinen sanastotietokanta. Sen avulla myös Voikon käyttäjät voivat auttaa kehittäjiä tekemään ohjelmasta entistäkin paremman. Esimerkiksi LibreOfficea käyttäessäsi saatat joskus huomata, että oikolukutoiminto ei hyväksy jotain kirjoittamaasi sanaa, vaikka se on oikein. Voit ilmoittaa meille näistä sanoista tämän lomakkeen kautta.</p> <form method="post" action="ehdotasanoja"> <p><label>Lisättävä sana: <input type="text" name="word" size="30" /></label><br /> <i>Lisättävä sana on parasta kirjoittaa perusmuodossaan. Tämä ei kuitenkaan ole välttämätöntä, jos olet epävarma sanan oikeasta perusmuodosta.</i></p> <p><label>Sanan tyyppi: <select name="type"> <option selected="selected" value="yleiskieltä">yleiskielinen sana</option>''') for sv in _get_special_vocabularies(db): jotools.write(req, u'<option value="%s">%s</option>' % (sv, sv)) jotools.write(req, u''' <option value="virheellinen">virheellinen sana (poistettava sanastosta)</option> </select></label><br /> <i>Valitse lisättävän sanan tyyppi. Vaihtoehtoisesti voit valita kohdan "virheellinen sana", jos Voikko hyväksyy virheellisen sanan.</i></p> <p><label>Lisätietoja: <input type="text" name="comment" size="60" /></label><br /> <i>Tähän voit kirjoittaa sanaan liittyviä lisätietoja. Jos sana on jonkin erikoisalan termi tai muuten harvinainen, kirjoita tähän sille lyhyt selitys.</i></p> <p><input type="submit" value="Lähetä ehdotus" /></p> </form> <hr /> <p>Ehdotukset käsitellään yleensä parin päivän kuluessa niiden lähettämisestä. Päivitettyjä versioita Voikon sanastosta julkaistaan puolestaan noin puolen vuoden välein. Jos sinulla on paljon ehdotuksia sanastoon lisättäviksi sanoiksi tai haluat auttaa jonkin erikoisalan sanaston kehityksessä, voit myös lähettää ehdotuksesi sähköpostitse Harri Pitkäselle (<a href="mailto:[email protected]">[email protected]</a>).</p> <p>Voikkoa kehitetään pääasiassa vapaaehtoisvoimin. Lisää tietoa Voikosta löytyy osoitteesta <a href="http://voikko.puimula.org">voikko.puimula.org</a>.</p>''')
def show(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' tid = jotools.toint(jotools.get_param(req, "tid", "0")) if tid == 0: joheaders.error_page(req, _(u'Parameter %s is required') % u'tid') return '\n' words_per_page = 20 db = jodb.connect() taskq = db.query("SELECT sql, orderby FROM task WHERE tid = %i" % tid) if taskq.ntuples() != 1: joheaders.error_page(req, u'Parameter %s is wrong' % u'tid') return '\n' tasksql = taskq.getresult()[0][0] taskorder = taskq.getresult()[0][1] results = db.query(("SELECT w.wid, w.word FROM word w, (%s) t " + "WHERE t.wid = w.wid AND w.wid NOT IN " + "(SELECT tw.wid FROM task_word tw WHERE tw.tid = %i)" + "ORDER BY %s") % (tasksql, tid, taskorder)) joheaders.page_header_nonavbar(req, u"%s %i" % (_(u'task'), tid)) jotools.write(req, u'<form method="post" action="save">\n') jotools.write(req, u'<table class="border">\n<tr><th>%s</th><th>%s</th></tr>\n' \ % (_(u'OK'), _(u'Word'))) firstword = random.randint(0, max(results.ntuples() - words_per_page, 0)) restuples = results.getresult() for i in range(firstword, min(firstword + words_per_page, results.ntuples())): word = restuples[i] jotools.write(req, u'<tr><td><input type="checkbox" name="checked%i" /></td>' \ % word[0]) jotools.write(req, (u'<td><a href="../word/edit?wid=%i" target="right">%s' + u'</a></td></tr>\n') \ % (word[0], jotools.escape_html(unicode(word[1], 'UTF-8')))) jotools.write(req, u'</table>') jotools.write(req, u'<p><input type="hidden" name="tid" value="%i" />' % tid) jotools.write(req, u'<input type="submit" value="%s"></form></p>' % _(u'Save checked')) jotools.write(req, u'<p><a href="../" target="_top">%s</a></p>\n' \ %_(u'Back to main page')) joheaders.page_footer_plain(req) return '\n'
def list(req): (uid, uname, editable) = jotools.get_login_user(req) db = jodb.connect() tasks = db.query("SELECT t.tid, t.descr, t.sql, COUNT(DISTINCT tw.wid) FROM task t " + "LEFT JOIN task_word tw ON (t.tid = tw.tid) " + "GROUP BY t.tid, t.descr, t.sql ORDER BY t.tid") if tasks.ntuples() == 0: joheaders.error_page(req, _(u'There are no tasks.')) return '\n' joheaders.page_header_navbar_level1(req, _(u"tasks"), uid, uname) jotools.write(req, u"<p>%s:</p>\n" % _(u'Choose a task')) jotools.write(req, (u'<table class="border"><tr><th>%s</th><th>%s</th>' + u'<th>%s *</th><th>%s *</th></tr>\n') \ % (_(u'Task'), _(u'Total words'), _(u'Words left'), _(u'Completed'))) for task in tasks.getresult(): wordcount = db.query("SELECT COUNT(*) FROM (%s) AS q" % task[2]).getresult()[0][0] jotools.write(req, u'<tr><td><a href="work?tid=%i">' % task[0]) jotools.write(req, u'%s</a></td>' % jotools.escape_html(unicode(task[1],'UTF-8'))) jotools.write(req, u'<td>%i</td>' % wordcount) jotools.write(req, u'<td>%i</td>' % (wordcount - task[3])) if wordcount == 0: pleft = u'-' else: pleft = task[3] * 100 / wordcount jotools.write(req, u'<td>%s %%</td></tr>\n' % pleft) jotools.write(req, u"</table>\n") # "Words left" is an approximation, because all of the checked words may not belong to # this task any more. Calculating the exact numbers is too slow to do here. jotools.write(req, u"<p>*) %s.</p>" % _(u'Number of words left is an estimate')) joheaders.page_footer_plain(req) return '\n'
def flags(req, wid = None): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' if wid == None: joheaders.error_page(req, _(u'Parameter %s is required') % u'wid') return '\n' wid_n = jotools.toint(wid) db = jodb.connect() results = db.query("select word, class from word where wid = %i" % wid_n) if results.ntuples() == 0: joheaders.error_page(req, _(u'Word %i does not exist') % wid_n) return '\n' wordinfo = results.getresult()[0] if req.method == 'GET': # show editor word = unicode(wordinfo[0], 'UTF-8') classid = wordinfo[1] title1 = _(u'Word') + u': ' + word link1 = u'edit?wid=%i' % wid_n title2 = _(u'flags') joheaders.page_header_navbar_level2(req, title1, link1, title2, uid, uname, wid_n) jotools.write(req, u'<p>%s</p>\n' % joeditors.call(db, u'word_class', [classid])) jotools.write(req, joeditors.call(db, u'flag_edit_form', [wid_n, classid])) joheaders.page_footer_plain(req) return '\n' if req.method != 'POST': joheaders.error_page(req, _(u'Only GET and POST requests are allowed')) return '\n' db.query("begin") edfield_results = db.query(("SELECT a.aid, a.descr, CASE WHEN fav.wid IS NULL THEN 'f' ELSE 't' END " + "FROM attribute_class ac, attribute a " + "LEFT OUTER JOIN flag_attribute_value fav ON (a.aid = fav.aid and fav.wid = %i) " + "WHERE a.aid = ac.aid AND ac.classid = %i AND a.type = 2" + "ORDER BY a.descr") % (wid_n, wordinfo[1])) eid = db.query("select nextval('event_eid_seq')").getresult()[0][0] event_inserted = False messages = [] for attribute in edfield_results.getresult(): html_att = 'attr%i' % attribute[0] if jotools.get_param(req, html_att, u'') == u'on': newval = True else: newval = False if attribute[2] == 't': oldval = True else: oldval = False if oldval == newval: continue if not event_inserted: db.query("insert into event(eid, eword, euser) values(%i, %i, %i)" % \ (eid, wid_n, uid)) event_inserted = True if newval == False: db.query(("delete from flag_attribute_value where wid = %i " + "and aid = %i") % (wid_n, attribute[0])) messages.append(_(u"Flag removed: '%s'") % unicode(attribute[1], 'UTF-8')) if newval == True: db.query(("insert into flag_attribute_value(wid, aid, eevent) " + "values(%i, %i, %i)") % (wid_n, attribute[0], eid)) messages.append(_(u"Flag added: '%s'") % unicode(attribute[1], 'UTF-8')) comment = jotools.get_param(req, 'comment', u'') if comment != u'': if not event_inserted: db.query("insert into event(eid, eword, euser) values(%i, %i, %i)" % \ (eid, wid_n, uid)) event_inserted = True db.query("update event set comment = '%s' where eid = %i" \ % (jotools.escape_sql_string(comment), eid)) if event_inserted and len(messages) > 0: mess_str = jotools.escape_sql_string(reduce(lambda x, y: x + u"\n" + y, messages, u"")) db.query("update event set message = '%s' where eid = %i" % (mess_str, eid)) db.query("commit") joheaders.redirect_header(req, u'edit?wid=%i' % wid_n) return '\n'
def form(req): db = jodb.connect() (uid, uname, editable) = jotools.get_login_user(req) joheaders.page_header_navbar_level1(req, _(u'Search database'), uid, uname) jotools.write(req, u'<form method="get" action="wlist">\n<p>') jotools.write(req, u'<label>%s: <input type="text" name="word" /></label></p>\n' % _(u'Word')) jotools.write(req, u'<p><label><input type="checkbox" name="wordre" /> %s</label>\n' \ % _(u'Use regular expression')) jotools.write(req, u' <b>%s</b> <label><input type="checkbox" name="wordsimplere" /> %s</label><br />\n' \ % (_(u'or'), _(u'Case insensitive search'))) jotools.write(req, u'<label><input type="checkbox" name="altforms" /> %s</label></p>\n' \ % _(u'Search from alternative spellings')) wclasses = db.query("SELECT classid, name FROM wordclass ORDER BY classid").getresult() jotools.write(req, u'<h2>%s</h2>\n' % _(u'Word class')) jotools.write(req, u'<p>%s ' % _(u'Word class is')) jotools.write(req, u'<select name="wordclass">\n') jotools.write(req, u'<option selected="selected" value="">(%s)</option>\n' % _(u'any')) for (classid, name) in wclasses: jotools.write(req, u'<option value="%i">%s</option>\n' % (classid, unicode(name, 'UTF-8'))) jotools.write(req, u'</select></p>\n') textattrs = db.query("SELECT aid, descr FROM attribute WHERE type = 1 ORDER BY descr, aid").getresult() jotools.write(req, u'<h2>%s</h2>\n' % _(u'Text attributes')) jotools.write(req, u'<p><select name="textaid">\n') jotools.write(req, u'<option selected="selected" value="">(%s)</option>\n' % _(u'select attribute')) for (aid, dsc) in textattrs: jotools.write(req, u'<option value="%i">%s</option>\n' % (aid, unicode(dsc, 'UTF-8'))) jotools.write(req, u'</select> %s <input type="text" name="textvalue" /><br />\n' % _(u'is')) flagattrs = db.query("SELECT aid, descr FROM attribute WHERE type = 2 ORDER BY descr, aid").getresult() jotools.write(req, u'</p><h2>%s</h2>' % _(u'Flags set')) jotools.write(req, u'<ul class="cblist">') for (aid, dsc) in flagattrs: jotools.write(req, u'<li><label><input type="checkbox" name="flagon%i" />%s</label></li>\n' \ % (aid, unicode(dsc, 'UTF-8'))) jotools.write(req, u'</ul>\n') jotools.write(req, u'<h2>%s</h2>' % _(u'Flags not set')) jotools.write(req, u'<ul class="cblist">') for (aid, dsc) in flagattrs: jotools.write(req, u'<li><label><input type="checkbox" name="flagoff%i" />%s</label></li>\n' \ % (aid, unicode(dsc, 'UTF-8'))) jotools.write(req, u'</ul>\n') jotools.write(req, u'<h2>%s</h2>\n<p>' % _(u'Output type')) for (tname, tdesc) in jooutput.list_supported_types(): if tname == 'html': selected = u'checked="checked"' else: selected = u'' jotools.write(req, (u'<label><input type="radio" name="listtype" value="%s" %s />' + u'%s</label><br />\n') % (tname, selected, tdesc)) jotools.write(req, u'</p><p><input type="submit" value="%s" /><input type="reset" value="%s" /></p>\n' \ % (_(u'Search'), _(u'Reset'))) jotools.write(req, u'</form>\n') joheaders.page_footer_plain(req) return '\n'
def add_from_db(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' if req.method != 'GET': joheaders.error_page(req, _(u'Only GET requests are allowed')) return '\n' db = jodb.connect() words_per_page = 15 category = jotools.get_param(req, 'category', None) if category == None: condition = "" else: condition = "AND coalesce(info, '') = '%s'" \ % jotools.escape_sql_string(category) results = db.query("SELECT count(*) FROM raw_word WHERE processed = FALSE %s" \ % condition) nwords = results.getresult()[0][0] if nwords <= words_per_page: limit = "" else: limit = "LIMIT %i OFFSET %i" % (words_per_page, random.randint(0, nwords - words_per_page)) results = db.query(("SELECT word, coalesce(notes, '') FROM raw_word " + "WHERE processed = FALSE %s " + "ORDER BY word %s") % (condition, limit)) if results.ntuples() == 0 and category == None: joheaders.error_page(req, _(u'There are no words to be added')) return '\n' if results.ntuples() == 0 and category != None: joheaders.error_page(req, _(u'There are no words to be added') + u' ' + _(u'in category %s') % jotools.escape_html(category)) return '\n' class_res = db.query("select classid, name from wordclass").getresult() joheaders.page_header_navbar_level1(req, _(u"Add words"), uid, uname) jotools.write(req, u'<form method="post" action="add">\n') jotools.write(req, u'<table class="border">\n') jotools.write(req, u'<tr><th>%s</th><th>%s</th><th>%s</th></tr>\n' \ % (_(u'Word'), _(u'Word class'), _(u'Notes'))) i = 0 for result in results.getresult(): word = unicode(result[0], 'UTF-8') notes = unicode(result[1], 'UTF-8') jotools.write(req, u'<tr><td><input type="hidden" name="origword%i" value=%s />' \ % (i, jotools.escape_form_value(word))) jotools.write(req, u'<input type="text" name="word%i" value=%s /></td><td>' \ % (i, jotools.escape_form_value(word))) jotools.write(req, _get_class_selector(class_res, None, i, True)) jotools.write(req, u'</td><td>') jotools.write(req, jotools.escape_html(notes)) jotools.write(req, u'</td></tr>\n') i = i + 1 jotools.write(req, u'</table>\n' + u'<p><input type="submit" value="%s"></p></form>\n' % _(u"Add words")) joheaders.page_footer_plain(req) return '\n'
def _add_entry_fields(req, db, words = None, count = 1): class_res = db.query("select classid, name from wordclass").getresult() if words == None: for i in range(count): jotools.write(req, u'<tr><td><input type="text" name="word%i" /></td><td>' % i) for res in class_res: jotools.write(req, (u'<label><input type="radio" name="class%i" ' + 'value="%i">%s</input></label>\n') \ % (i, res[0], jotools.escape_html(unicode(res[1], 'UTF-8')))) jotools.write(req, u'</td></tr>\n') return confirm_column = False for word in words: if word['try_again'] == True: confirm_column = True break i = 0 for word in words: jotools.write(req, u'<tr><td>') if word['try_again']: if word['oword'] != None: jotools.write(req, u'<input type="hidden" name="origword%i" value=%s />' \ % (i, jotools.escape_form_value(word['oword']))) jotools.write(req, u'<input type="hidden" name="word%i" value=%s />%s</td><td>' \ % (i, jotools.escape_form_value(word['word']), jotools.escape_html(word['word']))) incnocls = word['oword'] != None jotools.write(req, _get_class_selector(class_res, word['cid'], i, incnocls)) jotools.write(req, u'<td><input type="checkbox" name="confirm%i"></td><td>' % i) jotools.write(req, word['error']) jotools.write(req, u'</td>') i = i + 1 else: jotools.write(req, jotools.escape_html(word['word'])) jotools.write(req, u'</td><td>') jotools.write(req, _get_class_selector(class_res, word['cid'], -1, False)) jotools.write(req, u'</td><td>') if confirm_column: jotools.write(req, u' </td><td>') jotools.write(req, word['error']) jotools.write(req, u'</td>') jotools.write(req, u'</tr>\n')
def listchanges(req, sdate = None, edate = None): db = jodb.connect() (uid, uname, editable) = jotools.get_login_user(req) joheaders.page_header_navbar_level1(req, _(u'List changes'), uid, uname) edt = datetime.datetime.now() sdt = edt - datetime.timedelta(days=1) if sdate != None: try: stime = time.strptime(sdate, u'%Y-%m-%d') sdt = datetime.datetime(*stime[0:5]) except: jotools.write(req, "<p>%s</p>\n" % _("Invalid start date")) if edate != None: try: etime = time.strptime(edate, u'%Y-%m-%d') edt = datetime.datetime(*etime[0:5]) except: jotools.write(req, "<p>%s</p>\n" % _("Invalid end date")) sdate_s = sdt.strftime('%Y-%m-%d') edate_s = edt.strftime('%Y-%m-%d') jotools.write(req, u""" <form method="get" action="listchanges"> <label>%s <input type="text" name="sdate" value="%s"/></label><br /> <label>%s <input type="text" name="edate" value="%s"/></label><br /> <input type="submit" /> <input type="reset" /> </form> """ % (_(u'Start date'), sdate_s, _(u'End date'), edate_s)) # Increase edt by one day to make the the SQL between operator act on timestamps # in a more intuitive way. edt = edt + datetime.timedelta(days=1) edate_s = edt.strftime('%Y-%m-%d') results = db.query(""" SELECT u.uname, to_char(w.ctime, 'YYYY-MM-DD HH24:MI:SS'), coalesce(u.firstname, ''), coalesce(u.lastname, ''), '%s', NULL, w.wid, w.word FROM word w, appuser u WHERE w.cuser = u.uid AND w.ctime BETWEEN '%s' AND '%s' UNION SELECT u.uname, to_char(e.etime, 'YYYY-MM-DD HH24:MI:SS'), coalesce(u.firstname, ''), coalesce(u.lastname, ''), e.message, e.comment, w.wid, w.word FROM appuser u, event e, word w WHERE u.uid = e.euser AND e.eword = w.wid AND e.etime BETWEEN '%s' AND '%s' ORDER BY 2 DESC""" % (_(u'Word created').encode('UTF-8'), sdate_s, edate_s, sdate_s, edate_s)); if results.ntuples() > 1000: jotools.write(req, u'<p>%s</p>' % _(u'Too many changes, use narrower date interval.')) joheaders.page_footer_plain(req) return '\n' retstr = u'' for result in results.getresult(): wordlink = u'<a href="../word/edit?wid=%i">%s</a>' \ % (result[6], jotools.escape_html(unicode(result[7], 'UTF-8'))) date = result[1] user = jotools.escape_html(unicode(result[2], 'UTF-8')) + u" " + \ jotools.escape_html(unicode(result[3], 'UTF-8')) + u" (" + \ jotools.escape_html(unicode(result[0], 'UTF-8')) + u")" retstr = retstr + (u'<div class="logitem"><p class="date">%s %s %s</p>\n' \ % (wordlink, user, date)) if result[4] != None: msg = jotools.escape_html(unicode(result[4], 'UTF-8')).strip() msg = msg.replace(u'\n', u'<br />\n') retstr = retstr + u'<p class="logmsg">%s</p>\n' % msg if result[5] != None: comment = jotools.escape_html(unicode(result[5], 'UTF-8')).strip() comment = comment.replace(u'\n', u'<br />\n') comment = jotools.comment_links(comment) retstr = retstr + u'<p class="comment">%s</p>\n' % comment retstr = retstr + u"</div>\n" jotools.write(req, retstr) joheaders.page_footer_plain(req) return '\n'
def ok_page(req, message): page_header_nonavbar(req, u'Joukahainen: %s' % _(u'operation succeeded')) jotools.write(req, u'<h1>%s</h1><p>%s</p>\n' % (_(u'operation succeeded'), message)) jotools.write(req, u'<p><a href="%s">%s ...</a></p>\n' \ % (_config.WWW_ROOT_DIR + '/', _(u'Back to front page'))) page_footer_plain(req)
def error_page(req, errortext): page_header_nonavbar(req, u'Joukahainen: %s' % _(u'error')) jotools.write(req, u'<h1>%s</h1><p>%s</p>\n' % (_(u'Error'), errortext)) page_footer_plain(req)
def redirect_header(req, location): location_s = location.encode('UTF-8') req.headers_out['location'] = location_s req.status = mod_python.apache.HTTP_MOVED_TEMPORARILY req.send_http_header() jotools.write(req, _(u"Redirecting to %s") % location_s)
def classlist(req): (uid, uname, editable) = jotools.get_login_user(req) joheaders.page_header_navbar_level1(req, u'Etsi sanalle taivutusluokka', uid, uname) word = jotools.get_param(req, 'word', u'') if not jotools.checkword(word): joheaders.error_page(req, u'Sanassa on kiellettyjä merkkejä') return '\n' # Sanaa ei annettu, joten näytetään pelkkä lomake if len(word) == 0: _display_form(req, 1, u'-', u'') joheaders.page_footer_plain(req) return '\n' classid = jotools.toint(jotools.get_param(req, 'class', u'0')) if classid == 1: classdatafile = VOIKKO_DATA + "/subst.aff" elif classid == 3: classdatafile = VOIKKO_DATA + "/verb.aff" elif classid == 0: joheaders.page_footer_plain(req) return '\n' else: joheaders.error_page(req, u'Sanaluokkaa ei ole olemassa') return '\n' grad_type = jotools.get_param(req, 'gclass', u'-') if not grad_type in [u'-', u'av1', u'av2', u'av3', u'av4', u'av5', u'av6']: joheaders.error_page(req, u'Taivutusluokkaa ei ole olemassa') return '\n' if grad_type == u'-': grad_type_s = u'' else: grad_type_s = u'-' + grad_type _display_form(req, classid, grad_type, word) word_classes = voikkoinfl.readInflectionTypes(classdatafile) for word_class in word_classes: if len(word_class.joukahainenClasses) == 0: continue infclass_main = word_class.joukahainenClasses[0] inflected_words = voikkoinfl.inflectWordWithType(word, word_class, infclass_main, grad_type) if inflected_words == []: continue previous_inflected = voikkoinfl.InflectedWord() inflist = [] inflected_words.append(voikkoinfl.InflectedWord()) jotools.write(req, '<hr /><h2 class="infclass">' + infclass_main + grad_type_s + '</h2>') if word_class.note != u'': jotools.write(req, u'<p>%s</p>\n' % word_class.note) jotools.write(req, u'<p>Kotus-luokka: %s</p>' % \ reduce(lambda x, y: u"%s, %s" % (x, y), word_class.kotusClasses)) jotools.write(req, u'<table class="border">\n') for inflected_word in inflected_words: if previous_inflected.formName != inflected_word.formName: if previous_inflected.formName != u"" and len(inflist) > 0: if previous_inflected.isCharacteristic: infs = reduce(lambda x, y: u"%s, %s" % (x, y), inflist) jotools.write(req, (u"<tr><td>%s</td><td>%s</td></tr>\n" % (previous_inflected.formName, infs))) inflist = [] previous_inflected = inflected_word if not inflected_word.inflectedWord in inflist: inflist.append(inflected_word.inflectedWord) jotools.write(req, u'</table>\n') joheaders.page_footer_plain(req) return '\n'
def rwords(req, wid = None): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' if wid == None: joheaders.error_page(req, _(u'Parameter %s is required') % u'wid') return '\n' wid_n = jotools.toint(wid) db = jodb.connect() results = db.query("select word, class from word where wid = %i" % wid_n) if results.ntuples() == 0: joheaders.error_page(req, _(u'Word %i does not exist') % wid_n) return '\n' wordinfo = results.getresult()[0] if req.method == 'GET': # show editor word = unicode(wordinfo[0], 'UTF-8') classid = wordinfo[1] title1 = _(u'Word') + u': ' + word link1 = u'edit?wid=%i' % wid_n title2 = _(u'related words') joheaders.page_header_navbar_level2(req, title1, link1, title2, uid, uname, wid_n) jotools.write(req, u'<p>%s</p>\n' % joeditors.call(db, u'word_class', [classid])) jotools.write(req, joeditors.call(db, u'rwords_edit_form', [wid_n])) joheaders.page_footer_plain(req) return '\n' if req.method != 'POST': joheaders.error_page(req, _(u'Only GET and POST requests are allowed')) return '\n' db.query("begin") rword_results = db.query("SELECT rwid, related_word FROM related_word WHERE wid = %i" % wid_n) rword_res = rword_results.getresult() eid = db.query("select nextval('event_eid_seq')").getresult()[0][0] event_inserted = False messages = [] for attribute in rword_res: html_att = 'rword%i' % attribute[0] if jotools.get_param(req, html_att, u'') == u'on': remove = True else: remove = False if not remove: continue if not event_inserted: db.query("insert into event(eid, eword, euser) values(%i, %i, %i)" % \ (eid, wid_n, uid)) event_inserted = True db.query("delete from related_word where wid = %i and rwid = %i" \ % (wid_n, attribute[0])) messages.append(_(u"Alternative spelling removed: '%s'") \ % jotools.escape_html(unicode(attribute[1], 'UTF-8'))) newwords = jotools.get_param(req, 'add', u'') for word in jotools.unique(newwords.split()): if not jotools.checkword(word): continue already_listed = False for attribute in rword_res: if word == unicode(attribute[1], 'UTF-8'): already_listed = True break if already_listed: continue if not event_inserted: db.query("insert into event(eid, eword, euser) values(%i, %i, %i)" % \ (eid, wid_n, uid)) event_inserted = True db.query("insert into related_word(wid, eevent, related_word) values(%i, %i, '%s')" \ % (wid_n, eid, jotools.escape_sql_string(word))) messages.append(_(u"Alternative spelling added: '%s'") % jotools.escape_html(word)) comment = jotools.get_param(req, 'comment', u'') if comment != u'': if not event_inserted: db.query("insert into event(eid, eword, euser) values(%i, %i, %i)" % \ (eid, wid_n, uid)) event_inserted = True db.query("update event set comment = '%s' where eid = %i" \ % (jotools.escape_sql_string(comment), eid)) if event_inserted and len(messages) > 0: mess_str = jotools.escape_sql_string(reduce(lambda x, y: x + u"\n" + y, messages, u"")) db.query("update event set message = '%s' where eid = %i" % (mess_str, eid)) db.query("commit") joheaders.redirect_header(req, u'edit?wid=%i' % wid_n) return '\n'
def _display_form(req, classid, grad_type, word): jotools.write(req, u''' <div class="rightinfo"> <h2>Astevaihteluluokat</h2> <p>Vastaavat Kotus-astevaihteluluokat suluissa luokan nimen perässä. Joukahaisen astevaihteluluokista parittomissa sanan perusmuoto on vahva-asteinen, parillisissa heikkoasteinen.</p> <dl> <dt>av1 (A, B, C, E, F, G, H, I, J, K, M)</dt><dd> tt->t: ma<em>tt</em>o->ma<em>t</em>on<br /> pp->p: kaa<em>pp</em>i->kaa<em>p</em>in<br /> kk->k: ruu<em>kk</em>u->ruu<em>k</em>un<br /> mp->mm: so<em>mp</em>a->so<em>mm</em>an<br /> p->v: ta<em>p</em>a->ta<em>v</em>an<br /> nt->nn: ku<em>nt</em>a->ku<em>nn</em>an<br /> lt->ll: ki<em>lt</em>a->ki<em>ll</em>an<br /> rt->rr: ke<em>rt</em>a->ke<em>rr</em>an<br /> t->d: pöy<em>t</em>ä->pöy<em>d</em>än<br /> nk->ng: ha<em>nk</em>o->ha<em>ng</em>on<br /> uku->uvu: p<em>uku</em>->p<em>uvu</em>n<br /> yky->yvy: k<em>yky</em>->k<em>yvy</em>n </dd> <dt>av2 (A, B, C, E, F, G, H, I, J, K)</dt><dd> t->tt: rii<em>t</em>e->rii<em>tt</em>een<br /> p->pp: o<em>p</em>as->o<em>pp</em>aan<br /> k->kk: lii<em>k</em>e->lii<em>kk</em>een<br /> mm->mp: lu<em>mm</em>e->lu<em>mp</em>een<br /> v->p: tar<em>v</em>e->tar<em>p</em>een<br /> nn->nt: ra<em>nn</em>e->ra<em>nt</em>een<br /> ll->lt: sive<em>ll</em>in->sive<em>lt</em>imen<br /> rr->rt: va<em>rr</em>as->va<em>rt</em>aan<br /> d->t: sa<em>d</em>e->sa<em>t</em>een<br /> ng->nk: ka<em>ng</em>as->ka<em>nk</em>aan<br /> b->bb: lo<em>b</em>ata->lo<em>bb</em>aan<br /> g->gg: di<em>g</em>ata->di<em>gg</em>aan </dd> <dt>av3 (L)</dt><dd> k->j: jär<em>k</em>i->jär<em>j</em>en </dd> <dt>av4 (L)</dt><dd> j->k: pal<em>j</em>e->pal<em>k</em>een </dd> <dt>av5 (D)</dt><dd> k->∅: vuo<em>k</em>a->vuoan </dd> <dt>av6 (D)</dt><dd> ∅->k: säie->säi<em>k</em>een </dd> </dl> </div> <form method="get" action="classlist"><p> <label>Sana: <input type="text" name="word" value="%s"/></label><br /> <label>Sanaluokka: <select name="class">''' % word) if classid == 3: jotools.write(req, u''' <option value="1">Nomini</option> <option selected="selected" value="3">Verbi</option>''') else: jotools.write(req, u''' <option selected="selected" value="1">Nomini</option> <option value="3">Verbi</option>''') jotools.write(req, u''' </select></label><br /> <label>Astevaihteluluokka: <select name="gclass">''') if grad_type == u'-': jotools.write(req, u'<option selected="selected" value="-">ei astevaihtelua</option>') else: jotools.write(req, u'<option value="-">ei astevaihtelua</option>') for i in range(1, 7): if grad_type == (u'av%i' % i): jotools.write(req, u'<option selected="selected" ' \ + (u'value="av%i">av%i</option>' % (i, i))) else: jotools.write(req, u'<option value="av%i">av%i</option>' % (i, i)) jotools.write(req, u''' </select></label><br /> <input type="submit" value="Hae mahdolliset taivutukset" /></p> </form>''')
def add(req): (uid, uname, editable) = jotools.get_login_user(req) if not editable: joheaders.error_page(req, _(u'You are not allowed to edit data')) return '\n' db = jodb.connect() if req.method != 'POST': joheaders.error_page(req, _(u'Only POST requests are allowed')) return '\n' db.query("BEGIN") if jotools.get_param(req, 'confirm', u'') == u'on': confirm = True else: confirm = False nwordlist = [] added_count = 0 need_confirm_count = 0 i = -1 while True: i = i + 1 nword = jotools.get_param(req, 'word%i' % i, u'') if nword == u'': break word = {'word': nword, 'try_again': True, 'confirmed': False, 'wid': None} word['oword'] = jotools.get_param(req, 'origword%i' % i, None) nclass = jotools.get_param(req, 'class%i' % i, None) if not nclass in [None, u'']: nclass = jotools.toint(nclass) else: nclass = None word['cid'] = nclass if confirm and nclass != 0 and jotools.get_param(req, 'confirm%i' % i, u'') != u'on': word['error'] = _(u'Word was not added') word['try_again'] = False if jotools.get_param(req, 'confirm%i' % i, u'') == u'on': word['confirmed'] = True stored_word = _store_word(db, word, uid) if stored_word['wid'] != None: added_count = added_count + 1 if stored_word['try_again']: need_confirm_count = need_confirm_count + 1 nwordlist.append(stored_word) db.query("COMMIT") if added_count == 1 and len(nwordlist) == 1: # No confirmation screen if exactly 1 word was successfully added joheaders.redirect_header(req, "edit?wid=%i" % nwordlist[0]['wid']) return '\n' joheaders.page_header_navbar_level1(req, _(u"Add words"), uid, uname) if need_confirm_count > 0: jotools.write(req, u'<p>' + _(u'''Adding some words failed or requires confirmation. Make the required changes and mark the words that you still want to add.''') + u'</p>') jotools.write(req, u'<form method="post" action="add">\n') jotools.write(req, u'<table class="border"><tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n' \ % (_(u'Word'), _(u'Word class'), _(u'Confirm addition'), _(u'Notes'))) _add_entry_fields(req, db, nwordlist, None) jotools.write(req, u'</table>\n<p>' + u'<input type="hidden" name="confirm" value="on">' + u'<input type="submit" value="%s"></p></form>\n' % _(u'Continue')) joheaders.page_footer_plain(req) return '\n' else: jotools.write(req, u'<p>%s:</p>' % _(u'The following changes were made')) jotools.write(req, u'<table class="border"><tr><th>%s</th><th>%s</th><th>%s</th></tr>\n' \ % (_(u'Word'), _(u'Word class'), _(u'Notes'))) _add_entry_fields(req, db, nwordlist, None) jotools.write(req, u'</table>\n') jotools.write(req, u'<p><a href="../">%s ...</a></p>\n' \ % _(u'Back to main page')) joheaders.page_footer_plain(req) return '\n'