Add basic image support.

This commit is contained in:
Flancian 2021-01-10 20:59:07 +01:00
parent cfd33a3f58
commit f02373601b
6 changed files with 52 additions and 28 deletions

View File

@ -188,14 +188,10 @@ def asset(user, asset):
path = '/'.join(["garden", user, 'assets', asset])
return current_app.send_static_file(path)
@bp.route('/raw/<node>')
def raw(node):
# Currently unused.
# hack hack
# outlinks
return Response("\n\n".join([str(n.outlinks) for n in db.nodes_by_wikilink(node)]), mimetype="text/plain")
# content
# return Response("\n\n".join([n.content for n in db.nodes_by_wikilink(node)]), mimetype="text/plain")
@bp.route('/raw/<path:subnode>')
def raw(subnode):
s = db.subnode_by_uri(subnode)
return Response(s.content, mimetype=s.mediatype)
@bp.route('/backlinks/<node>')
def backlinks(node):

View File

@ -88,8 +88,14 @@ class Graph:
# does this belong here?
@cachetools.func.ttl_cache(maxsize=1, ttl=20)
def subnodes(self, sort=lambda x: x.uri.lower()):
# Markdown.
subnodes = [Subnode(f) for f in glob.glob(os.path.join(config.AGORA_PATH, '**/*.md'), recursive=True)]
# Org mode.
subnodes.extend([Subnode(f) for f in glob.glob(os.path.join(config.AGORA_PATH, '**/*.org'), recursive=True)])
# Image formats.
subnodes.extend([Subnode(f, mediatype='image/jpg') for f in glob.glob(os.path.join(config.AGORA_PATH, '**/*.jpg'), recursive=True)])
subnodes.extend([Subnode(f, mediatype='image/png') for f in glob.glob(os.path.join(config.AGORA_PATH, '**/*.png'), recursive=True)])
subnodes.extend([Subnode(f, mediatype='image/gif') for f in glob.glob(os.path.join(config.AGORA_PATH, '**/*.gif'), recursive=True)])
if sort:
return sorted(subnodes, key=sort)
else:
@ -188,7 +194,7 @@ class Subnode:
"""A subnode is a note or media resource volunteered by a user of the Agora.
It maps to a particular file in the Agora repository, stored (relative to
the Agora root) in the attribute 'uri'."""
def __init__(self, path):
def __init__(self, path, mediatype='text/plain'):
# Use a subnode's URI as its identifier.
self.uri = path_to_uri(path)
self.url = '/subnode/' + path_to_uri(path)
@ -196,10 +202,20 @@ class Subnode:
# i.e. if two users contribute subnodes titled [[foo]], they both show up when querying node [[foo]].
self.wikilink = util.canonical_wikilink(path_to_wikilink(path))
self.user = path_to_user(path)
with open(path) as f:
self.content = f.read()
self.mediatype = mediatype
if self.mediatype == 'text/plain':
with open(path) as f:
self.content = f.read()
self.forward_links = content_to_forward_links(self.content)
elif self.mediatype.startswith('image'):
with open(path, 'rb') as f:
self.content = f.read()
self.forward_links = []
else:
raise ValueError
self.mtime = os.path.getmtime(path)
self.forward_links = content_to_forward_links(self.content)
self.node = self.wikilink
# Initiate node for wikilink if this is the first subnode, append otherwise.
# G.addsubnode(self)
@ -220,13 +236,19 @@ class Subnode:
return 100-fuzz.ratio(self.wikilink, other.wikilink)
def render(self):
# hack hack
if self.mediatype != 'text/plain':
# hack hack
#return 'This is a subnode of type {}. You can <a href="/raw/{}">view</a> it.'.format(self.mediatype, self.uri)
return '<br /><img src="/raw/{}" style="display: block; margin-left: auto; margin-right: auto; width: 50%" /> <br />'.format(self.uri)
if self.uri.endswith('md') or self.uri.endswith('MD'):
content = render.markdown(self.content)
if self.uri.endswith('org') or self.uri.endswith('ORG'):
content = render.orgmode(self.content)
return render.postprocess(content)
def raw(self):
return content
def go(self):
"""
returns a set of go links contained in this subnode
@ -274,6 +296,8 @@ class Subnode:
def subnode_to_actions(subnode, action):
# hack hack.
if subnode.mediatype != 'text/plain':
return []
action_regex ='\[\[' + action + '\]\] (.*?)$'
content = subnode.content
actions = []
@ -352,11 +376,11 @@ def subnodes_by_wikilink(wikilink, fuzzy_matching=True):
return subnodes
def search_subnodes(query):
subnodes = [subnode for subnode in G.subnodes() if re.search(query, subnode.content, re.IGNORECASE)]
subnodes = [subnode for subnode in G.subnodes() if subnode.mediatype == 'text/plain' and re.search(query, subnode.content, re.IGNORECASE)]
return subnodes
def search_subnodes_by_user(query, user):
subnodes = [subnode for subnode in G.subnodes() if re.search(query, subnode.content, re.IGNORECASE) and subnode.user == user]
subnodes = [subnode for subnode in G.subnodes() if subnode.mediatype == 'text/plain' and subnode.user == user and re.search(query, subnode.content, re.IGNORECASE)]
return subnodes
def subnodes_by_user(user):
@ -366,7 +390,7 @@ def subnodes_by_user(user):
def user_readmes(user):
# hack hack
# fix duplication.
subnodes = [subnode for subnode in G.subnodes() if subnode.user == user and re.search('readme', subnode.wikilink, re.IGNORECASE)]
subnodes = [subnode for subnode in G.subnodes() if subnode.mediatype == 'text/plain' and subnode.user == user and re.search('readme', subnode.wikilink, re.IGNORECASE)]
return subnodes
def subnode_by_uri(uri):

View File

@ -80,19 +80,24 @@ nav { font-family: sans-serif}
.subnode-header {
font-style: italic;
width: 100%;
margin-bottom: 10px;
border-radius: 10px;
display: inline-block;
}
.subnode-footer {
font-style: italic;
width: 100%;
background: #2f2f2f;
color: #cfcfcf;
margin-bottom: 10px;
border-radius: 10px;
}
.subnode-id {
float: left;
}
.subnode-links {
float: right;
}
.links {

View File

@ -27,7 +27,7 @@
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/screen-dark.css')}}" id="theme-link" />
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='css/screen-dark.css')}}?uncached2" id="theme-link" />
<script type=text/javascript src="{{url_for('static', filename='js/main.js')}}"></script>
<!-- considering this way of integrating hypothesis, although I like "standard" (sidebar) mode.
<script type="application/json" class="js-hypothesis-config">

View File

@ -34,10 +34,9 @@ Try listing all <a href="/nodes">nodes</a> or perhaps <a href="/search">search</
{% for subnode in node.subnodes %}
<div class="subnode">
<div class="subnode-header">
<span class="subnode-id"><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span>
<span class="subnode-links">by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
<span class="subnode-id"><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span><br />
<span class="subnode-links"><strong>from</strong> <a href="/raw/{{subnode.uri}}">{{subnode.uri}}</a> by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
</div>
<br />
{{ subnode.render()|linkify|safe }}
</div>
{% endfor %}
@ -51,10 +50,9 @@ Try listing all <a href="/nodes">nodes</a> or perhaps <a href="/search">search</
{% for subnode in node.subnodes %}
<div class="subnode">
<div class="subnode-header">
<span class="subnode-id"><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span>
<span class="subnode-links">by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
<span class="subnode-id"><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span><br />
<span class="subnode-links"><strong>from</strong> <a href="/raw/{{subnode.uri}}">{{subnode.uri}}</a> by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
</div>
<br />
{{ subnode.render()|linkify|safe }}
</div>
{% endfor %}

View File

@ -30,9 +30,10 @@ Try going up to node <a href="/node/{{node.uri}}">[[{{node.uri}}]]</a> or perhap
{% for subnode in node.subnodes %}
<div class="subnode">
<div class="subnode-header">
<span><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span> in <strong>node</strong> <a href="/node/{{subnode.wikilink}}">[[{{subnode.wikilink}}]]</a></span>
<span class="subnode-links">by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
<br />
<span><strong>Subnode</strong> <a href="/@{{subnode.user}}/{{node.uri}}">[[@{{subnode.user}}/{{node.uri}}]]</a></span> in <strong>node</strong> <a href="/node/{{subnode.wikilink}}">[[{{subnode.wikilink}}]]</a></span><br />
<span class="subnode-links"><strong>from</strong> <a href="/raw/{{subnode.uri}}">{{subnode.uri}}</a> by <a href="/@{{subnode.user}}">@{{subnode.user}}</a></span>
</div>
{{ subnode.render()|linkify|safe }}
</div>