Exemple #1
0
    def update(self, new_data):
        ro_props = [x for x in new_data.keys() if x in self.ro_props]
        unsupported_props = [
            x for x in new_data.keys() if x not in self.rw_props
        ]
        if ro_props:
            raise BadRequestError(
                'The following settings are read only and cannot be updated: {}'
                .format(', '.join(ro_props)))
        if unsupported_props:
            raise BadRequestError(
                'The following settings are invalid: {}'.format(
                    ', '.join(unsupported_props)))

        if 'server_name' in new_data:
            new_data[
                'autogenerated_access_points_ssid'] = self.__autogenerated_access_point_ssid(
                    server_name=new_data['server_name'])

        on_update_args = [(x, getattr(self, x), new_data[x])
                          for x in new_data.keys()]

        self.json_map.update(new_data)
        if 'log_level' in new_data:
            self.update_log_level()

        redis_client.dict_set('settings', self.to_map())
        for on_update_listener in self.on_update:
            for new_item in on_update_args:
                on_update_listener(*new_item)
 def __start_slew_solver(self, options):
     if not 'cameraOptions' in options:
         raise BadRequestError(
             'You need to capture from camera when using Slew mode')
     if not 'target' in options:
         raise BadRequestError('You need a target when using Slew mode')
     if not 'telescope' in options:
         raise BadRequestError('You need a telescope when using Slew mode')
     self.solver_thread = start_thread(self.__slew_solver_thread, options)
     return self.to_map()
Exemple #3
0
 def shoot(self, guider_id, exposure, initial_pause):
     if exposure < 30:
         raise BadRequestError('Exposure should be at least 30 seconds')
     guider = [
         g for g in controller.indi_server.guiders() if g.id == guider_id
     ]
     if not guider:
         raise BadRequestError('Guider not found: {} (guiders: {})'.format(
             guider_id,
             ', '.join([g.id for g in controller.indi_server.guiders()])))
     start_thread(self.__darv, guider[0], exposure, initial_pause)
     return {'started': 'ok'}
Exemple #4
0
    def start(self, binary_path='/usr/bin/phd2', display=None):
        if self.running:
            raise BadRequestError('PHD2 is already running')
        try:
            if not binary_path or not display:
                raise BadRequestError(
                    'Both PHD2 binary path and display must be specified')

            phd2_env = os.environ.copy()
            phd2_env['DISPLAY'] = display
            self.__process = subprocess.Popen(['phd2'], env=phd2_env)
            return {'started': self.running}
        except Exception as e:
            raise FailedMethodError(str(e))
Exemple #5
0
 def __execute(self, *args, **kwargs):
     try:
         return self.__service.execute(*args, **kwargs)
     except PHD2ConnectionError as e:
         raise BadRequestError(e.message)
     except PHD2MethodError as e:
         raise FailedMethodError(str(e))
Exemple #6
0
 def stop_stale(self):
     if self.status != 'stale':
         raise BadRequestError('Sequence not stale')
     self.status = 'stopped'
     for job in self.sequence_jobs:
         if job.status == 'running':
             job.status = 'stopped'
Exemple #7
0
 def update(self, data):
     if 'name' not in data and 'drivers' not in data:
         raise BadRequestError(
             'Invalid json: either name or drivers must be specified')
     if 'name' in data:
         self.name = data['name']
     if 'drivers' in data:
         self.drivers = data['drivers']
    def run(self, sequence_id):
        if not self.controller.indi_server.is_connected():
            raise BadRequestError('INDI server not connected.')
        sequence = self.controller.sequences.lookup(sequence_id)
        def cleanup_sequence(_):
            del self.running_sequences[sequence_id]

        running_sequence = RunningSequence(sequence, self.controller, self.logger, on_finished=cleanup_sequence)
        self.running_sequences[sequence_id] = running_sequence
Exemple #9
0
    def update(self, new_data):
        ro_props = [x for x in new_data.keys() if x in self.ro_props]
        unsupported_props = [x for x in new_data.keys() if x not in self.rw_props]
        if ro_props:
            raise BadRequestError('The following settings are read only and cannot be updated: {}'.format(', '.join(ro_props)))
        if unsupported_props:
            raise BadRequestError('The following settings are invalid: {}'.format(', '.join(unsupported_props)))

        on_update_args = [(x, getattr(self, x), new_data[x]) for x in new_data.keys()]
        
        self.json_map.update(new_data)
        if 'log_level' in new_data:
            self.update_log_level()

        redis_client.dict_set('settings', self.to_map())

        if self.on_update:
            for new_item in on_update_args:
                self.on_update(*new_item)
