93 lines
2.4 KiB
Python
Executable File
93 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Image to text service
|
|
|
|
# Copyright (C) 2024 Matt "piusbird" Arnold
|
|
# Licensed under GNU AGPL version 3
|
|
|
|
import dbus
|
|
import dbus.service
|
|
from dbus.mainloop.glib import DBusGMainLoop
|
|
import os
|
|
import sys
|
|
import signal
|
|
from PIL import Image
|
|
import tesserocr
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
from gi.repository import Gtk, Gdk # noqa
|
|
|
|
|
|
class NullDevice:
|
|
def write(self, s):
|
|
pass
|
|
|
|
|
|
def hup_handle(sig, fr):
|
|
sys.exit()
|
|
|
|
|
|
class NunnallyService(dbus.service.Object):
|
|
def __init__(self):
|
|
bus_name = dbus.service.BusName(
|
|
"club.breadpunk.nunnally", bus=dbus.SessionBus()
|
|
)
|
|
dbus.service.Object.__init__(self, bus_name, "/club/breadpunk/nunnally")
|
|
self.boardxs = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
|
self.work_img = Gtk.Image.new_from_icon_name("process-stop", Gtk.IconSize.MENU)
|
|
|
|
@dbus.service.method("club.breadpunk.nunnally")
|
|
def ocrImage(self):
|
|
pixbuf = self.boardxs.wait_for_image()
|
|
if pixbuf is not None:
|
|
self.work_img.set_from_pixbuf(pixbuf)
|
|
ocrtarget = self.pixbuf2image(pixbuf)
|
|
final_text = tesserocr.image_to_text(ocrtarget)
|
|
self.boardxs.set_text(final_text, -1)
|
|
return final_text
|
|
else:
|
|
self.boardxs.set_text("No Image in clipboard")
|
|
return str(pixbuf)
|
|
|
|
@dbus.service.method("club.breadpunk.nunnally")
|
|
def getPid(self):
|
|
pidstr = str(os.getpid())
|
|
return pidstr
|
|
|
|
def pixbuf2image(self, pix):
|
|
"""Convert gdkpixbuf to PIL image"""
|
|
|
|
data = pix.get_pixels()
|
|
w = pix.props.width
|
|
h = pix.props.height
|
|
stride = pix.props.rowstride
|
|
mode = "RGB"
|
|
if pix.props.has_alpha:
|
|
mode = "RGBA"
|
|
im = Image.frombytes(mode, (w, h), data, "raw", mode, stride)
|
|
return im
|
|
|
|
|
|
pid = os.fork() # Hmmm this looks an awful lot like... C
|
|
|
|
if pid:
|
|
os._exit(0) # kill the parent
|
|
else:
|
|
# directions say this will stop exceptions while
|
|
# daemonized. Which would be bad
|
|
os.setpgrp()
|
|
os.umask(0)
|
|
|
|
print(os.getpid()) # to aid in stopping the server
|
|
# Run silent, run deep
|
|
sys.stdin.close()
|
|
sys.stdout = NullDevice()
|
|
sys.stderr = NullDevice()
|
|
|
|
signal.signal(signal.SIGHUP, hup_handle)
|
|
signal.signal(signal.SIGTERM, hup_handle)
|
|
DBusGMainLoop(set_as_default=True)
|
|
myservice = NunnallyService()
|
|
Gtk.main()
|