Passed
Push — master ( f4e57c...929827 )
by Cyb3r
01:59 queued 11s
created

MetaStalk.main.MetaStalk.__init__()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 1
dl 0
loc 5
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2 1
"""Main function of MetaStalk.
3
Run get any metadata from photos
4
and creates graphs from the metadata using MetaStalk.Modules"""
5 1
import argparse
6 1
from collections import OrderedDict
7 1
import os
8 1
import logging
9 1
import timeit
10 1
from hachoir.parser import createParser
11 1
from hachoir.metadata import extractMetadata
12 1
from hachoir.core import config as hachoirconfig
13 1
import MetaStalk.utils as utils
14 1
import MetaStalk.modules as modules
15
16 1
hachoirconfig.quiet = True
17
18
19 1
class MetaStalk():
20
    """MetaStalk.
21
    ---
22
23
    Main Class for all MetaStalk work
24
    """
25 1
    def __init__(self):
26 1
        self.log = logging.getLogger("MetaStalk")
27 1
        self.t_start = timeit.default_timer()
28 1
        self.valid, self.invalid = [], []
29 1
        self.plots = {}
30
31 1
    def run(self, args):
32
        """Run
33
34
        Process files and generates graphs
35
36
        Arguments:
37
            args {argparse.Namespace} -- The arguments from start()
38
            log {logging.Logger} -- Logger
39
        """
40 1
        for path in args.files:
41 1
            if os.path.isdir(path):
42 1
                self.log.debug("Detected path as a directory")
43 1
                for item in os.listdir(path):
44 1
                    item_path = os.path.join(path, item)
45 1
                    self.file_search(item_path)
46
            else:
47 1
                self.file_search(path)
48
49 1
        self.plots = {
50
            "Stats": modules.stats(self.valid, self.invalid),
51
            "GPS": modules.gps_check(self.valid),
52
            "Timestamp": modules.date_time(self.valid),
53
            "Model": modules.pie_chart(self.valid, "Camera model"),
54
            "Manufacturer": modules.pie_chart(self.valid, "Camera manufacturer"),
55
            "Focal": modules.pie_chart(self.valid, "Camera focal"),
56
            "Producer": modules.pie_chart(self.valid, "Producer")
57
        }
58 1
        if args.alphabetic:
59 1
            self.plots = OrderedDict(sorted(self.plots.items()))
60 1
        if args.export:
61 1
            utils.export(args.export, args.output, self.plots)
62 1
        utils.graph(self.plots, self.t_start, args.test, args.no_open)
63
64 1
    def file_search(self, parse_file: str):
65
        """file_search
66
67
        Used to append files if the path is not a directory.
68
69
        Arguments
70
            files {str} -- Name of the file to parse.
71
        """
72 1
        parser = createParser(parse_file)
73 1
        try:
74 1
            metadata = extractMetadata(parser).exportDictionary()["Metadata"]
75 1
            metadata["item"] = parse_file
76 1
            self.valid.append(metadata)
77 1
            self.log.debug("%s has metadata", parse_file)
78 1
        except AttributeError:
79 1
            self.invalid.append(parse_file)
80 1
            self.log.debug("%s has no metadata data", parse_file)
81
82
83 1
def start():
84
    """
85
    Function needed to start MetaStalk
86
    """
87 1
    parser = argparse.ArgumentParser(prog="MetaStalk",
88
                                     description="Tool to graph "
89
                                                 "image metadata.")
90 1
    parser.add_argument('files', nargs='*', default=None,
91
                        help='Path of photos to check.')
92 1
    parser.add_argument("-a", "--alphabetic", help="Sorts charts in alphabetical order rather than"
93
                        " the default order", default=False, action="store_true")
94 1
    parser.add_argument('-d', '--debug', help="Sets logging level to DEBUG.",
95
                        action="store_const", dest="loglevel",
96
                        const=logging.DEBUG, default=logging.WARNING)
97 1
    parser.add_argument("-e", "--export", choices=["pdf", "svg", "png", "html"],
98
                        help="Exports the graphs rather than all on one webpage")
99 1
    parser.add_argument("--no-open", help="Will only start the server and not open the browser"
100
                        " to view it", default=False, action="store_true")
101 1
    parser.add_argument("-o", "--output", default="metastalk_exports",
102
                        help="The name of the directory to output exports to. "
103
                             "Will be created if it does not exist. "
104
                             "Defaults to metastalk_exports.")
105 1
    parser.add_argument('-t', '--test', default=False, action="store_true",
106
                        help='Does not show the graphs at the end.')
107 1
    parser.add_argument("-v", "--verbose", help="Sets logging level to INFO",
108
                        action="store_const", dest="loglevel",
109
                        const=logging.INFO)
110 1
    args = parser.parse_args()
111 1
    log = utils.make_logger("MetaStalk", args.loglevel)
112 1
    log.info("MetaStalk starting")
113 1
    if not args.files:
114 1
        log.error("ERROR: No path was inputted.")
115 1
        raise FileNotFoundError("No path was inputted.")
116
    metastalk = MetaStalk()
117
    metastalk.run(args)
118