Exemple #10
0
    def stop(self):
        if not self.running:
            raise BadRequestError('PHD2 is not running')

        self.__process.terminate()
        try:
            self.__process.wait(timeout=5)
            return {'stopped': not self.running}
        except Exception as e:
            raise FailedMethodError(str(e))
 def download(self, arcminutes):
     if self.__download_thread:
         raise BadRequestError('Already downloading')
     self.downloaded = 0
     fov_limit = arcminutes * 0.1
     files = [f for f in astrometry_indexes if f['arcminutes'] >= fov_limit]
     self.__download_thread = threading.Thread(
         target=functools.partial(self.__download, files))
     self.__download_thread.start()
     return {'files': files, 'path': settings.astrometry_path()}
Exemple #12
0
 def stop(self, on_update=None):
     if not self.is_running() or not self.running_sequence_job:
         raise BadRequestError('Sequence not running')
     self.stopped = True
     self.status = 'stopping'
     if on_update:
         on_update()
     self.running_sequence_job.stop()
     self.status = 'stopped'
     if on_update:
         on_update()
    def solve_field(self, options):
        if not self.is_available():
            raise BadRequestError(
                'Astrometry.net solve-field not found in {}'.format(
                    settings.astrometry_solve_field_path))

        self.__set_status('solving')
        if not options['slewTelescope']:
            return self.__start_solver(options)
        else:
            return self.__start_slew_solver(options)
 def abort(self):
     if self.status != 'solving':
         raise BadRequestError('Solver is not running')
     self.__set_status('abort')
     if self.solver_process and self.solver_process_cancel_file:
         with open(self.solver_process_cancel_file, 'w') as f:
             f.write('abort')
         self.solver_process.wait()
         self.solver_process = None
         if self.solver_thread:
             self.solver_thread.join()
         self.solver_thread = None
     return self.to_map()
Exemple #15
0
 def __validate(self, format_string):
     test_params = {
         'exposure': 1,
         'number': 2,
         'timestamp': 1,
         'datetime': 'date-string',
         'filter': 'filter-name',
         'filter_index': 1
     }
     if not os.path.splitext(format_string.lower())[1] in ['.fit', '.fits']:
         raise BadRequestError('Unrecognized file extension')
     try:
         first_string = format_string.format(**test_params)
         test_params['number'] = 200
         if first_string == format_string.format(**test_params):
             raise BadRequestError(
                 '"number" parameter not present in format string: {}'.
                 format(format_string))
     except KeyError as e:
         raise BadRequestError(
             'Bad filename template: {} parameter not valid'.format(
                 e.args[0]))
    def __data_to_fits(self, data, temp_path):
        temp_upload_prefix = os.path.join(temp_path, 'solve_field_input')
        fits_file_path = temp_upload_prefix + '.fits'
        with open(temp_upload_prefix, 'wb') as file:
            file.write(data)

        if self.__check_fits_file(temp_upload_prefix):
            shutil.move(temp_upload_prefix, fits_file_path)
        else:
            if not self.__img_to_fits(
                    temp_upload_prefix, fits_file_path, remove=True):
                raise BadRequestError(
                    'File is not a FITS nor a recognizable image format')
        return fits_file_path
Exemple #17
0
 def guide(self, direction, duration):
     property_values = {
         'north': ('NS', 'N'),
         'south': ('NS', 'S'),
         'west': ('WE', 'W'),
         'east': ('WE', 'E'),
     }
     try:
         guide_axis, guide_direction = property_values[direction]
     except KeyError:
         raise BadRequestError('Bad guide direction: {}'.format(direction))
     guide_property = self.device.get_property(
         'TELESCOPE_TIMED_GUIDE_{}'.format(guide_axis))
     guide_property.set_values(
         {'TIMED_GUIDE_{}'.format(guide_direction): int(1000 * duration)})
     return self.guider_status()
    def __start_solver(self, options):
        temp_path = os.path.join(StaticSettings.ASTROMETRY_TEMP_PATH,
                                 'solve_field_{}'.format(time.time()))
        os.makedirs(temp_path, exist_ok=True)

        fits_file_path = None
        logger.debug('Solve field options: %s',
                     self.__platesolving_options_log(options))
        if 'fileBuffer' in options:
            data = base64.b64decode(
                options['fileBuffer']
                [options['fileBuffer'].find(PlateSolving.DATAURL_SEPARATOR) +
                 len(PlateSolving.DATAURL_SEPARATOR):])
            fits_file_path = self.__data_to_fits(data, temp_path)
        elif 'filePath' in options and os.path.isfile(options['filePath']):
            fits_file_path = options['filePath']
        elif 'cameraOptions' in options:
            from system import controller
            cameraOptions = options['cameraOptions']
            camera = controller.indi_server.get_camera(
                cameraOptions['camera']['id'])
            logger.debug('Shooting on camera {} with options {}'.format(
                camera, cameraOptions))
            result = camera.shoot_image(cameraOptions)
            logger.debug('Shoot successfull: {}'.format(result))
            fits_file_path = result['filename']
        else:
            raise BadRequestError(
                'You must pass either a fileBuffer object (data-uri formatted) or a filePath argument'
            )
        resolution = None
        with fits.open(fits_file_path) as fits_file:
            resolution = fits_file[0].data.shape

        if options.get('sync', False):
            return self.__wait_for_solution(options, resolution,
                                            fits_file_path, temp_path)
        else:
            self.solver_thread = start_thread(self.__async_wait_for_solution,
                                              options, resolution,
                                              fits_file_path, temp_path)
            return self.to_map()
