Skip to content

Commit 1435b30

Browse files
authored
Merge pull request #9 from casework/import_case_utils_0_9_0
Adopt case_utils, and import namespace prefixes
2 parents 5e4c145 + 486112f commit 1435b30

File tree

6 files changed

+813
-817
lines changed

6 files changed

+813
-817
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
strategy:
1818
fail-fast: false
1919
matrix:
20-
python-version: [3.7, 3.8, 3.9, "3.10", "3.11"]
20+
python-version: [3.8, 3.9, "3.10", "3.11"]
2121

2222
steps:
2323
- uses: actions/checkout@v3

exifread_case/exifread_case.py

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,34 @@
55
import hashlib
66
import argparse
77
import logging
8+
9+
import case_utils.local_uuid
810
import exifread
911
import rdflib
1012
import rdflib.plugins.sparql
1113

14+
from case_utils.namespace import NS_RDF, \
15+
NS_RDFS, NS_UCO_CORE, NS_UCO_OBSERVABLE, \
16+
NS_UCO_TYPES, NS_UCO_VOCABULARY, NS_XSD
1217

13-
__version__ = "0.1.1"
18+
__version__ = "0.1.2"
1419

1520
_logger = logging.getLogger(os.path.basename(__file__))
1621

17-
parser = argparse.ArgumentParser()
18-
parser.add_argument("file", help="file to extract exif data from")
19-
args = parser.parse_args()
2022

21-
NS_RDF = rdflib.RDF
22-
NS_RDFS = rdflib.RDFS
23-
NS_UCO_CORE = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/core#")
24-
NS_UCO_LOCATION = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/location#")
25-
NS_UCO_OBSERVABLE = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/observable#")
26-
NS_UCO_TYPES = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/types#")
27-
NS_UCO_VOCABULARY = rdflib.Namespace("https://unifiedcyberontology.org/ontology/uco/vocabulary#")
28-
NS_XSD = rdflib.namespace.XSD
23+
ns_kb = rdflib.Namespace("http://example.org/kb/")
24+
25+
26+
def get_node_iri(ns: rdflib.Namespace, prefix: str) -> rdflib.URIRef:
27+
node_id = rdflib.URIRef(f"{prefix}{case_utils.local_uuid.demo_uuid()}", ns)
28+
return node_id
2929

3030

