drime

French rhyme dictionary with web and CLI interface
git clone https://a3nm.net/git/drime/
Log | Files | Refs | README

commit 8ebd5e335fb5a14f41151b62d057cf456ecc5009
parent da8d869875cac049ed3f6fdba3ac2bcbac9e3624
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Fri, 23 Dec 2011 21:16:31 +0100

minimal webapp

Diffstat:
query.py | 77++++++++++++++++++++++++++++++++++++++++++-----------------------------------
static/main.css | 47+++++++++++++++++++++++++++++++++++++++++++++++
templates/about.html | 40++++++++++++++++++++++++++++++++++++++++
templates/disambig.html | 14++++++++++++++
templates/error.html | 6++++++
templates/notfound.html | 8++++++++
templates/page.html | 36++++++++++++++++++++++++++++++++++++
templates/results.html | 27+++++++++++++++++++++++++++
8 files changed, 220 insertions(+), 35 deletions(-)

diff --git a/query.py b/query.py @@ -8,9 +8,6 @@ import operator PAGESIZE=50 DBPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'db.sqlite') -db = sqlite3.connect(DBPATH) -db.row_factory = sqlite3.Row -cursor = db.cursor() def lcs(x, y): @@ -23,40 +20,49 @@ def lcs(x, y): return i - 1 -def query(word, syll='', genre=True, page=0): - # word => word, phon - word = word.strip().split(' ') - syll = syll.strip() - if word[-1].startswith('[') and word[-1].endswith(']'): - phon = word[-1][1:-1] - word = word[:-1] +def query(q, nsyl='', gender=True, page=0): + if not nsyl: + nsyl = '' + if not q: + raise ValueError + word = q.strip().split(' ') + nsyl = nsyl.strip() + if word[-1].startswith('[') and word[-1].endswith(']'): + phon = word[-1][1:-1] + word = word[:-1] + else: + phon = None + word = ' '.join(word) + if word == '': + word = None + elide = False + if len(nsyl) == 0: + minsyll = None + maxsyll = None + else: + syll = nsyl.split('-') + if syll[-1][-1] == '+': + syll[-1] = syll[-1][:-1] + elide = True else: - phon = None - word = ' '.join(word) - elide = False - if len(syll) == 0: - minsyll = None - maxsyll = None + elide = False + if len(syll) > 2: + raise ValueError + minsyll = int(syll[0]) + if len(syll) == 1: + maxsyll = int(syll[0]) else: - syll = syll.split('-') - if syll[1][-1] == '+': - syll[1] = syll[1][:-1] - elide = True - else: - elide = False - if len(syll) > 2: - raise ValueError - minsyll = int(syll[0]) - if len(syll) == 1: - maxsyll = int(syll[0]) - else: - maxsyll = int(syll[1]) + maxsyll = int(syll[1]) - return do_query(word, phon, minsyll, maxsyll, elide, genre, - page*PAGESIZE, PAGESIZE) + return do_query(word, phon, minsyll, maxsyll, elide, gender, + page*PAGESIZE, PAGESIZE) pass -def do_query(word, phon, minsyll, maxsyll, elide, genre, offset, size): +def do_query(word, phon, minsyll, maxsyll, elide, gender, offset, size): + print ((word, phon, minsyll, maxsyll, elide, gender,)) + db = sqlite3.connect(DBPATH) + db.row_factory = sqlite3.Row + cursor = db.cursor() cursor.execute(''' SELECT t1.freq AS t1_freq, t1.word AS t1_word, @@ -81,9 +87,10 @@ def do_query(word, phon, minsyll, maxsyll, elide, genre, offset, size): minsyll == None, minsyll, maxsyll == None, maxsyll, maxsyll,)) result = {} for x in cursor: - if x['t1_feminine'] != x['t2_feminine'] and genre: + if x['t1_feminine'] != x['t2_feminine'] and gender: continue - key = (x['t1_word'], x['t1_phon'], x['t1_freq']) + key = (x['t1_word'], x['t1_phon'], + x['t1_word'] + ' [' + x['t1_phon'] + ']') if key not in result.keys(): result[key] = [] row = dict([ @@ -101,7 +108,7 @@ def do_query(word, phon, minsyll, maxsyll, elide, genre, offset, size): result[key].append(row) for k in result.keys(): result[k] = sorted(result[k], key=operator.itemgetter('key')) - + print(result) return result if __name__ == '__main__': diff --git a/static/main.css b/static/main.css @@ -0,0 +1,47 @@ +h1 { + background: #0c0; + float: left; + margin: 0; + margin-right: 1em; + font-size: 150%; +} + +#body { + padding: 1em; +} + +h1 a { + color: white; + text-decoration: none; +} + +header { + background: black; + overflow: auto; +} + +#about a { + float: right; + color: #0c0; +} + +body { + margin: 0; + padding: 0; +} + +.redundant { + display: none; +} + +label { + color: white; +} + +.num { + text-align: center; +} + +table { + width: 100%; +} diff --git a/templates/about.html b/templates/about.html @@ -0,0 +1,40 @@ +{% extends "page.html" %} + +{% block body %} +TODO move this to / +<h2 id="info">What is this?</h2> +<p>This is drime, <a href="http://a3nm.net">a3nm</a>'s attempt to build a better +French rhyme dictionary. It uses the <a + href="http://www.lexique.org/">Lexique</a> database with some customisations, +and is powered by Python, Sqlite and Flask. You can get the code. TODO +links.</p> +<h2 id="help">How do I use it?</h2> +<p>In the <strong>word</strong> field, enter the word you want to get rhymes +for. Inferring pronunciation of unknown words isn't supported (yet), so don't +use proper nouns or rare words. You can also provide a pronunciation written +between square brackets using <a href="#pron">the right convention</a> to +disambiguate if multiple pronunciations are possible. Example: <a + href="/?query=fils%20[fis]">fils [fis]</a>.</p> +<p>In the <strong>n_syllabes</strong> field, you can specify a number of +syllabes to limit on. You can either specify an exact number or a range (eg. +"1-3"). You can suffix a "+" to indicate that you can accept one syllabe more if +the word could cause an elision in the previous word. TODO ref. The syllabe +counts for words are approximate: the system will always overapproximate your +query.</p> +<p>The checkbox limits to rhymes that respect rhyme gender. If you're unsure +about what this is, see <a + href="https://fr.wikipedia.org/wiki/Rime#Genre_des_rimes_:_rimes_f.C3.A9minines_et_masculines">the + relevant Wikipedia page (in French)</a>.</p> +<p>The system will ask you to select the exact word and pronunciation in case of +doubt. Results will then be provided.</p> + +<h2>How are results sorted?</h2> +<p>Results favor, in this order, the number of common phonemes, the number of +common letters, and the frequency of the word.</p> + +TODO more info about missing/redundant results + +<h2 id="pron">How is pronunciation written?</h2> +<p>TODO</p> +{% endblock %} + diff --git a/templates/disambig.html b/templates/disambig.html @@ -0,0 +1,14 @@ +{% extends "page.html" %} + +{% block body %} +<p>Did you mean:</p> +TODO include indications +TODO keep the other GET params +<ul> +{% for k in keys %} +<li><a href="?query={{ k[-1] }}">{{ k[-1] }}</a></li> +{% endfor %} +</ul> + +{% endblock %} + diff --git a/templates/error.html b/templates/error.html @@ -0,0 +1,6 @@ +{% extends "page.html" %} + +{% block body %} +<p>Invalid values supplied. Need some <a href="about#help">help</a>?</p> +{% endblock %} + diff --git a/templates/notfound.html b/templates/notfound.html @@ -0,0 +1,8 @@ +{% extends "page.html" %} + +{% block body %} +<p>No known word matches this query. Make sure you're using a word from the +dictionary. Remove syllabe count restrictions, if any. Need some <a + href="about#help">help</a>?</p> +{% endblock %} + diff --git a/templates/page.html b/templates/page.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html dir="ltr" lang="en-US"> + <head> + <title>{{ title }}</title> + <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> + <meta name="description" content="drime rhyme dictionary" /> + <link rel="stylesheet" href="static/main.css" type="text/css" media="screen" /> + </head> + <body> + <header> + <h1><a href="/">drime</a></h1> + <div id="about"><a href="about">about</a></div> + <form method="GET" action="query"> + <label class="redundant" for="query">Word</label> + <input id="query" name="query" + placeholder="word" + value="{{ q }}"/> + <label class="redundant" for="nsyl">Number of syllabes</label> + <input id="nsyl" name="nsyl" + placeholder="n_syllabes" + value="{{ nsyl }}"/> + <input type="checkbox" id="gender" name="gender" + {% if gender %} + checked="{{ gender }}" + {% endif %} + /> + <label for="gender">Respect gender?</label> + <input type="submit" /> + </form> + </header> + <div id="body"> + {% block body %} + {% endblock %} + </div> + </body> +</html> diff --git a/templates/results.html b/templates/results.html @@ -0,0 +1,27 @@ +{% extends "page.html" %} + +{% block body %} +<table> + <tr> + <th>word</th> + <th>pron<a href="about/#pron" class="help">?</a></th> + <th>phon</th> + <th>eye</th> + <th>kind</th> + <th>base</th> + <th>freq</th> +{% for r in result %} +<tr> + <td>{{ r.word }}</td> + <td>{{ r.phon }}</td> + <td class="num">{{ r.phon_rhyme }}</td> + <td class="num">{{ r.word_rhyme }}</td> + <td class="num">{{ r.kind }}</td> + <td>{{ r.base }}</td> + <td class="num">{{ r.freq }}</td> +</tr> +{% endfor %} +</table> + +{% endblock %} +