mkogg.py: Fix 'self.get_mp4_metadata(self, source)'
[blog.git] / posts / LDAP / ldap-jpeg.py
1 #!/usr/bin/env python2
2 #
3 # Copyright (C) 2011-2012  W. Trevor King
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 """LDAP jpegPhoto viewer using your mailcap-configured JPEG viewer.
19 """
20
21 import ConfigParser as _configparser
22 import itertools as _itertools
23 import mailcap as _mailcap
24 import mimetypes as _mimetypes
25 import os as _os
26 import os.path as _os_path
27 import shlex as _shlex
28 if not hasattr(_shlex, 'quote'):  # Python < 3.3
29     import pipes as _pipes
30     _shlex.quote = _pipes.quote
31 import subprocess as _subprocess
32 import tempfile as _tempfile
33
34 import ldap as _ldap
35 import ldap.sasl as _ldap_sasl
36
37 CONFIG = _configparser.SafeConfigParser()  # from mutt-ldap.py
38 CONFIG.add_section('connection')
39 CONFIG.set('connection', 'server', 'domaincontroller.yourdomain.com')
40 CONFIG.set('connection', 'port', '389')  # set to 636 for default over SSL
41 CONFIG.set('connection', 'ssl', 'no')
42 CONFIG.set('connection', 'starttls', 'no')
43 CONFIG.set('connection', 'basedn', 'ou=x co.,dc=example,dc=net')
44 CONFIG.add_section('auth')
45 CONFIG.set('auth', 'user', '')
46 CONFIG.set('auth', 'password', '')
47 CONFIG.set('auth', 'gssapi', 'no')
48 CONFIG.read(_os_path.expanduser('~/.mutt-ldap.rc'))
49
50 _CAPS = _mailcap.getcaps()  # from mailcap-test.py
51
52 def connect():
53     """Duplicated from mutt-ldap.py"""
54     protocol = 'ldap'
55     if CONFIG.getboolean('connection', 'ssl'):
56         protocol = 'ldaps'
57     url = '{}://{}:{}'.format(
58         protocol,
59         CONFIG.get('connection', 'server'),
60         CONFIG.get('connection', 'port'))
61     connection = _ldap.initialize(url)
62     if CONFIG.getboolean('connection', 'starttls') and protocol == 'ldap':
63         connection.start_tls_s()
64     if CONFIG.getboolean('auth', 'gssapi'):
65         sasl = _ldap_sasl.gssapi()
66         connection.sasl_interactive_bind_s('', sasl)
67     else:
68         connection.bind(
69             CONFIG.get('auth', 'user'),
70             CONFIG.get('auth', 'password'),
71             ldap.AUTH_SIMPLE)
72     return connection
73
74 def search(query, connection=None):
75     """Duplicated from mutt-ldap.py"""
76     local_connection = False
77     try:
78         if not connection:
79             local_connection = True
80             connection = connect()
81         post = ''
82         if query:
83             post = '*'
84         filterstr = u'(|{})'.format(
85             u' '.join([u'({}=*{}{})'.format(field, query, post)
86                        for field in ['cn', 'displayName', 'uid', 'mail']]))
87         r = connection.search_s(
88             CONFIG.get('connection', 'basedn'),
89             _ldap.SCOPE_SUBTREE,
90             filterstr.encode('utf-8'))
91     finally:
92         if local_connection and connection:
93             connection.unbind()
94     return r
95
96 def view(filename, mime=None):
97     """Duplicated from mailcap-test.py"""
98     if mime is None:
99         mime,encoding = _mimetypes.guess_type(filename)
100         if mime is None:
101             return 1
102         print('guessed {} for {}'.format(mime, filename))
103     match = _mailcap.findmatch(_CAPS, mime, filename=_shlex.quote(filename))
104     if match[0] is None:
105         return 1
106     print('view {} with {}'.format(filename, match[0]))
107     return _subprocess.call(match[0], shell=True)
108
109 def view_entry_photo(entry):
110     cn,data = entry
111     if 'jpegPhoto' in data:
112         for jpeg in data['jpegPhoto']:
113             name = data.get('displayName', data['cn'])[-1]
114             fd,filename = _tempfile.mkstemp(
115                 prefix= name + '-', suffix='.jpeg')
116             try:
117                 _os.write(fd, jpeg)
118                 view(filename=filename, mime='image/jpeg')
119             finally:
120                 _os.remove(filename)
121                 pass
122
123
124 if __name__ == '__main__':
125     import sys
126
127     query = unicode(' '.join(sys.argv[1:]), 'utf-8')
128     entries = search(query)
129     for entry in sorted(entries):
130         view_entry_photo(entry)