Controllers¶
The controllers can be grouped as follows.
Default¶
controllers.default
¶
EXPIRE
¶
auth
¶
cache
¶
Dummy
¶
Source code in controllers/default.py
class Dummy:
def action(self):
return lambda f: f
def requires_signature(self):
return lambda f: f
index()
¶
Serves the home page.
Corresponds with the SHEBANQ logo in the navigation bar.
Source code in controllers/default.py
def index():
"""Serves the **home** page.
Corresponds with the SHEBANQ logo in the navigation bar.
"""
session.forget(response)
response.title = T("SHEBANQ")
response.subtitle = T("Query the Hebrew Bible through the BHSA database")
return dict()
user()
¶
Unchanged from web2py.
exposes:
http://..../[app]/default/user/login
http://..../[app]/default/user/logout
http://..../[app]/default/user/register
http://..../[app]/default/user/profile
http://..../[app]/default/user/retrieve_password
http://..../[app]/default/user/change_password
http://..../[app]/default/user/manage_users (requires membership in
use @auth.requires_login()
@auth.requires_membership('group name')
@auth.requires_permission('read','table name',record_id)
to decorate functions that need access control
Source code in controllers/default.py
def user():
"""Unchanged from web2py.
```
exposes:
http://..../[app]/default/user/login
http://..../[app]/default/user/logout
http://..../[app]/default/user/register
http://..../[app]/default/user/profile
http://..../[app]/default/user/retrieve_password
http://..../[app]/default/user/change_password
http://..../[app]/default/user/manage_users (requires membership in
use @auth.requires_login()
@auth.requires_membership('group name')
@auth.requires_permission('read','table name',record_id)
to decorate functions that need access control
```
"""
response.title = T("User Profile")
return dict(form=auth())
download()
¶
Unchanged from web2py.
allows downloading of uploaded files
http://..../[app]/default/download/[filename]
Source code in controllers/default.py
@cache.action()
def download():
"""Unchanged from web2py.
```
allows downloading of uploaded files
http://..../[app]/default/download/[filename]
```
"""
return response.download(request, db)
call()
¶
Unchanged from web2py.
exposes services. for example:
http://..../[app]/default/call/jsonrpc
decorate with @services.jsonrpc the functions to expose
supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv
Source code in controllers/default.py
def call():
"""Unchanged from web2py.
```
exposes services. for example:
http://..../[app]/default/call/jsonrpc
decorate with @services.jsonrpc the functions to expose
supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv
```
"""
return service() # noqa F821
data()
¶
Unchanged from web2py.
http://..../[app]/default/data/tables
http://..../[app]/default/data/create/[table]
http://..../[app]/default/data/read/[table]/[id]
http://..../[app]/default/data/update/[table]/[id]
http://..../[app]/default/data/delete/[table]/[id]
http://..../[app]/default/data/select/[table]
http://..../[app]/default/data/search/[table]
but URLs must be signed, i.e. linked with
A('table',_href=URL('data/tables',user_signature=True))
or with the signed load operator
LOAD('default','data.load',args='tables',ajax=True,user_signature=True)
Source code in controllers/default.py
@auth.requires_signature()
def data():
"""Unchanged from web2py.
```
http://..../[app]/default/data/tables
http://..../[app]/default/data/create/[table]
http://..../[app]/default/data/read/[table]/[id]
http://..../[app]/default/data/update/[table]/[id]
http://..../[app]/default/data/delete/[table]/[id]
http://..../[app]/default/data/select/[table]
http://..../[app]/default/data/search/[table]
but URLs must be signed, i.e. linked with
A('table',_href=URL('data/tables',user_signature=True))
or with the signed load operator
LOAD('default','data.load',args='tables',ajax=True,user_signature=True)
```
"""
return dict(form=crud()) # noqa F821
Feed¶
controllers.feed
¶
atom()
¶
Serves an RSS feed of recently saved shared queries.
See also M:QUERYRECENT.
Source code in controllers/feed.py
def atom():
"""Serves an RSS feed of recently saved shared queries.
See also [M:QUERYRECENT][queryrecent.QUERYRECENT].
"""
session.forget(response)
U = Urls()
QueryRecent = QUERYRECENT()
queries = QueryRecent.feed()
icon = URL("static", "images/shebanq_logo_xxsmall.png", host=True)
cover = URL("static", "images/shebanq_cover.png", host=True)
base = URL("xxx", "yyy", host=True, extension="")[0:-8]
feed = URL("feed", "atom", host=True, extension="")
xml = []
xml.append(
"""<?xml version="1.0" encoding="utf-8"?>
"""
)
xml.append(
dedent(
"""
<feed
xmlns="http://www.w3.org/2005/Atom"
xmlns:webfeeds="http://webfeeds.org/rss/1.0"
>
"""
)
)
xml.append(
dedent(
f"""
<title>SHEBANQ</title>
<subtitle>Shared queries, recently executed</subtitle>
<link href="{hEsc(feed)}" rel="self"
title="SHEBANQ - Shared Queries" type="application/atom+xml"/>
<link href="{hEsc(base)}" rel="alternate" type="text/html"/>
<id>{hEsc(base + "/hebrew/queries")}</id>
<updated>{isodt()}</updated>
<category term="bible study"/>
<category term="biblical studies"/>
<category term="text"/>
<category term="linguistic"/>
<category term="hebrew"/>
<category term="bible"/>
<category term="query"/>
<category term="database"/>
<category term="research"/>
<category term="scholar"/>
<category term="annotation"/>
<category term="digital bible"/>
<category term="digital"/>
<category term="religion"/>
<category term="theology"/>
<icon>{hEsc(icon)}</icon>
<webfeeds:icon>{hEsc(icon)}</webfeeds:icon>
<logo>{hEsc(cover)}</logo>
<webfeeds:cover image="{hEsc(cover)}"/>
<webfeeds:accentColor>DDBB00</webfeeds:accentColor>
"""
)
)
for (
query_id,
first_name,
last_name,
query_name,
description,
qvid,
qexe,
qver,
) in queries:
descHtml = U.specialLinks(
sanitize(
markdown(
hEsc(description or "No description given"), output_format="xhtml5"
)
)
)
# we add a standard cover image if the description does not contain any image
standardImage = (
f"""<p><img src="{cover}"/></p>""" if "<img " not in descHtml else ""
)
href = hEsc(
URL(
"hebrew",
"query",
vars=dict(id=query_id, version=qver),
host=True,
extension="",
)
)
tag = f"tag:shebanq.ancient-data.org,2016-01-01:{query_id}/{qvid}/{qver}"
name = hEsc(f"{first_name} {last_name}")
xml.append(
dedent(
f"""
<entry>
<title>{hEsc(query_name)}</title>
<link href="{href}" rel="alternate" type="text/html"/>
<id>{tag}</id>
<updated>{isodt(qexe)}</updated>
<category term="query"/>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
{standardImage}
{descHtml}
</div>
</content>
<author><name>{name}</name></author>
</entry>
"""
)
)
xml.append(
dedent(
"""
</feed>
"""
)
)
return dict(xml="".join(xml))
Hebrew¶
In hebrew.py.
The significant controllers are all here. Their bodies are very short, because they all call a function from the modules, which does all the work.
The modules are individually documented by docstrings in the code.
controllers.hebrew
¶
init()
¶
Source code in controllers/hebrew.py
def init():
QueryChapter = QUERYCHAPTER()
QueryChapter.makeQCindexes()
books()
¶
Get all bible book names in all their translations.
See also M:BOOKS.getNames.
See ∈ language-info.
Source code in controllers/hebrew.py
def books():
"""Get all bible book names in all their translations.
See also [M:BOOKS.getNames][books.BOOKS.getNames].
See [∈ language-info][elem-language-info].
"""
Books = BOOKS()
session.forget(response)
return Books.getNames()
text()
¶
Serves a text page.
Corresponds with Text
in the menu bar.
Only the skeleton of the page is fetched.
See also M:VIEWSETTINGS.page.
Source code in controllers/hebrew.py
def text():
"""Serves a **text** page.
Corresponds with `Text` in the menu bar.
Only the skeleton of the page is fetched.
See also [M:VIEWSETTINGS.page][viewsettings.VIEWSETTINGS.page].
"""
session.forget(response)
init()
Books = BOOKS()
ViewSettings = VIEWSETTINGS(Books)
ViewSettings.initState()
return ViewSettings.page()
words()
¶
Serves words overview pages.
Corresponds with Words
in the menu bar.
The words are fetched in pages off all words starting with the same letter.
Source code in controllers/hebrew.py
def words():
"""Serves **words** overview pages.
Corresponds with `Words` in the menu bar.
The words are fetched in pages off all words starting with the same letter.
"""
session.forget(response)
init()
Books = BOOKS()
ViewSettings = VIEWSETTINGS(Books)
ViewSettings.initState()
Word = WORD()
return Word.page(ViewSettings)
queries()
¶
Serves the queries overview page.
Corresponds with Queries
in the menu bar.
The main part is the tree of queries. There is also a widget with recent queries and a control to add new queries.
Source code in controllers/hebrew.py
def queries():
"""Serves the **queries** overview page.
Corresponds with `Queries` in the menu bar.
The main part is the tree of queries.
There is also a widget with recent queries and a control to add new queries.
"""
session.forget(response)
init()
Books = BOOKS()
ViewSettings = VIEWSETTINGS(Books)
ViewSettings.initState()
Query = QUERY()
return Query.page(ViewSettings)
notes()
¶
Serves the notes overview page.
Corresponds with Notes
in the menu bar.
The main part is the tree of note sets. There is also a widget for bulk uploading sets of notes.
Source code in controllers/hebrew.py
def notes():
"""Serves the **notes** overview page.
Corresponds with `Notes` in the menu bar.
The main part is the tree of note sets.
There is also a widget for bulk uploading sets of notes.
"""
session.forget(response)
init()
Books = BOOKS()
ViewSettings = VIEWSETTINGS(Books)
ViewSettings.initState()
Note = NOTE(Books)
return Note.page(ViewSettings)
word()
¶
Serves a word record page.
Usually an overview page or from a shared link.
The page consists of a sidebar with the details of the word, and the main area displays the occurrences.
Source code in controllers/hebrew.py
def word():
"""Serves a *word* **record** page.
Usually an overview page or from a shared link.
The page consists of a sidebar with the details of the word,
and the main area displays the occurrences.
"""
session.forget(response)
request.vars["mr"] = "r"
request.vars["qw"] = "w"
request.vars["page"] = 1
return text()
query()
¶
Serves a query record page.
Usually an overview page or from a shared link.
The page consists of a sidebar with the details of the query, and the main area displays the results.
Source code in controllers/hebrew.py
def query():
"""Serves a *query* **record** page.
Usually an overview page or from a shared link.
The page consists of a sidebar with the details of the query,
and the main area displays the results.
"""
session.forget(response)
request.vars["mr"] = "r"
request.vars["qw"] = "q"
if request.extension == "json":
Query = QUERY()
return Query.bodyJson()
else:
request.vars["page"] = 1
return text()
note()
¶
Serves a notes set record page.
Usually from an overview page or a shared link.
The page consists of a sidebar with the details of the notes set, and the main area displays the notes between the verses.
Source code in controllers/hebrew.py
def note():
"""Serves a *notes set* **record** page.
Usually from an overview page or a shared link.
The page consists of a sidebar with the details of the notes set,
and the main area displays the notes between the verses.
"""
session.forget(response)
request.vars["mr"] = "r"
request.vars["qw"] = "n"
request.vars["page"] = 1
return text()
material()
¶
Serves AJAX call for HTML content for the main area.
Client code: {material.fetch}.
Source code in controllers/hebrew.py
def material():
"""Serves AJAX call for HTML content for the main area.
Client code: [{material.fetch}][materialfetch].
"""
session.forget(response)
Books = BOOKS()
Word = WORD()
Query = QUERY()
Note = NOTE(Books)
RecordQuery = RECORDQUERY(Query)
Material = MATERIAL(RecordQuery, Word, Query, Note)
return Material.page()
verse()
¶
Get the linguistic data of a verse.
See also M:VERSE.get.
Client code: {material.addverserefs}.
Source code in controllers/hebrew.py
def verse():
"""Get the linguistic data of a verse.
See also [M:VERSE.get][verse.VERSE.get].
Client code: [{material.addverserefs}][materialaddverserefs].
"""
session.forget(response)
Verse = VERSE()
return Verse.get()
sidematerial()
¶
Serves AJAX call for HTML content for the sidebar (material page).
Client code: {sidecontent.fetch}.
Source code in controllers/hebrew.py
def sidematerial():
"""Serves AJAX call for HTML content for the sidebar (**material** page).
Client code: [{sidecontent.fetch}][sidecontentfetch].
"""
session.forget(response)
Books = BOOKS()
Word = WORD()
Query = QUERY()
Note = NOTE(Books)
RecordQuery = RECORDQUERY(Query)
Material = MATERIAL(RecordQuery, Word, Query, Note)
Side = SIDE(Material, Word, Query, Note)
return Side.page()
sideword()
¶
Serves AJAX call for HTML content for the sidebar (word record page).
Used when the user is switching between material and record pages.
See also M:RECORD.body.
Client code: {sidecontent.fetch}.
Source code in controllers/hebrew.py
def sideword():
"""Serves AJAX call for HTML content for the sidebar (*word* **record** page).
Used when the user is switching between **material** and **record** pages.
See also [M:RECORD.body][record.RECORD.body].
Client code: [{sidecontent.fetch}][sidecontentfetch].
"""
session.forget(response)
Record = RECORD()
return Record.body()
sidequery()
¶
Serves AJAX call for HTML content for the sidebar (query record page).
Used when the user is switching between material and record pages.
See also M:RECORD.body.
Client code: {sidecontent.fetch}.
Source code in controllers/hebrew.py
def sidequery():
"""Serves AJAX call for HTML content for the sidebar (*query* **record** page).
Used when the user is switching between **material** and **record** pages.
See also [M:RECORD.body][record.RECORD.body].
Client code: [{sidecontent.fetch}][sidecontentfetch].
"""
session.forget(response)
Query = QUERY()
Record = RECORDQUERY(Query)
return Record.body()
sidenote()
¶
Serves AJAX call for HTML content for the sidebar (note set record page).
Used when the user is switching between material and record pages.
See also M:RECORD.body.
Client code: {sidecontent.fetch}.
Source code in controllers/hebrew.py
def sidenote():
"""Serves AJAX call for HTML content for the sidebar (*note set* **record** page).
Used when the user is switching between **material** and **record** pages.
See also [M:RECORD.body][record.RECORD.body].
Client code: [{sidecontent.fetch}][sidecontentfetch].
"""
session.forget(response)
Record = RECORD()
return Record.body()
sidewordbody()
¶
Serves AJAX call for HTML content for the sidebar (word record page).
Used when the user is loading word page directly.
See also M:WORD.body.
Source code in controllers/hebrew.py
def sidewordbody():
"""Serves AJAX call for HTML content for the sidebar (*word* **record** page).
Used when the user is loading *word* page directly.
See also [M:WORD.body][word.WORD.body].
"""
session.forget(response)
if not request.ajax:
redirect(URL("hebrew", "word", extension="", vars=request.vars))
Word = WORD()
return Word.body()
sidequerybody()
¶
Serves AJAX call for HTML content for the sidebar (query record page).
Used when the user is loading a query page directly.
See also M:QUERY.body.
Source code in controllers/hebrew.py
def sidequerybody():
"""Serves AJAX call for HTML content for the sidebar (*query* **record** page).
Used when the user is loading a *query* page directly.
See also [M:QUERY.body][query.QUERY.body].
"""
session.forget(response)
if not request.ajax:
redirect(URL("hebrew", "query", extension="", vars=request.vars))
Query = QUERY()
return Query.body()
sidenotebody()
¶
Serves AJAX call for HTML content for the sidebar (notes set record page).
Used when the user is loading a notes set page directly.
See also M:NOTE.body.
Source code in controllers/hebrew.py
def sidenotebody():
"""Serves AJAX call for HTML content for the sidebar (*notes set* **record** page).
Used when the user is loading a *notes set* page directly.
See also [M:NOTE.body][note.NOTE.body].
"""
session.forget(response)
if not request.ajax:
redirect(URL("hebrew", "note", extension="", vars=request.vars))
Books = BOOKS()
Note = NOTE(Books)
return Note.body()
queriesr()
¶
Serves AJAX call for json data for recently saved shared queries.
See also [queryrecent.QUERYRECENT.recent].
Client code: {queryrecent.fetch}
Source code in controllers/hebrew.py
def queriesr():
"""Serves AJAX call for json data for recently saved shared queries.
See also [queryrecent.QUERYRECENT.recent].
Client code: [{queryrecent.fetch}][queryrecentfetch]
"""
session.forget(response)
QueryRecent = QUERYRECENT()
return QueryRecent.recent()
querytree()
¶
Serves AJAX call for json data for the tree overview of queries.
See also M:QUERYTREE.get.
Client code: {querytree.Tree}
Source code in controllers/hebrew.py
def querytree():
"""Serves AJAX call for json data for the tree overview of queries.
See also [M:QUERYTREE.get][querytree.QUERYTREE.get].
Client code: [{querytree.Tree}][querytreetree]
"""
session.forget(response)
QueryTree = QUERYTREE()
return QueryTree.get()
notetree()
¶
Serves AJAX call for json data for the tree overview of notes sets.
See also M:NOTETREE.get.
Client code: {notetree.Tree}
Source code in controllers/hebrew.py
def notetree():
"""Serves AJAX call for json data for the tree overview of notes sets.
See also [M:NOTETREE.get][notetree.NOTETREE.get].
Client code: [{notetree.Tree}][notetreetree]
"""
session.forget(response)
NoteTree = NOTETREE()
return NoteTree.get()
getversenotes()
¶
Serves AJAX call for json data for all notes belonging to a single verse.
See also M:NOTE.getVerseNotes.
Client code: {noteverse.fetch}
Source code in controllers/hebrew.py
def getversenotes():
"""Serves AJAX call for json data for all notes belonging to a single verse.
See also [M:NOTE.getVerseNotes][note.NOTE.getVerseNotes].
Client code: [{noteverse.fetch}][noteversefetch]
"""
session.forget(response)
Books = BOOKS()
Note = NOTE(Books)
return Note.getVerseNotes()
putversenotes()
¶
Serves AJAX call for json data to save notes.
See also M:NOTESAVE.putVerseNotes.
Client code: {noteverse.sendnotes}
Source code in controllers/hebrew.py
def putversenotes():
"""Serves AJAX call for json data to save notes.
See also [M:NOTESAVE.putVerseNotes][notesave.NOTESAVE.putVerseNotes].
Client code: [{noteverse.sendnotes}][noteversesendnotes]
"""
session.forget(response)
Books = BOOKS()
Note = NOTE(Books)
NoteSave = NOTESAVE(Note)
return NoteSave.putVerseNotes()
noteupload()
¶
Receives bulk-uploaded notes and stores them.
See also M:NOTESUPLOAD.upload.
Client code: {notetree.Upload.submit}.
Source code in controllers/hebrew.py
def noteupload():
"""Receives bulk-uploaded notes and stores them.
See also [M:NOTESUPLOAD.upload][notesupload.NOTESUPLOAD.upload].
Client code: [{notetree.Upload.submit}][uploadsubmit].
"""
session.forget(response)
Books = BOOKS()
Note = NOTE(Books)
NotesUpload = NOTESUPLOAD(Books, Note)
return NotesUpload.upload()
item()
¶
Get csv data of the items associated with a record.
Items are: the occurrences of a word, the results of a query, the notes of a notes set.
See also M:CSVDATA.page.
Client code: {viewstate.csvUrl}.
Source code in controllers/hebrew.py
def item():
"""Get csv data of the items associated with a record.
Items are:
the occurrences of a word, the results of a query, the notes of a notes set.
See also [M:CSVDATA.page][csvdata.CSVDATA.page].
Client code: [{viewstate.csvUrl}][viewstatecsvurl].
"""
session.forget(response)
Word = WORD()
Query = QUERY()
RecordQuery = RECORDQUERY(Query)
CsvData = CSVDATA(RecordQuery, Word, Query)
return CsvData.page()
chart()
¶
Get a heat map of the items associated to a record.
Items are: the occurrences of a word, the results of a query, the notes of a notes set.
See also M:CHART.page.
Client code: {chart.fetch}.
Source code in controllers/hebrew.py
def chart(): # controller to produce a chart of query results or lexeme occurrences
"""Get a heat map of the items associated to a record.
Items are:
the occurrences of a word, the results of a query, the notes of a notes set.
See also [M:CHART.page][chart.CHART.page].
Client code: [{chart.fetch}][chartfetch].
"""
session.forget(response)
Books = BOOKS()
Word = WORD()
Query = QUERY()
Note = NOTE(Books)
RecordQuery = RECORDQUERY(Query)
Chart = CHART(Books, RecordQuery, Word, Query, Note)
return Chart.page()
itemrecord()
¶
Saves a record to the database, typically organizations, projects, queries.
See also M:RECORD.setItem.
Client code: {querytree.Tree.record}.
Source code in controllers/hebrew.py
def itemrecord():
"""Saves a record to the database, typically organizations, projects, queries.
See also [M:RECORD.setItem][record.RECORD.setItem].
Client code: [{querytree.Tree.record}][treerecord].
"""
session.forget(response)
Query = QUERY()
RecordQuery = RECORDQUERY(Query)
return RecordQuery.setItem()
querysharing()
¶
Saves the shared status of a query to the database.
See also M:QUERYSAVE.sharing.
Client code: {sidecontent.sendval}.
Source code in controllers/hebrew.py
def querysharing():
"""Saves the shared status of a query to the database.
See also [M:QUERYSAVE.sharing][querysave.QUERYSAVE.sharing].
Client code: [{sidecontent.sendval}][sidecontentsendval].
"""
session.forget(response)
Query = QUERY()
QueryChapter = QUERYCHAPTER()
QuerySave = QUERYSAVE(Query, QueryChapter)
return QuerySave.sharing()
queryupdate()
¶
Saves metadata of a query to the database.
See also M:QUERYSAVE.putRecord.
Client code: {sidecontent.sendvals}.
Source code in controllers/hebrew.py
def queryupdate():
"""Saves metadata of a query to the database.
See also [M:QUERYSAVE.putRecord][querysave.QUERYSAVE.putRecord].
Client code: [{sidecontent.sendvals}][sidecontentsendvals].
"""
session.forget(response)
Query = QUERY()
QueryChapter = QUERYCHAPTER()
QuerySave = QUERYSAVE(Query, QueryChapter)
return QuerySave.putRecord()