3131
def get_file_info(filepath):
3232
"""
3333
A function to get some basic information about the file application being run against
3434
:param filepath: The relative path to the image
35-
:return: A Dictinary with some information about the file
35+
:return: A Dictionary with some information about the file
3636
"""
3737
file_information = {}
3838
try:
@@ -54,9 +54,8 @@ def get_exif(file):
5454
:param file: The image file
5555
:return: Dictionary with the exif from the image
5656
"""
57-
file = open(file, 'rb')
58-
exif_tags = exifread.process_file(file)
59-
file.close()
57+
with open(file, 'rb') as file:
58+
exif_tags = exifread.process_file(file)
6059
return exif_tags
6160

6261

@@ -75,15 +74,15 @@ def create_exif_dict(tags):
7574

7675
def n_cyber_object_to_node(graph):
7776
"""
78-
Initial function to create the blank nodes for each of the file's facet nodes
77+
Initial function to create nodes for each of the file's facet nodes
7978
:param graph: rdflib graph object for adding nodes to
80-
:return: The four blank nodes for each fo the other functions to fill
79+
:return: The four nodes for each fo the other functions to fill
8180
"""
82-
cyber_object_facet = rdflib.BNode()
83-
n_raster_facets = rdflib.BNode()
84-
n_file_facets = rdflib.BNode()
85-
n_content_facets = rdflib.BNode()
86-
n_exif_facets = rdflib.BNode()
81+
cyber_object_facet = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="observableobject-"))
82+
n_raster_facets = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="rasterpicture-"))
83+
n_file_facets = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="filefacet-"))
84+
n_content_facets = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="contentfacet-"))
85+
n_exif_facets = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="exiffacet-"))
8786
graph.add((
8887
cyber_object_facet,
8988
NS_RDF.type,
@@ -116,12 +115,12 @@ def filecontent_object_to_node(graph, n_content_facets, file_information):
116115
"""
117116
Unused: Create a node that will add the file content facet node to the graph
118117
:param graph: rdflib graph object for adding nodes to
119-
:param n_content_facets: Blank node to contain all of the content facet information
118+
:param n_content_facets: Blank node to contain all content facet information
120119
:param file_information: Dictionary containing information about file being analysed
121120
:return: None
122121
"""
123-
byte_order_facet = rdflib.BNode()
124-
file_hash_facet = rdflib.BNode()
122+
byte_order_facet = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="byteorder-"))
123+
file_hash_facet = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="hash-"))
125124
graph.add((
126125
n_content_facets,
127126
NS_RDF.type,
@@ -259,13 +258,13 @@ def raster_object_to_node(graph, controlled_dict, n_raster_facets, file_informat
259258

260259
def controlled_dictionary_object_to_node(graph, controlled_dict, n_exif_facet):
261260
"""
262-
Add controlled dictionary object to accept all of the Values in the extracted exif
261+
Add controlled dictionary object to accept all Values in the extracted exif
263262
:param graph: rdflib graph object for adding nodes to
264263
:param controlled_dict: Dictionary containing the EXIF information from image
265-
:param n_controlled_dictionary:
264+
:param n_exif_facet:
266265
:return: None
267266
"""
268-
n_controlled_dictionary = rdflib.BNode()
267+
n_controlled_dictionary = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="controlleddict-"))
269268
graph.add((
270269
n_exif_facet,
271270
NS_RDF.type,
@@ -289,9 +288,9 @@ def controlled_dictionary_object_to_node(graph, controlled_dict, n_exif_facet):
289288
try:
290289
assert isinstance(v_value, rdflib.Literal)
291290
except AssertionError:
292-
_logger.info("v_value = %r." % v_value)
291+
_logger.info(f"v_value = {v_value}")
293292
raise
294-
n_entry = rdflib.BNode()
293+
n_entry = rdflib.URIRef(get_node_iri(ns=ns_kb, prefix="controlleddictionaryentry-"))
295294
graph.add((
296295
n_controlled_dictionary,
297296
NS_UCO_TYPES.entry,
@@ -319,16 +318,15 @@ def main():
319318
Main function to run the application
320319
:return: prints out the case file - TODO: write to file instead
321320
"""
321+
parser = argparse.ArgumentParser()
322+
parser.add_argument("file", help="file to extract exif data from")
323+
args = parser.parse_args()
322324
local_file = args.file
323325
file_info = get_file_info(local_file)
324326
tags = get_exif(local_file)
325327
tag_dict = create_exif_dict(tags)
328+
case_utils.local_uuid.configure()
326329
out_graph = rdflib.Graph()
327-
out_graph.namespace_manager.bind("uco-core", NS_UCO_CORE)
328-
out_graph.namespace_manager.bind("uco-location", NS_UCO_LOCATION)
329-
out_graph.namespace_manager.bind("uco-observable", NS_UCO_OBSERVABLE)
330-
out_graph.namespace_manager.bind("uco-types", NS_UCO_TYPES)
331-
out_graph.namespace_manager.bind("uco-vocabulary", NS_UCO_VOCABULARY)
332330
exif_facet_node, raster_facets_node, file_facets_node, content_facets \
333331
= n_cyber_object_to_node(out_graph)
334332
controlled_dictionary_object_to_node(out_graph, tag_dict, exif_facet_node)
@@ -338,17 +336,14 @@ def main():
338336
context = {"kb": "http://example.org/kb/",
339337
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
340338
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
341-
"uco-core": "https://unifiedcyberontology.org/ontology/uco/core#",
342-
"uco-location": "https://unifiedcyberontology.org/ontology/uco/location#",
343-
"uco-observable": "https://unifiedcyberontology.org/ontology/uco/observable#",
344-
"uco-types": "https://unifiedcyberontology.org/ontology/uco/types#",
339+
"uco-core": "https://ontology.unifiedcyberontology.org/uco/core/",
340+
"uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
341+
"uco-types": "https://ontology.unifiedcyberontology.org/uco/types/",
345342
"xsd": "http://www.w3.org/2001/XMLSchema#"}
346-
347343
graphed = out_graph.serialize(format='json-ld', context=context)
348344

349-
graph = json.dumps(graphed, indent=4)
350-
case_json = json.loads(graph.encode('utf-8'))
351-
print(case_json)
345+
parsed = json.loads(graphed)
346+
print(json.dumps(parsed, indent=4))
352347

353348

354349
if __name__ == "__main__":

0 commit comments

Comments
 (0)