Let using few messages in one file
[canaries.git] / canaries
blobdead7962f5fc5786e649205844010e7cc785d498
1 #!/usr/bin/env python3
3 #    Copyright 2020 Oskar Sharipov <oskar.sharipov[at]tuta.io>
5 #    Licensed under the Apache License, Version 2.0 (the "License");
6 #    you may not use this file except in compliance with the License.
7 #    You may obtain a copy of the License at
9 #        http://www.apache.org/licenses/LICENSE-2.0
11 #    Unless required by applicable law or agreed to in writing, software
12 #    distributed under the License is distributed on an "AS IS" BASIS,
13 #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #    See the License for the specific language governing permissions and
15 #    limitations under the License.
17 '''
18 Generates static html file of messages signed by signify(1).
20 Usage:
21     canaries [-q] <msgfolder>...
22     canaries (-h | --help)
23     canaries --version
25 Options:
26     -q              Quiet mode.
27     -h --help       Show this screen.
28     --verion        Show version.
30 Exit status:
31     0 - success.
32     1 - invalid message path.
33     2 - invalid files in path.
35 Examples:
36     Generate a new html file of messages in msg/ directory:
37         canaries -q msg
38     Look at result in your web-browser:
39         elinks canaries.html
40 '''
42 import os
43 import sys
44 import logging
45 from glob import glob
46 from typing import List, Dict
47 import jinja2
48 from docopt import docopt
51 __version__ = '1.2.0'
52 __all__ = [
53     'main',
54     'grab_messages_with_signatures',
55     'join_messages'
58 logger = logging.getLogger('canaries')
59 _handler = logging.StreamHandler()
60 _handler.setLevel(logging.INFO)
61 logger.addHandler(_handler)
64 def grab_messages_with_signatures(folder: str) -> List[Dict[str, str]]:
65     ''' searches for '*.sig' signs and its messages in `folder` directory '''
66     signatures = sorted(
67         glob(os.path.join(folder, '*.sig')),
68         key=os.path.getctime,
69         reverse=True
70     )
72     if not signatures:
73         logger.error(f'There is no signatures in `{folder}".')
74         sys.exit(2)
76     messages_with_signatures = list()
77     for signature_file in signatures:
78         message_file = signature_file[: -len('.sig')]
79         if not os.path.isfile(message_file):
80             logger.error(
81                 f'`{message_file}` doesn\'t exist or it\'s not a file.'
82             )
83             sys.exit(2)
85         with open(signature_file, 'r') as file:
86             signature = file.read()
87         with open(message_file, 'r') as file:
88             message = file.read()
89         name = message_file
90         logger.info(f"Grabbed `{name}` message")
92         messages_with_signatures.append(
93             dict(name=name, message=message, signature=signature)
94         )
95     return messages_with_signatures
98 def join_messages(signed_messages: List[Dict[str, str]]) -> str:
99     ''' renders `signed_messages` by jinja2 template system '''
100     with open('template.html', 'r') as file:
101         template = jinja2.Template(file.read())
102     return template.render(signed_messages=signed_messages)
105 def main() -> None:
106     ''' parses args and does all magic '''
107     args: Dict[str, str] = docopt(__doc__, version=__version__)
109     logger.setLevel(logging.ERROR if args['-q'] else logging.INFO)
110     signed_messages = list()
111     for folder in args['<msgfolder>']:
112         if not os.path.isdir(folder):
113             logger.error(f'`{folder}` doesn\'t exist or it\'s not a folder.')
114             sys.exit(1)
115         signed_messages.extend(grab_messages_with_signatures(folder))
117     main_page = join_messages(signed_messages)
118     with open('canaries.html', 'w') as file:
119         file.write(main_page)
120     logger.info('Wrote html to `canaries.html`.')
123 if __name__ == '__main__':
124     main()