def set_app_operator(self, user): config = get_metadata(SCANCENTER_METADATA_DIR) config['operator'] = user set_metadata(config, SCANCENTER_METADATA_DIR) self._config = get_metadata(SCANCENTER_METADATA_DIR) runtime_config = Scribe3Configuration() runtime_config.set('operator', user)
def __init__(self, **kwargs): self._identifier = None self._metadata = None self._new_book = False self._config = Scribe3Configuration() self.book_obj = None self.books_db = kwargs.pop('books_db', Library()) self.rcs_manager = RCS() self.rcs_manager.subscribe(self._rcs_update_handler) self.task_scheduler = kwargs.pop('task_scheduler') self.books_dir = kwargs.get('books_dir', None) or BOOKS_DIR self.book_path = kwargs.get('book_path', None) self.config_path = kwargs.get('config_path', None) or CONFIG_DIR super(BookMetadataScreenBackend, self).__init__(**kwargs)
def __init__(self, **kwargs): super(ImportFolderTask, self).__init__(**kwargs) self.source_path = kwargs['path'] self.library = kwargs['library'] self.book_obj = None self.image_stack = None self.scandata = None self.metadata = None self.DEFAULT_FIELDS_AND_VALUES = [ ('operator', get_sc_metadata()['operator']), ('scanningcenter', get_sc_metadata()['scanningcenter']), ('ppi', Scribe3Configuration().get_numeric_or_none('ppi')), ] self.do_not_rotate = True
def __init__(self, scribe_widget=scribe_widget, **kwargs): super(SingleCalibrationWidget, self).__init__(**kwargs) self.scribe_widget = scribe_widget self.image = None self.thumb = None self.foldout_image = None self.foldout_thumb = None self.foldout_widget = None self.config = Scribe3Configuration() if scribe_widget.cameras.get_camera_port('foldout') is None: self.cam_port = '' else: self.cam_port = scribe_widget.cameras.get_camera_port('foldout') self.capture_images() Clock.schedule_once(self._bind_image_menus)
def __init__(self, **kwargs): self._help_opened = False self._help_key_down = False self.timeout_event = None super(ScribeWidget, self).__init__(**kwargs) try: self.config = Scribe3Configuration() self.config.validate() self.init_pid_file() except CredentialsError as e: # if this is raised, we show the wizard msg = '[b]It looks like there is an issue with your credentials[/b].\n' \ '\n{}\nClick the button to begin the wizard.'.format(e.msg) popup = InfoPopup(title='Logged out', message=msg, auto_dismiss=False) popup.bind(on_submit=self.begin_wizard) popup.open() return except ScribeException as e: # if this is raised, the app can no longer continue msg = 'Scribe3 could not initialize\nbecause of the following error:' \ '\n\n[b]{}[/b].\n\nClick the button to close.'.format(str(e)) popup = InfoPopup(title='Initialization error', message=msg, auto_dismiss=False) app = App.get_running_app() popup.bind(on_submit=app.stop) popup.open() return #self.config.subscribe(get_adapter('config')) md_version = {'tts_version': scribe_globals.BUILD_NUMBER} set_sc_metadata(md_version) screen_manager = self.ids._screen_manager screen_manager.bind(current=self._on_current_screen) self._init_top_bar(self.config) self.help = Help() self.help.fbind('on_open', self._on_help_open) self.help.fbind('on_dismiss', self._on_help_dismiss) self.notifications_manager = NotificationManager() Clock.schedule_once(self._postponed_init, -1)
def init(self): if not self.scandata: self.scandata = ScanData(self.book['path'], downloaded=True) self._note_leafs[:] = self.scandata.iter_flagged_leafs() try: leaf_index = self._note_leafs.index(self.reopen_at) except ValueError: leaf_index = 0 self.set_current_leaf_index(leaf_index) if not self.keyboard_detector: detector = ReShootActionDetector(RESHOOT_ACTION_BINDINGS) self.keyboard_detector = detector self._keyboard_action_handler.detector = self.keyboard_detector self._cameras_count = self.camera_system.cameras.get_num_cameras() self._capture_running = False self._reverse_cams = False self.config = Scribe3Configuration() super(ReShootScreenBackend, self).init()
def _generate_thumbs(self): self.dispatch_progress('Generating thumbs') for n, image in enumerate(self.image_stack): self.dispatch_progress('Generating thumbs [{}/{}]'.format( n, len(self.image_stack))) source_image = os.path.join(self.book_obj.path, image) target_image = os.path.join(self.book_obj.path, 'thumbnails', image) current_degree = int( self.scandata.get_page_data(n).get('rotateDegree', 0)) rotate_by = convert_scandata_angle_to_thumbs_rotation( current_degree, None) thumbnail_size = (1500, 1000) if Scribe3Configuration().is_true('low_res_proxies'): thumbnail_size = (750, 500) image = Image.open(source_image) image.thumbnail(thumbnail_size) image = image.rotate(rotate_by, expand=True) image.save(target_image, 'JPEG', quality=90)
from ia_scribe.scribe_globals import BUILD_NUMBER, LOGGING_FORMAT from ia_scribe.book.metadata import get_metadata from ia_scribe import scribe_globals from ia_scribe.config.config import Scribe3Configuration log = logging.getLogger('TTSServices') log.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.DEBUG) formatter=logging.Formatter(LOGGING_FORMAT) handler.setFormatter(formatter) log.addHandler(handler) from raven import * from raven.handlers.logging import SentryHandler config = Scribe3Configuration() def get_scanner_name(): raw_md = get_metadata(scribe_globals.CONFIG_DIR) metadata = dict((k, v) for k, v in raw_md.items() if v) ret = metadata.get('scanner') return ret if ret else socket.gethostname() raven_client = Client( dsn='https://4af7fdad024f412eb45b933a400344a4' ':[email protected]/3', release=BUILD_NUMBER, name=get_scanner_name() ) sentry_handler = SentryHandler(raven_client) log.addHandler(sentry_handler)
def __init__(self, *args, **kwargs): super(C2Widget, self).__init__(**kwargs) self.config = Scribe3Configuration() self.config.subscribe(self.on_config_update) self.on_config_update()
import fcntl import json import traceback from codecs import open from collections import OrderedDict from os.path import exists, join, splitext from kivy.compat import text_type from kivy.event import EventDispatcher from sortedcontainers import SortedSet from ia_scribe import scribe_globals from ia_scribe.config.config import Scribe3Configuration CONFIG = Scribe3Configuration() PT_NORMAL = 'Normal' PT_COVER = 'Cover' PT_TITLE = 'Title' PT_COPYRIGHT = 'Copyright' PT_CONTENTS = 'Contents' PT_TISSUE = 'Tissue' PT_COLOR_CARD = 'Color Card' PT_CHAPTER = 'Chapter' PT_WHITE_CARD = 'White Card' PT_FOLDOUT = 'Foldout' PT_ABSTRACT = 'Abstract' PT_APPENDIX = 'Appendix' PT_CONTRIBUTIONS = 'Contributions' PT_DELETE = 'Delete'
import datetime from functools import partial from uuid import uuid4 from kivy.metrics import dp from kivy.clock import Clock from kivy.event import EventDispatcher from kivy.properties import (ListProperty, StringProperty, ObjectProperty, BooleanProperty, NumericProperty) from ia_scribe.abstract import singleton from ia_scribe.config.config import Scribe3Configuration from ia_scribe.utils import toast_notify move_along_frequency = \ Scribe3Configuration().get_numeric_or_none('periodic_move_along_interval') DEFAULT_EXPIRATION = move_along_frequency if move_along_frequency else 60 class Notification(EventDispatcher): title = StringProperty() message = StringProperty() is_error = BooleanProperty(False) is_sticky = BooleanProperty(False) creation_date = ObjectProperty() expiration_date = ObjectProperty() show_system_tile = BooleanProperty(False) size_hint = ObjectProperty((1, None)) type = StringProperty() height = NumericProperty(dp(54))
def capture_thread(q, cameras): config = Scribe3Configuration() '''Manage the capture image process''' sound = SoundLoader.load('camera_shoot.wav') sound_delay = config.get('sound_delay', 0) has_single_camera = cameras.get_num_cameras() == 1 if not config.is_true('stats_disabled'): from ia_scribe.breadcrumbs.api import log_event def psound(sound): try: Logger.info('Camera shoot sound delay is {}s' .format(sound_delay)) try: if float(sound_delay) < 0: Logger.debug('ScribeWidget: Negative value in config ' 'for sound_delay. Camera shoot sound is ' 'disabled') return except Exception: pass sound.seek(0) time.sleep(float(sound_delay)) sound.play() except Exception as e: Logger.exception('Failed to play camera shoot ' 'sound ({})'.format(e)) Logger.info('Starting capture thread with Queue {} ' .format(q)) myfile = None clog = False if config.is_true('camera_logging'): myfile = open('/tmp/tts_shoot_times.csv', 'a') clog = True Logger.info('Camera logging {} with file {}' .format(clog, myfile)) while True: camera_kwargs = q.get() Logger.info( 'Capturing image using kwargs: {}{}' .format(os.linesep, pformat(camera_kwargs)) ) camera_side = camera_kwargs[camera_system.KEY_SIDE] path = camera_kwargs[camera_system.KEY_PATH] thumb_path = camera_kwargs[camera_system.KEY_THUMB_PATH] callback = camera_kwargs[camera_system.KEY_CALLBACK] stats = {} capture_error = None if camera_side == 'left': angle = 90 elif camera_side == 'right': angle = -90 else: angle = - config.get_integer('default_single_camera_rotation',180) \ if has_single_camera else 0 port = cameras.get_camera_port(camera_side) Logger.info( 'ScribeWidget: Capturing side {s} with ' 'port {p}, angle {a}, path {path} and fake {fake}' .format(s=camera_side, p=port, a=angle, path=path, fake=fake_cameras) ) camera_start = time.time() # Move this in try catch block when debug is finished Logger.info('ScribeWidget: Playing camera shoot sound') _thread.start_new_thread(psound, (sound,)) Logger.info('Sound dispatched, now calling camera.shoot()') output = cameras.take_shot(camera_side, path) if type(output) is subprocess.CalledProcessError: capture_error = 'gphoto error: {}'.format(output.returncode) Logger.exception('ScribeWidget: Camera shoot failed') elif type(output) is Exception: capture_error = 'generic gphoto error' Logger.exception('ScribeWidget: Camera shoot failed with error {}'.format(output)) stats['capture_time'] = time.time() - camera_start Logger.info('ScribeWidget: Camera took {t:.2f}s' .format(t=stats['capture_time'])) # Having a camera powered off won't cause an exception, so check # to see if the image was created if not os.path.exists(path): Logger.error('ScribeWidget: Camera failed to capture an image') capture_error = 'gphoto error' Logger.info('ScribeWidget: Generating thumbs...') thumb_start = time.time() if capture_error is None: try: size = (1500, 1000) # (6000,4000)/4 if config.is_true('low_res_proxies'): size = (750, 500) # (6000,4000)/8 # size = (3000, 2000) # (6000,4000)/2 image = Image.open(path) image.thumbnail(size) image = image.rotate(angle, expand=True) if fake_cameras is not False: Logger.info('ScribeWidget: fake_cameras is {} ' '(not False) -> Drawing debug output' .format(fake_cameras)) draw = ImageDraw.Draw(image) font_color = (0, 0, 0) font_filename = join(scribe_globals.FONTS_DIR, scribe_globals.UTF8_FONT + '.ttf') font = ImageFont.truetype(font_filename, 50) draw.text((0, 0), os.path.basename(path), font_color, font=font) if angle % 360 == 0 or angle % 360 == 180: height = size[1] else: height = size[0] draw.text((0, height - 200), '{} image'.format(camera_side), fill=font_color, font=font) draw.text((0, height - 400), 'port {}'.format(port), fill=font_color, font=font) image.save(thumb_path, 'JPEG', quality=90) except Exception as e: capture_error = 'thumbnail error' + str(e) Logger.exception( 'ScribeWidget: Failed to create thumbnail: {}' .format(thumb_path) ) stats['thumb_time'] = time.time() - thumb_start Logger.info( 'ScribeWidget: Generated thumbnail at ' '{thumb_path}. Took {t:.2f}s' .format(t=stats['thumb_time'], thumb_path=thumb_path) ) if clog: ctime = '{t:.2f}s'.format(t=stats['capture_time']) ttime = '{t:.2f}s'.format(t=stats['thumb_time']) Logger.info( 'ScribeWidget: Writing ctime = {ctime}, ' 'ttime = {ttime} to stats file {path}' .format(ttime=ttime, ctime=ctime, path=myfile.name) ) lineout = ( '{0},{1},{2},{3},{4},{5},{6},{7}\n' .format(time.time(), camera_side, port, angle, ctime, ttime, path, threading.current_thread().ident) ) myfile.write(lineout) report = {camera_system.KEY_SIDE: camera_side, camera_system.KEY_THUMB_PATH: thumb_path, camera_system.KEY_ERROR: capture_error, camera_system.KEY_STATS: stats} if config.is_true('enable_camera_telemetry'): metrics_payload = {camera_system.KEY_SIDE: camera_side, camera_system.KEY_ERROR: capture_error, 'angle': angle, 'thumb_time': stats['thumb_time'], 'path': path, } put_metric('scribe3.camera.capture_time', stats['capture_time'], metrics_payload) if not config.is_true('stats_disabled'): log_event('camera', 'capture_time', stats['capture_time'], camera_side) widget = camera_kwargs.get(camera_system.KEY_IMAGE_WIDGET, None) if widget: report[camera_system.KEY_IMAGE_WIDGET] = widget extra = camera_kwargs.get(camera_system.KEY_EXTRA, None) if extra is not None: report[camera_system.KEY_EXTRA] = extra if callback is not None: Clock.schedule_once(partial(callback, report)) q.task_done()