Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.pyc
.not/
.ropeproject/

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Commands:
f # Go forward in history
b # Go back in history
hist # Print history stack.
select # SPARQL SELECT query, example: select distinct ?p where { ?s ?p ?o } order by ?p
help # Print this help.
exit # Exit.

Expand Down
16 changes: 16 additions & 0 deletions rdfcli/controller.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import operator

from history import History

class Controller:
Expand Down Expand Up @@ -129,3 +131,17 @@ def types(self):
def norm(self, ref):
return self.model.norm(ref)

def select(self, query):
cols = None
rows = []
sortkey = operator.itemgetter(1)
for row in self.model.select(query):
values = []
if cols is None:
cols = [
col for col, _ in sorted(row.labels.items(), key=sortkey)
]
for col in cols:
values.append(self.norm(row[col]))
rows.append(values)
return cols, rows
10 changes: 8 additions & 2 deletions rdfcli/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ def get_reverse_properties(self, obj):
return properties

def norm(self, ref):
return self.graph.namespace_manager.normalizeUri(ref) if ref else None
if ref is None:
return None
elif isinstance(ref, URIRef):
return self.graph.namespace_manager.normalizeUri(ref)
else:
return unicode(ref)

def to_uriref(self, string):
"""Expand QName to UriRef based on existing namespaces."""
Expand All @@ -75,4 +80,5 @@ def to_uriref(self, string):
else:
return URIRef(string)


def select(self, query):
return self.graph.query(query)
15 changes: 15 additions & 0 deletions rdfcli/view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pyparsing
from cmd import Cmd
from prettytable import PrettyTable

HELP_MSG = '''
Commands:
Expand All @@ -16,6 +18,7 @@
f # Go forward in history
b # Go back in history
hist # Print history stack.
select # SPARQL SELECT query, example: select distinct ?p where { ?s ?p ?o } order by ?p
help # Print this help.
exit # Exit.
'''
Expand Down Expand Up @@ -148,6 +151,18 @@ def do_types(self, params):
for type_ in types:
print self.__norm(type_)

def do_select(self, params):
try:
cols, rows = self.controller.select('select %s' % params)
except pyparsing.ParseException as e:
print e
else:
table = PrettyTable(cols)
table.align = 'l'
for row in rows:
table.add_row(row)
print table

def __norm(self, ref, trim=False):
res = self.controller.norm(ref)
if trim and res[0] == '<' and res[-1] == '>':
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pyparsing==1.5.7
rdflib==4.0.1
six==1.4.1
wsgiref==0.1.2
prettytable==0.7.2
44 changes: 29 additions & 15 deletions test/test_controller.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

import unittest
from rdflib import Graph
from rdflib.namespace import Namespace, RDF, FOAF
from rdflib.term import URIRef, Literal
from rdflib.term import Literal

from rdfcli.controller import Controller
from rdfcli.model import Model

N = Namespace('http://example.org/#')
REL = Namespace('http://www.perceive.net/schemas/relationship/')


class FakeModel(Model):
def load(self, source, format=None):
self.graph.parse('test/fixture.rdf')


class TestController(unittest.TestCase):

def setUp(self):
self.controller = Controller()

# stub Model.load to load only a local file
def load_stub(self, source, format=None):
self.graph.parse('test/fixture.rdf')

Model.load = load_stub
model = Model()
self.controller.set_model(model)
self.controller.set_model(FakeModel())
self.controller.load('test/fixture.rdf')

def test_initialization(self):
Expand All @@ -38,10 +38,10 @@ def test_ls(self):
result = self.controller.ls(None)
self.assertIn(FOAF.Person, result[RDF.type])
self.assertIn(Literal('Spiderman'), result[FOAF.name])
self.assertIn(Literal(u'Человек-паук', lang=u'ru'), result[FOAF.name])
self.assertIn(Literal('Человек-паук', lang='ru'), result[FOAF.name])
result = self.controller.ls('foaf:name')
self.assertIn(Literal('Spiderman'), result)
self.assertIn(Literal(u'Человек-паук', lang=u'ru'), result)
self.assertIn(Literal('Человек-паук', lang='ru'), result)

def test_is(self):
self.controller.go(N.spiderman)
Expand Down Expand Up @@ -73,16 +73,30 @@ def test_bw(self):
def test_forward(self):
self.controller.go(N.spiderman)
self.controller.back()
result = self.controller.forward()
self.controller.forward()
self.assertEqual(N.spiderman, self.controller.current)

def test_back(self):
self.controller.go(N.spiderman)
result = self.controller.back()
self.controller.back()
self.assertEqual(None, self.controller.current)

def test_this(self):
self.controller.go(N.spiderman)
result = self.controller.this()
self.controller.this()
self.assertEqual(N.spiderman, self.controller.current)

def test_select(self):
self.controller.go(N.spiderman)
self.controller.model.graph.bind('ex', 'http://example.org/#')
cols, rows = self.controller.select('select ?s ?p ?o where { ?s ?p ?o . }')
self.assertEqual(cols, ['s', 'p', 'o'])
self.assertEqual(sorted(rows), [
['ex:green_goblin', 'foaf:name', 'Green Goblin'],
['ex:green_goblin', 'rdf:type', 'foaf:Person'],
['ex:green_goblin', 'rel:enemyOf', 'ex:spiderman'],
['ex:spiderman', 'foaf:name', 'Spiderman'],
['ex:spiderman', 'foaf:name', 'Человек-паук'],
['ex:spiderman', 'rdf:type', 'foaf:Person'],
['ex:spiderman', 'rel:enemyOf', 'ex:green_goblin'],
])