summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmytro Meleshko2019-08-23 21:26:15 +0300
committerDmytro Meleshko2019-08-23 21:26:15 +0300
commit219e77d24dbe240312787a95f190b5f2a3ef3965 (patch)
tree4f10a9e0df30fc0baa811316fc208ba250dc3633
parent235663c5cd9ea4001bacb10b056d275615295eca (diff)
downloadaur-219e77d24dbe240312787a95f190b5f2a3ef3965.tar.gz
update to 1.0_pre2
-rw-r--r--.SRCINFO15
-rw-r--r--PKGBUILD28
-rw-r--r--exif.c206
-rw-r--r--exif.patch276
-rw-r--r--mirage-0.9.5.2-setup.py.patch55
5 files changed, 507 insertions, 73 deletions
diff --git a/.SRCINFO b/.SRCINFO
index fa3e0e5d6cd6..500fde8017d5 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,16 +1,19 @@
pkgbase = mirage
pkgdesc = A simple GTK+ Image Viewer
- pkgver = 0.9.5.2
- pkgrel = 6
+ pkgver = 1.0_pre2
+ pkgrel = 1
url = https://sourceforge.net/projects/mirageiv.berlios/
arch = x86_64
license = GPL
depends = pygtk
+ depends = libexif
optdepends = gnome-python: toolbar setting support in GNOME
- source = http://downloads.sourceforge.net/project/mirageiv.berlios/mirage-0.9.5.2.tar.bz2
- source = mirage-0.9.5.2-setup.py.patch
- md5sums = 92191a4496b0a50486ed7299baf6729f
- md5sums = 9b54ee94338f6daf5e7e7926427040e4
+ source = http://downloads.sourceforge.net/project/mirageiv.berlios/mirage-1.0_pre2.tar.bz2
+ source = exif.patch
+ source = exif.c
+ md5sums = 3a0cdb4efd445f85bc29a1ab7ff8a579
+ md5sums = 6f5148c3ff866fcb5cedac9ee2ad22e2
+ md5sums = 16285505d2dea76e2ab3e9159fafd8ce
pkgname = mirage
diff --git a/PKGBUILD b/PKGBUILD
index 317ae4f54655..9a350d499eb1 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -5,29 +5,33 @@
# Contributor: Ionut Biru <ibiru@archlinux.org>
pkgname=mirage
-pkgver=0.9.5.2
-pkgrel=6
+pkgver=1.0_pre2
+pkgrel=1
pkgdesc="A simple GTK+ Image Viewer"
url="https://sourceforge.net/projects/mirageiv.berlios/"
license=('GPL')
-depends=('pygtk')
+depends=('pygtk' 'libexif')
optdepends=('gnome-python: toolbar setting support in GNOME')
arch=('x86_64')
source=(http://downloads.sourceforge.net/project/mirageiv.berlios/${pkgname}-${pkgver}.tar.bz2
- mirage-0.9.5.2-setup.py.patch)
-md5sums=('92191a4496b0a50486ed7299baf6729f'
- '9b54ee94338f6daf5e7e7926427040e4')
+ exif.patch
+ exif.c)
+md5sums=('3a0cdb4efd445f85bc29a1ab7ff8a579'
+ '6f5148c3ff866fcb5cedac9ee2ad22e2'
+ '16285505d2dea76e2ab3e9159fafd8ce')
prepare() {
- cd "${pkgname}-${pkgver}"
- patch --forward --strip=1 --input="${srcdir}/mirage-0.9.5.2-setup.py.patch"
+ cd "${pkgname}-${pkgver}"
+ patch --forward --strip=1 --input="${srcdir}/exif.patch"
+ cp "${srcdir}/exif.c" .
}
build() {
- cd "${pkgname}-${pkgver}"
- python2 setup.py build
+ cd "${pkgname}-${pkgver}"
+ python2 setup.py build
}
+
package() {
- cd "${pkgname}-${pkgver}"
- python2 setup.py install --root="${pkgdir}" --optimize=1 --skip-build
+ cd "${pkgname}-${pkgver}"
+ python2 setup.py install --root="${pkgdir}" --optimize=1 --skip-build
}
diff --git a/exif.c b/exif.c
new file mode 100644
index 000000000000..9fe007c65019
--- /dev/null
+++ b/exif.c
@@ -0,0 +1,206 @@
+// This module is a replacement for pyexiv2 in the mirage image viewer.
+//
+// pyexiv2 is a Python 2 binding to the exiv2, a popular library for reading
+// EXIF, IPTC and XMP metadata from image files. mirage 1.0_pre1 and later uses
+// it to get some basic metadata like image orientation, camera model and some
+// other tags related to picture-taking. This library is not required, but is
+// nice to have. The problem is that pyexiv2 depends on an outdated version of
+// exiv2, so it can't be compiled with the latest one (0.27.2). I had the
+// following choices:
+//
+// 1. Use libgexiv2, it provides Python bindings through PyGObject. The problem
+// is that PyGObject uses GTK3 and mirage is written with GTK2 (PyGTK), this
+// would require porting the entire application to GTK3 and this is not a
+// very straigh-forward solution.
+// 2. Use py3exiv2 which supports only Python 3. But PyGTK does not support
+// Python 3. So again, I'd need to port mirage to GTK3 and this has the
+// exact same problems that solution #1 has.
+// 3. Use GObject 2 which works on Python 2. However, libgexiv2 doesn't provide
+// bindings for GObject 2.
+// 4. Patch pyexiv2 so that it can be compiled with modern exiv2. This is a
+// very hard task for me since I don't have much experience with C/C++,
+// Boost.Python and Python internals. And nobody needs this binding nowadays
+// anyway.
+// 5. Create a replacement bindings for exiv2 just for this application. I
+// tried to do this, but quickly abandoned this idea because C++ is just too
+// hard for me.
+//
+// Then I examined the source code of mirage and noticed that it only uses EXIF
+// metadata and ignores IPTC and XMP. I quickly found a popular C library for
+// parsing EXIF called libexif. "Why not use a Python library?" you might ask.
+// Well, for two reasons:
+//
+// a) I was packaging mirage for latest version of mirage (1.0_pre2) for AUR
+// (Arch User Repository) and decided to use a well-known library which can
+// be found in official Arch Linux repositories and is used by other popular
+// applications. libexif is a perfect candidate because it is in the 'extra'
+// repo and is used by GIMP, PCManFM, Thunar, Ristretto and (indirectly)
+// Mono.
+// b) libexif is written in C and I wrote C for Arduino in the past, plus I
+// have a lot of experience with Rust. It ain't much, but I wanted to learn
+// something new.
+//
+// So, I decided to write a Python extension in C that is a binding to libexif
+// that allows you only to read metadata of an image file (because that's the
+// only feature mirage needs).
+
+// Useful Links:
+// https://libexif.github.io/api/index.html
+// https://github.com/libexif/libexif
+// https://docs.python.org/2/extending/extending.html
+// https://docs.python.org/2/c-api/concrete.html
+// https://pythonextensionpatterns.readthedocs.io/en/latest/refcount.html
+// https://www.exif.org/Exif2-2.PDF
+
+#include <Python.h>
+#include <libexif/exif-data.h>
+
+// Converts a numeric value stored in an EXIF entry to a Python object. Returns
+// NULL If a non-numeric format is provided.
+PyObject* mirage_exif_number_to_py(const unsigned char* ptr, ExifFormat format, ExifByteOrder bo) {
+ PyObject* py_num = NULL;
+ switch (format) {
+ // Size of all EXIF integers is <= 32 bits, so they can be safely stored in
+ // PyInt. All numeric types are signed by default and 'S' in type names
+ // means 'signed'.
+ // 8-bit
+ case EXIF_FORMAT_BYTE:
+ case EXIF_FORMAT_SBYTE:
+ py_num = PyInt_FromLong(*ptr);
+ break;
+ // 16-bit
+ case EXIF_FORMAT_SHORT:
+ py_num = PyInt_FromLong(exif_get_short(ptr, bo));
+ break;
+ case EXIF_FORMAT_SSHORT:
+ py_num = PyInt_FromLong(exif_get_sshort(ptr, bo));
+ break;
+ // 32-bit
+ case EXIF_FORMAT_LONG:
+ py_num = PyInt_FromLong(exif_get_long(ptr, bo));
+ break;
+ case EXIF_FORMAT_SLONG:
+ py_num = PyInt_FromLong(exif_get_slong(ptr, bo));
+ break;
+ // rational numbers consist of two LONGs, they are represented as a PyTuple
+ // with two PyInts
+ // TODO: can code duplication be reduced here?
+ case EXIF_FORMAT_RATIONAL: {
+ ExifRational r = exif_get_rational(ptr, bo);
+ PyObject* n = PyInt_FromLong(r.numerator);
+ PyObject* d = PyInt_FromLong(r.denominator);
+ py_num = PyTuple_Pack(2, n, d);
+ Py_DECREF(n);
+ Py_DECREF(d);
+ } break;
+ case EXIF_FORMAT_SRATIONAL: {
+ ExifSRational r = exif_get_srational(ptr, bo);
+ PyObject* n = PyInt_FromLong(r.numerator);
+ PyObject* d = PyInt_FromLong(r.denominator);
+ py_num = PyTuple_Pack(2, n, d);
+ Py_DECREF(n);
+ Py_DECREF(d);
+ } break;
+ }
+ return py_num;
+}
+
+// Converts contents of an EXIF entry to a Python object.
+PyObject* mirage_exif_entry_to_py(ExifEntry* e, ExifByteOrder byte_order) {
+ PyObject* py_value = NULL;
+ switch (e->format) {
+ case EXIF_FORMAT_BYTE:
+ case EXIF_FORMAT_SBYTE:
+ case EXIF_FORMAT_SHORT:
+ case EXIF_FORMAT_SSHORT:
+ case EXIF_FORMAT_LONG:
+ case EXIF_FORMAT_SLONG:
+ case EXIF_FORMAT_RATIONAL:
+ case EXIF_FORMAT_SRATIONAL:
+ // numeric values are stored in a PyList even if e->components == 1 to
+ // reduce code complexity
+ py_value = PyList_New(e->components);
+ unsigned char format_size = exif_format_get_size(e->format);
+ for (unsigned int i = 0; i < e->components; i++) {
+ const unsigned char* ptr = e->data + i*format_size;
+ PyObject* py_num = mirage_exif_number_to_py(ptr, e->format, byte_order);
+ // Note that PyList_SetItem does not increase refcount of added item
+ // (py_num in this case), documentation says that it "steals" a
+ // reference to it, so refcount shouldn't be decremented here.
+ PyList_SetItem(py_value, i, py_num);
+ }
+ break;
+
+ case EXIF_FORMAT_ASCII:
+ // ASCII entries contain a null-terminated string of bytes with 7-bit
+ // ASCII codes. 1 is subtracted here to chop off the last null ('\0')
+ // byte.
+ py_value = PyString_FromStringAndSize(e->data, e->size ? e->size - 1 : 0);
+ break;
+
+ default:
+ // Content of an entry with an unknown format (including
+ // EXIF_FORMAT_UNDEFINED) is simply converted to a PyByteArray.
+ py_value = PyByteArray_FromStringAndSize(e->data, e->size);
+ }
+ return py_value;
+}
+
+// Converts all entries inside an IFD (image file directory) to a PyDict with
+// EXIF tag names as keys and entry values (see mirage_exif_entry_to_py) as
+// values.
+PyObject* mirage_exif_ifd_entries_to_py(ExifContent* c, ExifIfd ifd, ExifByteOrder byte_order) {
+ PyObject* py_entries = PyDict_New();
+
+ for (unsigned int i = 0; i < c->count; i++) {
+ ExifEntry* entry = c->entries[i];
+ if (!entry) continue;
+
+ const char* tag_name = exif_tag_get_name_in_ifd(entry->tag, ifd);
+ PyObject* py_entry_value = mirage_exif_entry_to_py(entry, byte_order);
+ PyDict_SetItemString(py_entries, tag_name, py_entry_value);
+ Py_DECREF(py_entry_value);
+ }
+
+ return py_entries;
+}
+
+// Reads EXIF metadata from a file and returns a PyDict with IFD names ('EXIF',
+// '0', '1', 'GPS' etc, see EXIF specification) as keys and PyDicts of IFD
+// entries (see mirage_exif_ifd_entries_to_py) as values.
+PyObject* mirage_exif_read_metadata(PyObject* self, PyObject* args) {
+ const char* filename;
+ int filename_len;
+ if (!PyArg_ParseTuple(args, "s#", &filename, &filename_len))
+ return NULL;
+
+ ExifData* data = exif_data_new_from_file(filename);
+ if (!data) Py_RETURN_NONE;
+
+ ExifByteOrder byte_order = exif_data_get_byte_order(data);
+
+ PyObject* py_dict = PyDict_New();
+
+ for (int ifd = 0; ifd < EXIF_IFD_COUNT; ifd++) {
+ ExifContent* content = data->ifd[ifd];
+ if (!content) continue;
+
+ const char* ifd_name = exif_ifd_get_name(ifd);
+ PyObject* py_entries = mirage_exif_ifd_entries_to_py(content, ifd, byte_order);
+ PyDict_SetItemString(py_dict, ifd_name, py_entries);
+ Py_DECREF(py_entries);
+ }
+
+ exif_data_unref(data);
+
+ return py_dict;
+}
+
+PyMethodDef methods[] = {
+ {"read_metadata", mirage_exif_read_metadata, METH_VARARGS},
+ {NULL, NULL, 0},
+};
+
+void initexif(void) {
+ Py_InitModule("exif", methods);
+}
diff --git a/exif.patch b/exif.patch
new file mode 100644
index 000000000000..05736bd0ea69
--- /dev/null
+++ b/exif.patch
@@ -0,0 +1,276 @@
+diff --recursive --unified mirage-1.0_pre2.orig/mirage.py mirage-1.0_pre2/mirage.py
+--- mirage-1.0_pre2.orig/mirage.py 2012-12-10 13:28:48.000000000 +0200
++++ mirage-1.0_pre2/mirage.py 2019-08-22 20:51:41.810026855 +0300
+@@ -64,11 +64,11 @@
+ print _("xmouse.so module not found, some screenshot capabilities will be disabled.")
+
+ try:
+- import pyexiv2
++ import exif
+ HAS_EXIF = True
+ except:
+ HAS_EXIF = False
+- print _("pyexiv2 module not found, exifdata reading/writing are disabled")
++ print _("exif.so module not found, exifdata reading/writing are disabled")
+
+ try:
+ import gconf
+@@ -2337,9 +2337,8 @@
+ hbox.pack_start(vbox_right, False, False, 3)
+ includes_exif = False
+ if HAS_EXIF:
+- exifd = pyexiv2.ImageMetadata(self.currimg.name)
+- exifd.read()
+- if ([x for x in exifd.exif_keys if "Exif.Photo" in x]):
++ metadata = self.currimg.exif_metadata
++ if metadata is not None:
+ includes_exif = True
+ # The exif data
+ exif_lbox = gtk.VBox()
+@@ -2349,13 +2348,13 @@
+ exif_vbox = gtk.VBox()
+ exif_empty = gtk.Label(" ")
+
+- expo_l, expo_v = self.exif_return_label(exifd, _("Exposure time:"), _("%s sec"),"Exif.Photo.ExposureTime", "rat_frac")
+- aperture_l, aperture_v = self.exif_return_label(exifd, _("Aperture:"), _("%s"),"Exif.Photo.FNumber", "rat_float")
+- focal_l, focal_v = self.exif_return_label(exifd, _("Focal length:"), _("%s mm"),"Exif.Photo.FocalLength", "rat_int")
+- date_l, date_v = self.exif_return_label(exifd, _("Time taken:"), _("%s"),"Exif.Photo.DateTimeOriginal", "str")
+- ISO_l, ISO_v = self.exif_return_label(exifd, _("ISO Speed:"), _("%s"),"Exif.Photo.ISOSpeedRatings", "int")
+- bias_l, bias_v = self.exif_return_label(exifd, _("Exposure bias:"), _("%s"),"Exif.Photo.ExposureBiasValue", "rat_frac")
+- model_l, model_v = self.exif_return_label(exifd, _("Camera:"), _("%s"),"Exif.Image.Model", "str")
++ expo_l, expo_v = self.exif_return_label(metadata, _("Exposure time:"), _("%s sec"),'EXIF',"ExposureTime", "rat_frac")
++ aperture_l, aperture_v = self.exif_return_label(metadata, _("Aperture:"), _("%s"),'EXIF',"FNumber", "rat_float")
++ focal_l, focal_v = self.exif_return_label(metadata, _("Focal length:"), _("%s mm"),'EXIF',"FocalLength", "rat_int")
++ date_l, date_v = self.exif_return_label(metadata, _("Time taken:"), _("%s"),'EXIF',"DateTimeOriginal", "str")
++ ISO_l, ISO_v = self.exif_return_label(metadata, _("ISO Speed:"), _("%s"),'EXIF',"ISOSpeedRatings", "int")
++ bias_l, bias_v = self.exif_return_label(metadata, _("Exposure bias:"), _("%s"),'EXIF',"ExposureBiasValue", "rat_frac")
++ model_l, model_v = self.exif_return_label(metadata, _("Camera:"), _("%s"),'0',"Model", "str")
+ exif_lbox.pack_start(exif_title, False, False, 2)
+ exif_lbox.pack_start(aperture_l, False, False, 2)
+ exif_lbox.pack_start(focal_l, False, False, 2)
+@@ -2390,19 +2389,19 @@
+ show_props.run()
+ show_props.destroy()
+
+- def exif_return_label(self, exif, label_v, format, tag, type="str"):
++ def exif_return_label(self, metadata, label_v, format, ifd, tag, type="str"):
+ label = gtk.Label(label_v)
+ label.set_alignment(1, 1)
+- if tag in exif.exif_keys:
+- raw = exif[tag].value
++ if ifd in metadata and tag in metadata[ifd]:
++ raw = metadata[ifd][tag]
+ if type == "rat_frac":
+- val = Fraction(str(raw))
++ val = Fraction(raw[0][0], raw[0][1])
+ elif type == "rat_float":
+- val = float(raw)
++ val = float(raw[0][0]) / float(raw[0][1])
+ elif type == "rat_int":
+- val = int(raw)
++ val = int(round(float(raw[0][0]) / float(raw[0][1])))
+ elif type == "int":
+- val = int(raw)
++ val = int(raw[0])
+ else:
+ val = raw
+ value = gtk.Label(format % str(val))
+@@ -4629,10 +4628,13 @@
+ self.height_original = self.height
+ self.orientation = ImageData.ORIENT_NORMAL
+ if HAS_EXIF :
+- exifd = pyexiv2.ImageMetadata(self.name)
+- exifd.read()
+- if "Exif.Image.Orientation" in exifd.exif_keys :
+- self.orientation = exifd["Exif.Image.Orientation"].value
++ self.exif_metadata = exif.read_metadata(self.name)
++ try:
++ orientation = self.exif_metadata['1']['Orientation'][0]
++ except KeyError:
++ orientation = None
++ if orientation is not None :
++ self.orientation = orientation
+ if self.orientation == ImageData.ORIENT_LEFT :
+ self.rotate_pixbuf(90)
+ elif self.orientation == ImageData.ORIENT_MIRROR :
+diff --recursive --unified mirage-1.0_pre2.orig/po/cs.po mirage-1.0_pre2/po/cs.po
+--- mirage-1.0_pre2.orig/po/cs.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/cs.po 2019-08-22 15:18:10.630214010 +0300
+@@ -31,7 +31,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/de.po mirage-1.0_pre2/po/de.po
+--- mirage-1.0_pre2.orig/po/de.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/de.po 2019-08-22 15:18:10.600214010 +0300
+@@ -32,7 +32,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/es.po mirage-1.0_pre2/po/es.po
+--- mirage-1.0_pre2.orig/po/es.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/es.po 2019-08-22 15:18:10.640214010 +0300
+@@ -32,7 +32,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/fr.po mirage-1.0_pre2/po/fr.po
+--- mirage-1.0_pre2.orig/po/fr.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/fr.po 2019-08-22 15:18:10.630214010 +0300
+@@ -34,7 +34,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/he.po mirage-1.0_pre2/po/he.po
+--- mirage-1.0_pre2.orig/po/he.po 2012-12-10 12:49:54.000000000 +0200
++++ mirage-1.0_pre2/po/he.po 2019-08-22 15:18:10.620214010 +0300
+@@ -32,7 +32,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/hu.po mirage-1.0_pre2/po/hu.po
+--- mirage-1.0_pre2.orig/po/hu.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/hu.po 2019-08-22 15:18:10.610214010 +0300
+@@ -36,7 +36,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/it.po mirage-1.0_pre2/po/it.po
+--- mirage-1.0_pre2.orig/po/it.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/it.po 2019-08-22 15:18:10.620214010 +0300
+@@ -33,7 +33,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/messages.po mirage-1.0_pre2/po/messages.po
+--- mirage-1.0_pre2.orig/po/messages.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/messages.po 2019-08-22 15:18:10.630214010 +0300
+@@ -32,7 +32,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/nl.po mirage-1.0_pre2/po/nl.po
+--- mirage-1.0_pre2.orig/po/nl.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/nl.po 2019-08-22 15:18:10.620214010 +0300
+@@ -31,7 +31,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/pl.po mirage-1.0_pre2/po/pl.po
+--- mirage-1.0_pre2.orig/po/pl.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/pl.po 2019-08-22 15:18:10.640214010 +0300
+@@ -36,7 +36,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/pt_BR.po mirage-1.0_pre2/po/pt_BR.po
+--- mirage-1.0_pre2.orig/po/pt_BR.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/pt_BR.po 2019-08-22 15:18:10.610214010 +0300
+@@ -33,7 +33,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/ru.po mirage-1.0_pre2/po/ru.po
+--- mirage-1.0_pre2.orig/po/ru.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/ru.po 2019-08-22 15:18:10.630214010 +0300
+@@ -31,7 +31,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/po/uk.po mirage-1.0_pre2/po/uk.po
+--- mirage-1.0_pre2.orig/po/uk.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/uk.po 2019-08-22 15:18:10.620214010 +0300
+@@ -38,8 +38,8 @@
+ "буде відключено."
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
+-msgstr "Модуль pyexiv2 не знайдено, читання/запис exifdata буде відключено."
++msgid "exif.so module not found, exifdata reading/writing are disabled"
++msgstr "Модуль exif.so не знайдено, читання/запис exifdata буде відключено."
+
+ #: mirage.py:79
+ #, python-format
+diff --recursive --unified mirage-1.0_pre2.orig/po/zh_CN.po mirage-1.0_pre2/po/zh_CN.po
+--- mirage-1.0_pre2.orig/po/zh_CN.po 2012-12-10 12:43:02.000000000 +0200
++++ mirage-1.0_pre2/po/zh_CN.po 2019-08-22 15:18:10.610214010 +0300
+@@ -34,7 +34,7 @@
+ msgstr ""
+
+ #: mirage.py:71
+-msgid "pyexiv2 module not found, exifdata reading/writing are disabled"
++msgid "exif.so module not found, exifdata reading/writing are disabled"
+ msgstr ""
+
+ #: mirage.py:79
+diff --recursive --unified mirage-1.0_pre2.orig/setup.py mirage-1.0_pre2/setup.py
+--- mirage-1.0_pre2.orig/setup.py 2012-12-10 13:28:31.000000000 +0200
++++ mirage-1.0_pre2/setup.py 2019-08-22 15:07:14.900205205 +0300
+@@ -37,6 +37,7 @@
+ py_modules = ['mirage'],
+ ext_modules = [Extension(name='imgfuncs', sources=['imgfuncs.c']),
+ Extension(name='xmouse', sources=['xmouse.c'], libraries=['X11']),
++ Extension(name='exif', sources=['exif.c'], libraries=['exif']),
+ Extension(name='mirage_numacomp', sources=['mirage_numacomp.c'])],
+ scripts = ['mirage'],
+ data_files=[('share/mirage', ['README', 'COPYING', 'CHANGELOG', 'TODO', 'TRANSLATORS', 'stock_shuffle.png', 'stock_leave-fullscreen.png', 'stock_fullscreen.png', 'mirage_blank.png']),
diff --git a/mirage-0.9.5.2-setup.py.patch b/mirage-0.9.5.2-setup.py.patch
deleted file mode 100644
index 9d6328409e15..000000000000
--- a/mirage-0.9.5.2-setup.py.patch
+++ /dev/null
@@ -1,55 +0,0 @@
---- mirage-0.9.5.2/setup.py 2019-08-21 14:45:22.270204699 +0300
-+++ mirage-0.9.5.2/setup.py 2019-08-21 14:54:32.630212089 +0300
-@@ -7,28 +7,6 @@
-
- from distutils.core import setup, Extension
-
--def removeall(path):
-- if not os.path.isdir(path):
-- return
--
-- files=os.listdir(path)
--
-- for x in files:
-- fullpath=os.path.join(path, x)
-- if os.path.isfile(fullpath):
-- f=os.remove
-- rmgeneric(fullpath, f)
-- elif os.path.isdir(fullpath):
-- removeall(fullpath)
-- f=os.rmdir
-- rmgeneric(fullpath, f)
--
--def rmgeneric(path, __func__):
-- try:
-- __func__(path)
-- except OSError, (errno, strerror):
-- pass
--
- # Create mo files:
- if not os.path.exists("mo/"):
- os.mkdir("mo/")
-@@ -76,23 +54,3 @@
- ('share/locale/ua/LC_MESSAGES', ['mo/ua/mirage.mo']),
- ('share/locale/it/LC_MESSAGES', ['mo/it/mirage.mo'])],
- )
--
--# Cleanup (remove /build, /mo, and *.pyc files:
--print "Cleaning up..."
--try:
-- removeall("build/")
-- os.rmdir("build/")
--except:
-- pass
--try:
-- removeall("mo/")
-- os.rmdir("mo/")
--except:
-- pass
--try:
-- for f in os.listdir("."):
-- if os.path.isfile(f):
-- if os.path.splitext(os.path.basename(f))[1] == ".pyc":
-- os.remove(f)
--except:
-- pass