aivavic

Untitled

May 28th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.99 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3.  
  4. # modify_date = '2016-05-31'
  5. # version 0.9
  6.  
  7. import pygtk
  8. import gtk
  9. import sane
  10. import base64
  11. import StringIO
  12. import time
  13. import sys
  14. import urllib
  15. import httplib
  16. import cgi
  17. from optparse import OptionParser
  18. from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
  19. import logging
  20. import getpass
  21. import os
  22.  
  23. pygtk.require('2.0')
  24.  
  25.  
  26. class Application(object):
  27.     #  main application class
  28.  
  29.     def __init__(self):
  30.         self.mainTimeout = 300  # main timeout for http response to service
  31.         self.imageId = ''  # id image to response
  32.         self.image = None  # image date to response
  33.         self.imageType = ''  # image type to response
  34.         self.options = None
  35.         self.logParams = {}
  36.  
  37.         # init options
  38.         self._parse_options_()
  39.  
  40.         try:
  41.             sane.init()
  42.         except Exception, m:
  43.             logging.exception(m)
  44.             logging.exception("Can't init sane!")
  45.             time.sleep(60 * 5)
  46.             sys.exit(0)
  47.  
  48.     def http_list(self):
  49.         try:
  50.             http_server = HTTPServer(('localhost', 32556), BaseHandler)
  51.             http_server.app = self
  52.             logging.info('Server http start')
  53.             http_server.timeout = 300  # restart
  54.             http_server.handle_request()
  55.         except Exception, message:
  56.             logging.exception(message)
  57.             time.sleep(10)
  58.  
  59.     def _parse_options_(self):
  60.         parser = OptionParser("usage: %prog [options]")
  61.         parser.add_option("-u", "--url_service", action="store", type="string", dest="url_service",
  62.                           default="pscan.np.ua:80", help="index of device in use")
  63.         parser.add_option("-i", "--device_index", action="store", dest="id_device", default=0,
  64.                           help="index of device in use", type="int")
  65.         parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
  66.                           help="print status messages to stdout")
  67.  
  68.         log_filename = '/var/log/remotescan/%s.log' % getpass.getuser()
  69.         log_format = '%(asctime)s ' + getpass.getuser() + ' %(levelname)-12s %(message)s'
  70.  
  71.         # init options
  72.         try:
  73.             global args
  74.             (self.options, args) = parser.parse_args()
  75.         except Exception, message:
  76.             logging.exception(message)
  77.             logging.error('Error parse options')
  78.  
  79.         logging.basicConfig(filename=log_filename if not self.options.verbose else None,
  80.                             level=logging.DEBUG,
  81.                             format=log_format
  82.                             )
  83.  
  84.     def post_image(self, b64image, count_try=0):
  85.         # post to web service
  86.         local_params = {'IdImage': self.imageId, 'DataImage': b64image, 'TypeImage': self.imageType,
  87.                         'UserName': self.logParams.get('uName', 'None'),
  88.                         'UserUUID': (self.logParams.get('uUUID', '00000000-0000-0000-0000-000000000000'),),
  89.                         'UserWarehouse': self.logParams.get('uWarehouse', '00000000-0000-0000-0000-000000000000')}
  90.  
  91.         params = urllib.urlencode(local_params)
  92.  
  93.         headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
  94.         service = self.options.url_service
  95.         full_response = "error"
  96.         try:
  97.             connection = httplib.HTTPConnection(service, timeout=self.mainTimeout)
  98.             connection.connect()
  99.             connection.request("POST", "/imageshare.php", params, headers)
  100.             response = connection.getresponse()
  101.             full_response = response.read()
  102.             connection.close()
  103.         except Exception, message:
  104.             if count_try < 4:
  105.                 logging.exception(message)
  106.                 full_response = self.post_image(b64image, count_try + 1)
  107.  
  108.         return full_response
  109.  
  110.     def response_image(self):
  111.         try:
  112.             if self.image != -1:
  113.                 buf = StringIO.StringIO()
  114.                 self.image.save(buf, "JPEG", quality=30)
  115.                 str_img = buf.getvalue()
  116.                 str_img = base64.b64encode(str_img)
  117.                 buf.close()
  118.                 logging.info("Scan image ok")
  119.                 logging.info("Image length: %s" % len(str_img))
  120.                 response = self.post_image(str_img)
  121.  
  122.                 return response
  123.         except Exception, message:
  124.             logging.exception(message)
  125.             return "Error"
  126.  
  127.     def scan_image(self):
  128.         logging.info("Scan image")
  129.  
  130.         try:
  131.             if sane.get_devices():
  132.                 scanner = sane.open(sane.get_devices()[self.options.id_device][0])
  133.                 scanner.depth = 2
  134.                 scanner.mode = "gray"
  135.                 logging.info("Open scanner")
  136.             else:
  137.                 logging.info("No scanner")
  138.                 message_box("Немає підєднаного сканеру")
  139.                 return False
  140.  
  141.         except Exception, message:
  142.             logging.exception(message)
  143.             sane.exit()
  144.             return False
  145.  
  146.         try:
  147.             scanner.start()
  148.             image = scanner.snap()
  149.         except Exception, message:
  150.             logging.exception(message)
  151.             message_box("Помилка роботи сканеру!")
  152.             return False
  153.  
  154.         form = MainForm(self, image)
  155.         if form.image2send:
  156.             response = self.response_image()
  157.             if response == 'OK':
  158.                 logging.info('Image delivered to service')
  159.             else:
  160.                 message_box('Зображення не передано!')
  161.                 logging.warning('Image not delivered')
  162.                 return False
  163.         else:
  164.             return False
  165.  
  166.         return True
  167.  
  168.  
  169. class MainForm:
  170.  
  171.     def image2pix_buf(self):
  172.  
  173.         file_io = StringIO.StringIO()
  174.         self.image.save(file_io, "ppm")
  175.         contents = file_io.getvalue()
  176.         file_io.close()
  177.         loader = gtk.gdk.PixbufLoader("pnm")
  178.         loader.write(contents, len(contents))
  179.         pix_buf = loader.get_pixbuf()
  180.         loader.close()
  181.  
  182.         orig_width = pix_buf.get_width()
  183.         orig_height = pix_buf.get_height()
  184.  
  185.         if orig_width > orig_height:
  186.             new_width = 300
  187.             new_height = 300 * orig_height / orig_width
  188.         else:
  189.             new_height = 300
  190.             new_width = 300 * orig_width / orig_height
  191.  
  192.         pix_buf = pix_buf.scale_simple(new_width, new_height, gtk.gdk.INTERP_BILINEAR)
  193.         self.img_new.set_from_pixbuf(pix_buf)
  194.  
  195.     def image_rotate(self, button, name):
  196.         if button:
  197.             self.image = self.image.rotate(90 if name == 'left' else -90)
  198.             self.image2pix_buf()
  199.  
  200.     def _exit_(self, button=None, name=''):
  201.         self.img_window.destroy()
  202.         while gtk.events_pending():
  203.             gtk.main_iteration(False)
  204.         gtk.main_quit()
  205.         if button and name:
  206.             logging.info('Exit ' + name)
  207.  
  208.     def _send_(self, button=None):
  209.         self.app.image = self.image
  210.         self._exit_(button, 'send button')
  211.         self.image2send = True
  212.  
  213.     def __init__(self, app, image):
  214.         self.app = app
  215.         self.image = image
  216.         self._create_widgets_()
  217.         self.image2pix_buf()
  218.         self.img_window.show_all()
  219.         self.image2send = False
  220.         gtk.main()
  221.  
  222.     def __add_sleep__(self, widget=None):
  223.         # auto close
  224.         if widget:
  225.             gtk.timeout_add(120*1000, self._exit_)
  226.  
  227.     def _create_widgets_(self):
  228.  
  229.         main_window = gtk.Window(gtk.WINDOW_POPUP)
  230.         main_window.set_resizable(0)
  231.         main_window.set_keep_above(True)
  232.         main_window.set_modal(1)
  233.         main_window.set_deletable(False)
  234.         main_window.set_decorated(True)
  235.         main_window.set_title("Remote Scan: Попередній перегляд")
  236.         main_window.set_position(gtk.WIN_POS_CENTER_ALWAYS)
  237.         main_window.set_focus_on_map(True)
  238.         main_window.set_accept_focus(True)
  239.         accel_group = gtk.AccelGroup()
  240.         main_window.add_accel_group(accel_group)
  241.         v_box1 = gtk.VBox(False, 3)
  242.         main_window.add(v_box1)
  243.         v_box1.show()
  244.         h_box1 = gtk.HBox(False, 4)
  245.         h_box2 = gtk.HBox(False, 2)
  246.         h_box1.set_size_request(60, 60)
  247.  
  248.         bt_rotate_left = gtk.Button()
  249.         bt_rotate_right = gtk.Button()
  250.  
  251.         image1 = gtk.Image()
  252.         image1.set_from_file("/usr/share/pixmaps/remotescan/rotate_left.png")
  253.         bt_rotate_left.set_image(image1)
  254.         image2 = gtk.Image()
  255.         image2.set_from_file("/usr/share/pixmaps/remotescan/rotate_rigth.png")
  256.         bt_rotate_right.set_image(image2)
  257.  
  258.         self.img_new = gtk.Image()
  259.         self.img_new.set_size_request(300, 300)
  260.         bt_send = gtk.Button("Зберегти")
  261.         bt_exit = gtk.Button("Відмінити")
  262.         bt_send.set_size_request(40, 40)
  263.         bt_exit.set_size_request(40, 40)
  264.         bt_rotate_left.add_accelerator("clicked", accel_group, ord("X"), gtk.gdk.CONTROL_MASK, 1)
  265.         bt_rotate_right.add_accelerator("clicked", accel_group, ord("C"), gtk.gdk.CONTROL_MASK, 1)
  266.  
  267.         bt_send.add_accelerator("clicked", accel_group, ord("s"), gtk.gdk.CONTROL_MASK, 1)
  268.         bt_exit.add_accelerator("clicked", accel_group, ord("q"), gtk.gdk.CONTROL_MASK, 1)
  269.  
  270.         h_box1.pack_start(bt_rotate_left, True, True, 0)
  271.         h_box1.pack_start(bt_rotate_right, True, True, 0)
  272.  
  273.         h_box2.pack_start(bt_send, True, True, 0)
  274.         h_box2.pack_start(bt_exit, True, True, 0)
  275.  
  276.         v_box1.pack_start(h_box1,   True, True, 0)
  277.         v_box1.pack_start(self.img_new,     True, True, 0)
  278.         v_box1.pack_start(h_box2,   True, True, 0)
  279.  
  280.         bt_send.set_flags(gtk.CAN_FOCUS)
  281.         bt_rotate_left.connect("clicked", self.image_rotate, 'left')
  282.         bt_rotate_right.connect("clicked", self.image_rotate, 'right')
  283.         bt_send.connect("clicked", self._send_)
  284.         bt_exit.connect("clicked", self._exit_, 'Button clicked')
  285.         main_window.connect("destroy", gtk.main_quit)
  286.         main_window.connect_after('show', self.__add_sleep__)
  287.  
  288.         self.img_window = main_window
  289.  
  290.  
  291. class BaseHandler(BaseHTTPRequestHandler):
  292.  
  293.     def get_params(self, params):
  294.         if isinstance(params, dict):
  295.             log_params = {'uName': params.get('uName', ''),
  296.                           'uWarehouse': params.get('uWarehouse', ''),
  297.                           'uUUID': params.get('uUUID', '')
  298.                           }
  299.  
  300.             self.server.app.imageType = params.get('imname', None)
  301.             self.server.app.imageId = params.get('idimage', None)
  302.             self.server.app.logParams = log_params
  303.             return True
  304.  
  305.         return None
  306.  
  307.     def do_GET(self):
  308.  
  309.         try:
  310.             if self.path[1:11] == 'scanimage?':
  311.                 self.path, self.query_string = self.path.split('?', 1)
  312.                 result = dict(cgi.parse_qsl(self.query_string))
  313.                 params = self.get_params(result)
  314.                 self.send_response(200)
  315.                 self.send_header('Cache-Control', 'no-cache, must-revalidate')
  316.                 self.send_header('Content-Type', 'text/json; charset=utf-8;')
  317.                 self.end_headers()
  318.  
  319.                 if params:
  320.                     if self.server.app.scan_image():
  321.                         self.wfile.write('{"Response" : "OK"}')
  322.                     else:
  323.                         self.wfile.write('{"Response" : "Error"}')
  324.                 else:
  325.                     self.wfile.write('{"Response" : "Error in params request"}')
  326.  
  327.                 self.finish()
  328.                 return
  329.         except Exception, message:
  330.             logging.exception(message)
  331.         return self.send_error(404, 'File Not Found: %s' % self.path)
  332.  
  333.  
  334. def message_box(message_text):
  335.     os.system('zenity --title="Remote Scan v0.9" --width=300 --timeout=20 --warning --text="%s"' % message_text)
  336.  
  337. try:
  338.     base_app = Application()
  339.     base_app.http_list()
  340. except Exception, msg:
  341.     logging.exception(msg)
Add Comment
Please, Sign In to add comment