Exemple #19
0
    def convert(self, args):
        key = '&'.join(
            ['{}={}'.format(key, value) for key, value in args.items()])
        key = hashlib.md5(key.encode()).hexdigest()
        format_name = args.get('format', 'jpeg')

        if format_name == 'original':
            return self.__file_info(self.path, format_name)

        if key not in self.cached_conversions:
            if format_name not in Image.FORMATS:
                raise BadRequestError(
                    'Unrecognized format: {}'.format(format_name))
            format = Image.FORMATS[format_name]
            filename = '{}_{}.{}'.format(self.id, key, format['extension'])
            filepath = os.path.join(self.directory, filename)
            self.__convert(args, filepath, format)
            self.cached_conversions[key] = self.__file_info(
                filepath, format_name, format['content_type'])
        return self.cached_conversions[key]
Exemple #20
0
def set_content_type():
    e = request.environ
    c.render_style = e['render_style']
    c.response_content_type = e['content_type']

    if e.has_key('extension'):
        c.extension = ext = e['extension']
        if ext in ('embed', 'wired', 'widget'):

            def to_js(content):
                return utils.to_js(content,
                                   callback=request.params.get(
                                       "callback", "document.write"))

            c.response_wrappers.append(to_js)
        if ext in ("rss", "api", "json") and request.method.upper() == "GET":
            user = valid_feed(request.GET.get("user"), request.GET.get("feed"),
                              request.path)
            if user and not g.read_only_mode:
                c.user = user
                c.user_is_loggedin = True
        if ext in ("mobile", "m") and not request.GET.get("keep_extension"):
            try:
                if request.cookies['reddit_mobility'] == "compact":
                    c.extension = "compact"
                    c.render_style = "compact"
            except (ValueError, KeyError):
                c.suggest_compact = True
        if ext in ("mobile", "m", "compact"):
            if request.GET.get("keep_extension"):
                c.cookies['reddit_mobility'] = Cookie(ext, expires=NEVER)
    # allow JSONP requests to generate callbacks, but do not allow
    # the user to be logged in for these
    callback = request.GET.get("jsonp")
    if is_api() and request.method.upper() == "GET" and callback:
        if not valid_jsonp_callback(callback):
            abort(BadRequestError(errors.BAD_JSONP_CALLBACK))
        c.allowed_callback = callback
        c.user = UnloggedUser(get_browser_langs())
        c.user_is_loggedin = False
    def __init__(self, data):
        self.id = random_id(data.get('id'))
        self.type = data['type']
        data.update({'id': self.id})
        self.job = None
        if self.type == 'shots':
            self.job = ExposureSequenceJob(data)
        elif self.type == 'filter':
            self.job = FilterWheelSequenceJob(data)
        elif self.type == 'property':
            self.job = PropertySequenceJob(data)
        elif self.type == 'command':
            self.job = CommandSequenceJob(data)
        elif self.type == 'pause':
            self.job = PauseSequenceJob(data)
        else:
            raise BadRequestError('Invalid sequence job type: {}'.format(
                self.type))

        self.status = data.get('status', 'idle')
        self.started_ts, self.finished_ts = None, None
        self.stopped = False
 def get_drift(self):
     if len(polar_alignment_platesolving_capture.captures) != 2:
         raise BadRequestError('You need to execute two captures')
     dec_drift = polar_alignment_platesolving_capture.coordinates(0).dec - polar_alignment_platesolving_capture.coordinates(1).dec
     return { 'declination_drift': dec_drift.deg }
 def disconnect(self):
     if not self.__thread:
         return BadRequestError('PHD2 Not connected')
     self.__connect = False
     self.__thread.join()
Exemple #24
0
 def f_wrapper(*args, **kwargs):
     if not controller.indi_server.is_connected():
         raise BadRequestError('INDI server not connected')
     return f(*args, **kwargs)
Exemple #25
0
 def import_catalog(self, name):
     if name == 'ngc_ic':
         return self.import_ngc_ic()
     raise BadRequestError('Catalog {} not supported'.format(name))