mirror of https://github.com/MISP/PyTaxonomies
Initial commit
commit
a86f2c305e
|
@ -0,0 +1,5 @@
|
|||
build
|
||||
dist
|
||||
pytaxonomies.egg-info
|
||||
*.swp
|
||||
*.pyc
|
|
@ -0,0 +1,21 @@
|
|||
language: python
|
||||
|
||||
cache: pip
|
||||
|
||||
python:
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "nightly"
|
||||
|
||||
install:
|
||||
- pip install coveralls
|
||||
- pip install codecov
|
||||
- pip install .
|
||||
|
||||
script:
|
||||
- nosetests --with-coverage --cover-package=pytaxonomies
|
||||
|
||||
after_success:
|
||||
- codecov
|
||||
- coveralls
|
|
@ -0,0 +1,4 @@
|
|||
# PyTaxonomies
|
||||
|
||||
Pythonic way to work with the taxonomies defined there: https://github.com/MISP/misp-taxonomies
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
from pytaxonomies import Taxonomies
|
||||
|
||||
if __name__ == '__main__':
|
||||
argParser = argparse.ArgumentParser(description='Use MISP taxonomies')
|
||||
argParser.add_argument('-p', action='store_true', help='Print all taxonomies')
|
||||
args = argParser.parse_args()
|
||||
if args.p:
|
||||
t = Taxonomies()
|
||||
print(t)
|
|
@ -0,0 +1 @@
|
|||
from .api import Taxonomies
|
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import requests
|
||||
import os
|
||||
import collections
|
||||
|
||||
|
||||
class Entry():
|
||||
|
||||
def __init__(self, value, expanded, description):
|
||||
self.value = value
|
||||
self.expanded = expanded
|
||||
self.description = description
|
||||
|
||||
|
||||
class Predicate(collections.Mapping):
|
||||
|
||||
def __init__(self, predicate, description, entries):
|
||||
self.predicate = predicate
|
||||
self.description = description
|
||||
self.entries = {}
|
||||
if entries:
|
||||
self.__init_entries(entries)
|
||||
|
||||
def __init_entries(self, entries):
|
||||
for e in entries:
|
||||
self.entries[e['value']] = Entry(e['value'], e['expanded'],
|
||||
e.get('description'))
|
||||
|
||||
def __getitem__(self, entry):
|
||||
return self.entries[entry]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.entries)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.entries)
|
||||
|
||||
|
||||
class Taxonomy(collections.Mapping):
|
||||
|
||||
def __init__(self, taxonomy):
|
||||
self.taxonomy = taxonomy
|
||||
self.name = self.taxonomy['namespace']
|
||||
self.description = self.taxonomy['description']
|
||||
self.version = self.taxonomy['version']
|
||||
self.__init_predicates()
|
||||
|
||||
def __init_predicates(self):
|
||||
self.predicates = {}
|
||||
entries = {}
|
||||
if self.taxonomy.get('values'):
|
||||
for v in self.taxonomy['values']:
|
||||
if not entries.get(v['predicate']):
|
||||
entries[v['predicate']] = []
|
||||
entries[v['predicate']] += v['entry']
|
||||
for p in self.taxonomy['predicates']:
|
||||
self.predicates[p['value']] = Predicate(p['value'], p.get('expanded'),
|
||||
entries.get(p['value']))
|
||||
|
||||
def __str__(self):
|
||||
to_return = ''
|
||||
for p, content in self.predicates.items():
|
||||
if content:
|
||||
for k in content.keys():
|
||||
to_return += '{}:{}="{}"\n'.format(self.name, p, k)
|
||||
else:
|
||||
to_return += '{}:{}\n'.format(self.name, p)
|
||||
return to_return
|
||||
|
||||
def __getitem__(self, predicate):
|
||||
return self.predicates[predicate]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.predicates)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.predicates)
|
||||
|
||||
def amount_entries(self):
|
||||
return sum([len(p) for p in self.predicates])
|
||||
|
||||
def print_expanded_entries(self):
|
||||
to_return = ''
|
||||
for p, content in self.predicates.items():
|
||||
if content:
|
||||
for k, entry in content.items():
|
||||
to_return += '{}:{}="{}"\n'.format(self.name, p, entry.expanded)
|
||||
else:
|
||||
to_return += '{}:{}\n'.format(self.name, p)
|
||||
return to_return
|
||||
|
||||
|
||||
class Taxonomies(collections.Mapping):
|
||||
|
||||
def __init__(self, manifest_url='https://raw.githubusercontent.com/MISP/misp-taxonomies/master/MANIFEST.json',
|
||||
manifest_path=None):
|
||||
if manifest_path:
|
||||
self.loader = self.__load_path
|
||||
self.manifest = self.loader(manifest_path)
|
||||
else:
|
||||
self.loader = self.__load_url
|
||||
self.manifest = self.loader(manifest_url)
|
||||
|
||||
if manifest_path:
|
||||
self.url = os.path.dirname(os.path.realpath(manifest_path))
|
||||
self.version = self.manifest['version']
|
||||
self.license = self.manifest['license']
|
||||
self.description = self.manifest['description']
|
||||
self.taxonomies_names = [t['name'] for t in self.manifest['taxonomies']]
|
||||
self.__init_taxonomies()
|
||||
|
||||
def __load_path(self, path):
|
||||
with open(path, 'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
def __load_url(self, url):
|
||||
return requests.get(url).json()
|
||||
|
||||
def __make_uri(self, taxonomy_name):
|
||||
return '{}{}/{}'.format(self.manifest['url'], taxonomy_name, self.manifest['path'])
|
||||
|
||||
def __init_taxonomies(self):
|
||||
self.taxonomies = {}
|
||||
for t in self.manifest['taxonomies']:
|
||||
uri = self.__make_uri(t['name'])
|
||||
tax = self.loader(uri)
|
||||
self.taxonomies[t['name']] = Taxonomy(tax)
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.taxonomies[name]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.taxonomies)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.taxonomies)
|
||||
|
||||
def __str__(self):
|
||||
to_return = ''
|
||||
for k, taxonomy in self.taxonomies.items():
|
||||
to_return += '{}\n'.format(taxonomy.__str__())
|
||||
return to_return
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup(
|
||||
name='pytaxonomies',
|
||||
version='0.5',
|
||||
author='Raphaël Vinot',
|
||||
author_email='raphael.vinot@circl.lu',
|
||||
maintainer='Raphaël Vinot',
|
||||
url='https://github.com/MISP/PyTaxonomies',
|
||||
description='Python API for the taxonomies.',
|
||||
packages=['pytaxonomies'],
|
||||
scripts=['bin/pytaxonomies'],
|
||||
classifiers=[
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Console',
|
||||
'Intended Audience :: Science/Research',
|
||||
'Intended Audience :: Telecommunications Industry',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Security',
|
||||
'Topic :: Internet',
|
||||
],
|
||||
tests_requires=['nose'],
|
||||
test_suite='nose.collector',
|
||||
install_requires=['requests'],
|
||||
)
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
from pytaxonomies import Taxonomies
|
||||
|
||||
|
||||
class TestPyTaxonomies(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.taxonomies = Taxonomies()
|
||||
|
||||
def test_print(self):
|
||||
print(self.taxonomies)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
Reference in New Issue