/ src / bitmessageqt / utils.py
utils.py
  1  import hashlib
  2  import os
  3  
  4  from PyQt4 import QtGui
  5  
  6  import state
  7  from addresses import addBMIfNotPresent
  8  from bmconfigparser import config
  9  
 10  str_broadcast_subscribers = '[Broadcast subscribers]'
 11  str_chan = '[chan]'
 12  
 13  
 14  def identiconize(address):
 15      size = 48
 16  
 17      if not config.getboolean('bitmessagesettings', 'useidenticons'):
 18          return QtGui.QIcon()
 19  
 20      # If you include another identicon library, please generate an
 21      # example identicon with the following md5 hash:
 22      # 3fd4bf901b9d4ea1394f0fb358725b28
 23  
 24      identicon_lib = config.safeGet(
 25          'bitmessagesettings', 'identiconlib', 'qidenticon_two_x')
 26  
 27      # As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr"
 28      # to make it compatible with other identicon generators. (Note however,
 29      # that E-Mail programs might convert the BM-address to lowercase first.)
 30      # It can be used as a pseudo-password to salt the generation of
 31      # the identicons to decrease the risk of attacks where someone creates
 32      # an address to mimic someone else's identicon.
 33      identiconsuffix = config.get('bitmessagesettings', 'identiconsuffix')
 34      if identicon_lib[:len('qidenticon')] == 'qidenticon':
 35          # originally by:
 36          # :Author:Shin Adachi <shn@glucose.jp>
 37          # Licesensed under FreeBSD License.
 38          # stripped from PIL and uses QT instead (by sendiulo, same license)
 39          import qidenticon
 40          icon_hash = hashlib.md5(
 41              addBMIfNotPresent(address) + identiconsuffix).hexdigest()
 42          use_two_colors = identicon_lib[:len('qidenticon_two')] == 'qidenticon_two'
 43          opacity = int(
 44              identicon_lib not in (
 45                  'qidenticon_x', 'qidenticon_two_x',
 46                  'qidenticon_b', 'qidenticon_two_b'
 47              )) * 255
 48          penwidth = 0
 49          image = qidenticon.render_identicon(
 50              int(icon_hash, 16), size, use_two_colors, opacity, penwidth)
 51          # filename = './images/identicons/'+hash+'.png'
 52          # image.save(filename)
 53          idcon = QtGui.QIcon()
 54          idcon.addPixmap(image, QtGui.QIcon.Normal, QtGui.QIcon.Off)
 55          return idcon
 56      elif identicon_lib == 'pydenticon':
 57          # Here you could load pydenticon.py
 58          # (just put it in the "src" folder of your Bitmessage source)
 59          from pydenticon import Pydenticon
 60          # It is not included in the source, because it is licensed under GPLv3
 61          # GPLv3 is a copyleft license that would influence our licensing
 62          # Find the source here:
 63          # https://github.com/azaghal/pydenticon
 64          # note that it requires pillow (or PIL) to be installed:
 65          # https://python-pillow.org/
 66          idcon_render = Pydenticon(
 67              addBMIfNotPresent(address) + identiconsuffix, size * 3)
 68          rendering = idcon_render._render()
 69          data = rendering.convert("RGBA").tostring("raw", "RGBA")
 70          qim = QtGui.QImage(data, size, size, QtGui.QImage.Format_ARGB32)
 71          pix = QtGui.QPixmap.fromImage(qim)
 72          idcon = QtGui.QIcon()
 73          idcon.addPixmap(pix, QtGui.QIcon.Normal, QtGui.QIcon.Off)
 74          return idcon
 75  
 76  
 77  def avatarize(address):
 78      """
 79      Loads a supported image for the given address' hash form 'avatars' folder
 80      falls back to default avatar if 'default.*' file exists
 81      falls back to identiconize(address)
 82      """
 83      idcon = QtGui.QIcon()
 84      icon_hash = hashlib.md5(addBMIfNotPresent(address)).hexdigest()
 85      if address == str_broadcast_subscribers:
 86          # don't hash [Broadcast subscribers]
 87          icon_hash = address
 88      # https://www.riverbankcomputing.com/static/Docs/PyQt4/qimagereader.html#supportedImageFormats
 89      # QImageReader.supportedImageFormats ()
 90      extensions = [
 91          'PNG', 'GIF', 'JPG', 'JPEG', 'SVG', 'BMP', 'MNG', 'PBM', 'PGM', 'PPM',
 92          'TIFF', 'XBM', 'XPM', 'TGA']
 93      # try to find a specific avatar
 94      for ext in extensions:
 95          lower_hash = state.appdata + 'avatars/' + icon_hash + '.' + ext.lower()
 96          upper_hash = state.appdata + 'avatars/' + icon_hash + '.' + ext.upper()
 97          if os.path.isfile(lower_hash):
 98              idcon.addFile(lower_hash)
 99              return idcon
100          elif os.path.isfile(upper_hash):
101              idcon.addFile(upper_hash)
102              return idcon
103      # if we haven't found any, try to find a default avatar
104      for ext in extensions:
105          lower_default = state.appdata + 'avatars/' + 'default.' + ext.lower()
106          upper_default = state.appdata + 'avatars/' + 'default.' + ext.upper()
107          if os.path.isfile(lower_default):
108              default = lower_default
109              idcon.addFile(lower_default)
110              return idcon
111          elif os.path.isfile(upper_default):
112              default = upper_default
113              idcon.addFile(upper_default)
114              return idcon
115      # If no avatar is found
116      return identiconize(address)