Example #1
0
	def parse_target(self, section, options):
		"""
		Tries to transform a "target" into a ParseResults.
		Raises if not possible.
		"""

		target_str = section

		if 'target' in options:
			target_str = options['target']
			print(
				"WARNING: Section '%s' has option 'target'. " % section +
				"This option will go away in the future. " +
				"Please use the section name as target.",
			)
		debug("parsing target '%s'" % target_str)

		if "//" not in target_str:
			target_str = "//" + target_str

		parsed_target = urlparse(target_str)
		options['parsed_target'] = parsed_target
		debug(str(parsed_target))

		return options
Example #2
0
 def is_correct(self, user):
     debug("checking directory permissions for %s" % user.pw_name)
     home_path = self.get_home_for_user(user)
     if not isdir(home_path):
         debug("...directory does not exist. Ignoring.")
         return True
     return S_IMODE(stat(home_path).st_mode) == self.permissions
Example #3
0
	def test_targets(self):
		"""
		Method simply runs tests for every section.
		"""
		for section, options in self.configs.items():
			debug("do check for %s" % section)
			options['strategy'].do_check()
Example #4
0
 def is_correct(self, user):
     debug("checking directory permissions for %s" % user.pw_name)
     home_path = self.get_home_for_user(user)
     if not isdir(home_path):
         debug("...directory does not exist. Ignoring.")
         return True
     return S_IMODE(stat(home_path).st_mode) == self.permissions
Example #5
0
 def allocate_camera(self, url):
     debug(f"=== init_camera ===")
     r = self.ping(url)
     if r == 200:
         self.init = True
         self.url = url
     return r
Example #6
0
	def check_deviation(self, new_sample):

		if not self.success:
			return

		previous_sample = self.load_sample()
		self.save_sample(new_sample)

		try:
			max_deviation = self.options.get_float(
				self.OPTION_MAX_DEVIATION,
				None
			)
		except TypeError as e:
			return

		if previous_sample is None or new_sample is None:
			# too little information available -> optimistically assume no deviation
			deviation = 0
		elif previous_sample == "":
			if new_sample == "":
				deviation = 0
			else:
				deviation = 100
		else:
			deviation = 100 * len(new_sample) / len(previous_sample) - 100

		additional_message = "Deviation in size %f%% (max %f%%)" % (
			deviation, max_deviation
		)

		debug(additional_message)

		self.success &= deviation <= max_deviation
		self.message += "\n\n" + additional_message
Example #7
0
    def fill_from_file(self, filename):
        """
        Method loads configuration from file into dictionary.
        """
        debug("filling configuration from '%s'" % filename)
        fp = open(filename, "r")
        sections = dict()
        options = OptionsDict()
        for line in fp.readlines():
            line = line.strip()

            if line.startswith("#"):
                continue

            if line.startswith('[') and line.endswith(']'):
                options = OptionsDict()
                sections[line[1:-1].strip()] = options
                continue

            if '=' in line:
                key, value = tuple(line.split("=", 1))
                options[key.strip()] = value.strip()
                continue

        fp.close()
        debug("filled configuration is: '%s'" % str(sections))

        self.update(sections)
Example #8
0
 def check(self):
     """
     Executes all checks according to configuration.
     """
     if not self.options.get_bool('check'):
         debug("check skipped: disabled in configuration")
         return
     self._check()
Example #9
0
 def correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("setting permissions for %s to %o" %
           (home_path, self.permissions))
     if not isdir(home_path):
         debug("...directory does not exist. Doing nothing.")
         return
     self.execute_safely(chmod, home_path, self.permissions)
Example #10
0
 def auto(self):
     """
     Run all actions in the correct order. (Calls this from outside)
     """
     debug("started")
     self._load_configs()
     self._load_users()
     self.do_checks()
Example #11
0
 def correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("setting owner for %s to %s" % (home_path, user.pw_name))
     if not isdir(home_path):
         debug("...directory does not exist. Doing nothing.")
         return
     self.execute_safely(chown, home_path, self.owner_uid_for_user(user),
                         -1)
Example #12
0
 def auto(self):
     """
     Run all actions in the correct order. (Calls this from outside)
     """
     debug("started")
     self._load_configs()
     self._load_users()
     self.do_checks()
Example #13
0
 def correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("setting permissions for %s to %o" % (
         home_path, self.permissions))
     if not isdir(home_path):
         debug("...directory does not exist. Doing nothing.")
         return
     self.execute_safely(chmod, home_path, self.permissions)
Example #14
0
 def is_correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("checking directory owner for %s" % user.pw_name)
     if not isdir(home_path):
         debug("...directory does not exist. Ignoring.")
         return True
     current_uid = self.__class__.owner_uid_for_path(home_path)
     return current_uid == self.owner_uid_for_user(user)
Example #15
0
File: owner.py Project: lpirl/homes
 def is_correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("checking directory owner for %s" % user.pw_name)
     if not isdir(home_path):
         debug("...directory does not exist. Ignoring.")
         return True
     current_uid = self.__class__.owner_uid_for_path(home_path)
     return current_uid == self.owner_uid_for_user(user)
Example #16
0
 def check(self):
     """
     Executes all checks according to configuration.
     """
     if not self.options.get_bool('check'):
         debug("check skipped: disabled in configuration")
         return
     self._check()
Example #17
0
 def get_checks(cls):
     """
     Acquires all checks (classes) in the module 'checks'.
     """
     checks = [	t[1] for t in
                     getmembers(checks_module, isclass)
                         if not t[0].startswith("Abstract") ]
     debug("found checks: %s" % str([s.__name__ for s in checks]))
     return checks
Example #18
0
 def get_checks_sorted(cls):
     """
     Sames as get_checks but checks are sorted,
     starting with most important.
     """
     checks = cls.get_checks()
     checks.sort(key=lambda check: check.order)
     debug("sorted checks: %s" % str([s.__name__ for s in checks]))
     return checks
Example #19
0
	def auto(self):
		"""
		Run all actions in the correct order to read config and
		check all targets.
		"""
		debug("started in auto mode")
		self.load_configs()
		self.test_targets()
		self.mail_results()
Example #20
0
def stop_live():
    debug(f"=== rest api:stop_live ===")
    if 'ffmpeg_process' not in session:
        return "success"
    debug(f"kill process: {session['ffmpeg_process']}")
    # os.killpg(os.getpgid(session['ffmpeg_process']), signal.SIGTERM)
    # os.killpg(session['ffmpeg_process'], signal.SIGTERM)
    os.kill(session['ffmpeg_process'], signal.SIGTERM)
    return "success"
Example #21
0
 def get_checks_sorted(cls):
     """
     Sames as get_checks but checks are sorted,
     starting with most important.
     """
     checks = cls.get_checks()
     checks.sort(key=lambda check: check.order)
     debug("sorted checks: %s" % str([s.__name__ for s in checks]))
     return checks
Example #22
0
	def get_strategies(cls):
		"""
		Acquires all strategies (classes) in the module 'strategies'.
		"""
		strategies = [	t[1] for t in
						getmembers(strategies_module, isclass) ]
		debug("found stategies: %s" % str(
				[s.__name__ for s in strategies]
			))
		return strategies
Example #23
0
 def do_checks(self):
     for check_cls in HomesChecker.get_checks_sorted():
         debug("doing check for %s" % str(check_cls))
         check = check_cls(
             self.homes_path,
             self.users,
             self.simulate,
             self.configs[check_cls.config_section]
         )
         check.check()
Example #24
0
 def get_checks(cls):
     """
     Acquires all checks (classes) in the module 'checks'.
     """
     checks = [
         t[1] for t in getmembers(checks_module, isclass)
         if not t[0].startswith("Abstract")
     ]
     debug("found checks: %s" % str([s.__name__ for s in checks]))
     return checks
Example #25
0
 def stop_live(self):
     debug(f"=== stop_live ===")
     if self.init is False:
         return 404
     r = requests.get(url=f'{self.url}/stop_live',
                      cookies=self.session_cookie)
     # if r.status_code == 200:
     # with open(path, 'wb') as f:
     #     for chunk in r.iter_content(1024):
     #         f.write(chunk)
     return r.status_code
Example #26
0
 def _check(self):
     """
     For every user, check if home correct and correct if required
     and configured.
     """
     for user in self.users:
         if not self.is_correct(user):
             if not self.options.get_bool('correct'):
                 debug("correction skipped: disabled in configuration")
                 continue
             self.correct(user)
Example #27
0
 def _check(self):
     """
     For every user, check if the home directory is correct and
     correct with respect to the configuration.
     """
     for user in self.users:
         if not self.is_correct(user):
             if not self.options.get_bool('correct'):
                 debug("correction skipped: disabled in configuration")
                 continue
             self.correct(user)
Example #28
0
 def _check(self):
     """
     For every existing home directory, check if it's correct and
     correct if required and configured.
     """
     for directory in self.get_existing_directories():
         if not self.is_correct(directory):
             if not self.options.get_bool('correct'):
                 debug("correction skipped: disabled in configuration")
                 continue
             self.correct(directory)
Example #29
0
 def _check(self):
     """
     For every existing home directory, check if it's correct and
     correct if required and configured.
     """
     for directory in self.get_existing_directories():
         if not self.is_correct(directory):
             if not self.options.get_bool('correct'):
                 debug("correction skipped: disabled in configuration")
                 continue
             self.correct(directory)
Example #30
0
	def do_check(self):
		"""
		Method coordinates check.
		"""
		self._do_request()

		debug("%sreached\n\n'%s'\n" % (
			'NOT ' if not self.success else '',
			''.join([COLOR_LIGHT, self.message, COLOR_STD])
		))

		self.check_deviation(self.response_str)
Example #31
0
 def get_frame(self, path=None):
     debug(f"=== get_frame {path} ===")
     if self.init is False:
         return 404
     r = requests.get(url=f'{self.url}/get_frame',
                      cookies=self.session_cookie)
     if r.status_code == 200:
         if path is not None:
             with open(path, 'wb') as f:
                 for chunk in r.iter_content(1024):
                     f.write(chunk)
     return r.status_code
Example #32
0
 def ping(self, url):
     debug(f"=== ping ===")
     r = requests.get(url=f'{url}/', cookies=self.session_cookie)
     if r.status_code == 200:
         debug(f"cookies:{r.cookies}")
         if 'session' in r.cookies:
             self.session_cookie = {'session': r.cookies['session']}
     # if r.status_code == 200:
     # with open(path, 'wb') as f:
     #     for chunk in r.iter_content(1024):
     #         f.write(chunk)
     return r.status_code
Example #33
0
File: owner.py Project: lpirl/homes
 def correct(self, user):
     home_path = self.get_home_for_user(user)
     debug("setting owner for %s to %s" % (home_path, user.pw_name))
     if not isdir(home_path):
         debug("...directory does not exist. Doing nothing.")
         return
     self.execute_safely(
         chown,
         home_path,
         self.owner_uid_for_user(user),
         -1
     )
Example #34
0
 def _frame(self, path=None):
     # example to read file
     # https://stackoverflow.com/questions/13137817/how-to-download-image-using-requests
     debug(f"=== _frame ===")
     if self.init is False:
         return 404
     r = requests.get(url=f'{self.url}/_frame', cookies=self.session_cookie)
     if r.status_code == 200:
         if path is not None:
             with open(path, 'wb') as f:
                 for chunk in r.iter_content(1024):
                     f.write(chunk)
     return r.status_code
Example #35
0
    def check_existance_and_fill_missing_files(self, user):
        """
        Does the actual check for ``is_correct`` and stores paths
        of missing files in ``self.missing_files``
        (what ``self.is_correct`` already initialized).
        """
        append_to_missing_files = self.missing_files[user].append
        for unexpanded_path in self.unexpanded_paths:
            file_path = self.expand_string_for_user(unexpanded_path, user)

            if not self.equal_files_for_expanded_path(user, file_path):
                debug("...not equal.")
                append_to_missing_files(file_path)
Example #36
0
	def preprocess_configs(self, configs):
		"""
		Method prepares every service in configs for running the tests.
		"""
		self._strategies = MeerkatMon.get_strategies()
		for section, options in configs.items():
			debug("processing service '%s'" % section)
			if section not in ['meerkatmon_default', 'meerkatmon_global']:
				options.apply_defaults(self.default_configs)
				options = self.parse_target(section, options)
				options = self.assign_strategy(section, options)
			configs[section] = options
		return configs
Example #37
0
 def start_live(self, address, timestamp=False, frame_rate=30):
     debug(f"=== start_live ===")
     if self.init is False:
         return 404
     r = requests.get(
         url=
         f'{self.url}/start_live/{address}/{ 1 if timestamp is True else 0 }/{frame_rate}',
         cookies=self.session_cookie)
     # if r.status_code == 200:
     # with open(path, 'wb') as f:
     #     for chunk in r.iter_content(1024):
     #         f.write(chunk)
     return r.status_code
Example #38
0
    def do_checks(self):
        for check_cls in ChecksRunner.get_checks_sorted():

            options = self.configs.get(check_cls.config_section, None)

            if not options:
                debug("no configuration for %s! Skipping." % check_cls)
                continue

            debug("doing check for %s" % check_cls)
            check = check_cls(self.home_path, self.users, self.simulate,
                              self.configs[check_cls.config_section])
            check.check()
Example #39
0
    def post_init(self):
        """
        Load file paths from configured file into ``unexpanded_paths``.
        """

        self.missing_files = {}
        """
        Dictionary of {user: file_name}
        Where ``user`` is an objects in terms of Pythons built-in pwd module
        and ``file_name`` an expanded path.
        """

        debug("Loaded list of files for section '%s': %r" %
              (self.config_section, self.unexpanded_paths))
Example #40
0
    def equal_files_for_expanded_path(self, user, file_path):
        """
        Compares the corresponding file in home and real root.
        Returns ``True`` if files are egual, ``False`` otherwise.
        """
        src_file_path, dst_file_path = self.get_src_and_dst_path(
            user, file_path)

        debug("Comparing '{0}' and '{1}'".format(src_file_path, dst_file_path))

        if not isfile(dst_file_path):
            return False

        return compare_files(src_file_path, dst_file_path)
Example #41
0
    def _check(self):
        """
        Checks correctness and corrects if configured using iterables of
        all users and existing directories.
        """
        directories = list(self.get_existing_directories())
        users = self.users

        if not self.is_correct(users, directories):
            debug("correction required")
            if not self.options.get_bool('correct'):
                debug("correction skipped: disabled in configuration")
                return
            self.correct(users, directories)
Example #42
0
    def _check(self):
        """
        Checks correctness and corrects if configured using iterables of
        all users and existing directories.
        """
        directories = list(self.get_existing_directories() or [])
        users = self.users

        if not self.is_correct(users, directories):
            debug("correction required")
            if not self.options.get_bool('correct'):
                debug("correction skipped: disabled in configuration")
                return
            self.correct(users, directories)
Example #43
0
    def do_checks(self):
        for check_cls in ChecksRunner.get_checks_sorted():

            options = self.configs.get(check_cls.config_section, None)

            if not options:
                debug("no configuration for %s! Skipping." % check_cls)
                continue

            debug("doing check for %s" % check_cls)
            check = check_cls(
                self.home_path,
                self.users,
                self.simulate,
                self.configs[check_cls.config_section]
            )
            check.check()
Example #44
0
    def check_existance_and_fill_missing_files(self, user):
        """
        Checks if all binaries listed in the configuration and their
        required libraries are identically present in the home.
        """
        append_to_missing_files = self.missing_files[user].append

        for unexpanded_path in self.unexpanded_paths:
            binary_path = self.expand_string_for_user(unexpanded_path, user)

            dependencies = self.get_dependendencies_for_expanded_path(
                binary_path)

            for path in dependencies + [binary_path]:

                if not self.equal_files_for_expanded_path(user, path):
                    debug("...not equal.")
                    append_to_missing_files(path)
Example #45
0
	def send_mails(self, headers_and_messages=None):
		"""
		Method actually does send an email.
		"""
		if not headers_and_messages:
			return

		s = SMTP('localhost')
		for headers, message in headers_and_messages:
			msg = MIMEText(message)
			for key, value in headers.items():
				msg[key] = value
			debug("sending %s" % str(msg))
			s.sendmail(
				headers['From'],
				[r[1] for r in getaddresses([headers['To']])],
				msg.as_string()
			)
		s.quit()
Example #46
0
	def assign_strategy(self, section, options):
		"""
		Rates all strategies for all targets and selects the best one.
		"""
		global_options = self.global_options
		best_strategy = (None, KNOWLEDGE_NONE)
		for strategy in self._strategies:
			strategy_for_target = 	strategy(
										global_options,
										section,
										options,
									)
			knowledge = strategy_for_target.target_knowledge()
			if knowledge > best_strategy[1]:
				best_strategy = (strategy_for_target, knowledge)

		debug("choosen strategy is '%s'" % best_strategy[0].__class__.__name__)
		options['strategy'] = best_strategy[0]

		return options
Example #47
0
    def get_dependendencies_for_expanded_path(self, binary_path):
        """
        Returns a list of paths to librarires that are required by
        """
        out = []
        ldd_out = check_output(['ldd', binary_path]).decode('utf-8')
        ldd_out_lines = ldd_out.split("\n")
        for ldd_out_line in ldd_out_lines:

            # ex:'	libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (…)'
            if '=> /' in ldd_out_line:
                out.append(ldd_out_line.split(' ')[2])

            # ex: "	/lib64/ld-linux-x86-64.so.2 (…)"
            if ldd_out_line.startswith("\t/"):
                out.append(ldd_out_line.split(" ")[0].strip())

        debug("Dependencies for '{0}': {1}".format(binary_path, out))

        return out
Example #48
0
	def send_mails(self, headers_and_messages=None):
		"""
		Method actually does send an email.
		"""
		if not headers_and_messages:
			return

		s = SMTP('localhost')
		for headers, message in headers_and_messages:
			msg = MIMEText(message)
			for key, value in headers.items():
				msg[key] = value
			debug("sending %s" % str(msg))
			try:
				s.sendmail(
					headers['From'],
					[r[1] for r in getaddresses([headers['To']])],
					msg.as_string()
				)
			except ConnectionRefusedError:
				print("ERROR: could not send emails. "
				      "Connection to localhost refused.")
		s.quit()
Example #49
0
def start_live(address, timestamp, frame_rate):
    debug(f"=== rest api:get_live at {address}, timestamp: {timestamp} ===")
    if eval(timestamp) == 1:
        ffmpeg = "ffmpeg -f {device} -framerate 30 -video_size 1280x720 -i {camera} -vcodec libx264 " \
                 "-preset ultrafast -tune zerolatency -pix_fmt yuv422p " \
                 "-vf drawtext=\"fontfile=/System/Library/Fonts/NewYork.ttf: text=\"{text}\": fontcolor=white: fontsize=36: x=(w-text_w)/2: y=(h-text_h)/2\" " \
                 "-r {rate} -f mpegts udp://{addr}".format(device= config.INPUT_DEVICE, camera=config.CAMERA_ID, text="%\{gmtime\}", rate=frame_rate, addr=address)
    else:
        ffmpeg = "ffmpeg -f {device} -framerate 30 -video_size 1280x720 -i {camera} -vcodec libx264 " \
                 "-preset ultrafast -tune zerolatency -pix_fmt yuv422p " \
                 "-r {rate} -f mpegts udp://{addr}".format(device=config.INPUT_DEVICE, camera=config.CAMERA_ID, rate=frame_rate, addr=address)

        # ffmpeg -f avfoundation -framerate 30 -video_size 1280x720 -i "0:none" -vcodec libx264 -preset ultrafast
    #        -tune zerolatency -pix_fmt yuv422p -f mpegts udp://192.168.8.3:12345
    # return_code = subprocess.run([ffmpeg], shell=True)
    # debug(f"=== subprocess.run return {return_code} ===")
    debug(f"{ffmpeg}")
    process = subprocess.Popen(ffmpeg, shell=True)
    debug(f"=== subprocess.Popen return {process.pid} ===")
    session["ffmpeg_process"] = process.pid
    debug(f"process: {process.pid}")
    debug(f"process: {session['ffmpeg_process']}")
    return "success"
Example #50
0
	def mail_results_together(self, results):
		"""
		Method mails test results all together to global admin.
		"""
		mail_from = self.global_options['mail_from']
		mail_admin = self.default_configs['admin']
		mail_subject = 'Output from checking ' + ', '.join(list(results.keys()))
		mail_messages_delim = "\n\n%s\n\n" % ("="*80)
		mail_message = mail_messages_delim.join((
			''.join(("--- ", r['subject'], " ---\n", r['message']))
			for r in list(results.values())
		))
		if not mail_message:
			debug("Mailing together. Nothing to do.")
			return
		mail_headers = {
			'From': mail_from,
			'To': mail_admin,
			'Subject': mail_subject,
		}
		self._mail_headers_add_references(mail_headers)

		debug("Mailing together. Collected %s" % str((mail_headers, mail_message)))
		self.send_mails([(mail_headers, mail_message)])
Example #51
0
	def mail_results_separate(self, results):
		"""
		Method mails test results all together to admin specified in
		corresponding section or global admin if absent.
		"""

		# list of tuples: (<header dict>, <message str>)
		headers_and_messages = list()

		mail_from = self.global_options['mail_from']
		for section, result in results.items():
			mail_to = self.configs[section]['admin']
			mail_subject = result['subject']
			mail_message = result['message']
			mail_headers = {
				'From': mail_from,
				'To': mail_to,
				'Subject': mail_subject,
			}
			self._mail_headers_add_references(mail_headers, section)
			headers_and_messages.append((mail_headers, mail_message))

		debug("mailing separate. Collected %s" % str(headers_and_messages))
		self.send_mails(headers_and_messages)
Example #52
0
	def do_check(self):
		cmd = [
			self.which('ping'),
			'-W', self.options.get('timeout', '5'),
			'-c', self.options.get('count', '1'),
			self.target.netloc
		]

		debug("running command: %s" % str(cmd))

		success = True
		try:
			output = check_output(cmd, stderr=STDOUT)
		except CalledProcessError as e:
			success = False
			output = e.output

		self.output = output.decode().strip()
		self.success = success

		debug("had %ssuccess \n\n'%s'\n" % (
			'NO ' if not self.success else '',
			''.join([COLOR_LIGHT, self.output, COLOR_STD])
		))
Example #53
0
    def do_trash_directory(self, directory_path):
        """
        Moves directory to trash.
        """
        if listdir(directory_path):
            debug("archiving directory '%s'" % directory_path)
            if not self.do_archive_directory(directory_path):
                return
        else:
            debug("not archiving empty directory '%s'" % directory_path)

        debug("deleting directory '%s'" % directory_path)
        self.execute_safely(rmtree, directory_path, ignore_errors=True)
Example #54
0
def _frame():
    debug("=== rest_api:_frame ===")
    # debug(f"session: {session}")
    # debug(f"session type: {type(session)}")
    # if 'test' not in session:
    #     session['test'] = 1
    #     debug(f"set session[test]={session['test']}")
    # else:
    #     debug(f"get session[test]={session['test']}")
    # return "success"
    if 'frame' not in session:
        debug(f"no frame found in seesion")
        return get_frame()
    # put _frame in response
    debug(f"put current _frame to response ===")

    retval, buffer = cv2.imencode('.png', session['frame'])
    response = make_response(buffer.tobytes())
    response.headers.set('Content-Type', 'image/png')
    #
    debug(f"return response ===")
    return response
Example #55
0
    def do_trash_directory(self, directory_path):
        """
        Moves directory to trash.
        """
        if listdir(directory_path):
            debug("archiving directory '%s'" % directory_path)
            if not self.do_archive_directory(directory_path):
                return
        else:
            debug("not archiving empty directory '%s'" % directory_path)

        debug("deleting directory '%s'" % directory_path)
        self.execute_safely(    rmtree,
                                directory_path,
                                ignore_errors=True)
Example #56
0
def RankedPairs(candidates, ballots, ignored_candidates=[], tie_breaker=None):
    candidates = list(candidates)
    candidates.sort()

    tie_breaker_list = []
    if tie_breaker:
        tie_breaker_list = tie_breaker.split('>')

        if len(set(tie_breaker_list)) != len(tie_breaker_list):
            raise InvalidTieBreakerException(
                'The tie breaker ballot must not contain duplicate candidates')

        if len(tie_breaker_list) < len(candidates):
            raise InvalidTieBreakerException(
                'The tie breaker ballot must contain all candidates')

        for cand in tie_breaker_list:
            if not cand in candidates:
                raise InvalidTieBreakerException(
                    'Invalid candidate %s in tie breaker' % (cand))

    # Create pairs
    pairs = {}
    for i, cand1 in enumerate(candidates):
        for cand2 in candidates[i + 1:]:
            pair_name = cand1 + cand2
            pair = pairs[pair_name] = {
                'diff': 0,
                'winner': None,
                'loser': None,
                cand1: 0,
                cand2: 0
            }

    # Tally
    blank_ballots = 0
    cand_stats = {}
    for cand in candidates:
        cand_stats[cand] = {'won': 0, 'lost': 0, 'mentions': 0}

    for ballot in ballots:
        already_mentioned = []

        rows = ballot.split('>')
        # Turn blank votes into an empty list
        rows = list(filter(lambda row: len(row), rows))
        rows = list(map(lambda row: row.split('='), rows))

        if not len(rows):
            blank_ballots += 1
            continue

        for y, cur_row in enumerate(rows):
            for cur_col in cur_row:
                if not cur_col in candidates:
                    raise InvalidBallotException(
                        'Invalid candidate %s in ballot %s' %
                        (cur_col, ballot))
                if cur_col in already_mentioned:
                    raise InvalidBallotException(
                        'Duplicate candidate %s in ballot %s' %
                        (cur_col, ballot))
                already_mentioned.append(cur_col)
                cand_stats[cur_col]['mentions'] += 1

        # Consider candidates not mentioned as lesser than those mentioned
        rows.append(list(set(candidates) - set(already_mentioned)))
        print(rows)

        for y, cur_row in enumerate(rows):
            for cur_col in cur_row:
                for lesser_row in rows[y + 1:]:
                    for lesser_col in lesser_row:
                        if not lesser_col in candidates:
                            raise InvalidBallotException(
                                'Invalid candidate %s in ballot %s' %
                                (cur_col, ballot))
                        if lesser_col == cur_col:
                            raise InvalidBallotException(
                                'Duplicate candidate %s in ballot %s' %
                                (cur_col, ballot))
                        pair_name = ''.join(sorted((cur_col, lesser_col)))
                        pairs[pair_name][cur_col] += 1

    # Check blank vote count
    debug('%d ballots cast (%d blank)' % (len(ballots), blank_ballots))
    if blank_ballots >= len(ballots) / 2:
        raise TooManyBlankBallotsException('Too many blank ballots',
                                           blank_ballots, len(ballots))

    # Disqualify candidates as needed
    disqualified_candidates = []
    for cand, stats in cand_stats.items():
        is_ignored = cand in ignored_candidates
        has_insufficient_mentions = stats['mentions'] < len(ballots) / 2

        if (is_ignored or has_insufficient_mentions):
            candidates.remove(cand)

            for pair_name in dict(pairs):
                cands = list(pair_name)
                if cand in cands:
                    del pairs[pair_name]

        if is_ignored:
            debug('%s is ignored in this election' % (cand))
        elif has_insufficient_mentions:
            disqualified_candidates.append(cand)
            debug('%s is disqualified due to insufficient mentions' % (cand))

    # Determine the results of the compared pairs
    for pair_name, pair in pairs.items():
        cand1, cand2 = list(pair_name)
        pair['diff'] = pair[cand1] - pair[cand2]

        if pair[cand1] > pair[cand2]:
            cand_stats[cand1]['won'] += 1
            cand_stats[cand2]['lost'] += 1
            pair['winner'] = cand1
            pair['loser'] = cand2
        elif pair[cand2] > pair[cand1]:
            cand_stats[cand2]['won'] += 1
            cand_stats[cand1]['lost'] += 1
            pair['winner'] = cand2
            pair['loser'] = cand1
        else:
            if not tie_breaker:
                raise TieBreakerNeededException()

            cand1_index = tie_breaker_list.index(cand1)
            cand2_index = tie_breaker_list.index(cand2)

            if cand1_index < cand2_index:
                cand_stats[cand1]['won'] += 1
                cand_stats[cand2]['lost'] += 1
                pair['winner'] = cand1
                pair['loser'] = cand2
            else:
                cand_stats[cand2]['won'] += 1
                cand_stats[cand1]['lost'] += 1
                pair['winner'] = cand2
                pair['loser'] = cand1

    debug('\nCompared pairs:')
    debug(pairs)

    debug('\nCandidate pair scores:')
    debug(cand_stats)

    # Order the pairs
    ordered_entries = []
    entries = list(pairs.items())
    while len(entries):
        max_diff = -1
        max_diff_indices = None

        for i, pair in enumerate(entries):
            abs_diff = abs(pair[1]['diff'])
            if abs_diff > max_diff:
                max_diff = abs_diff
                max_diff_indices = [i]
            elif abs_diff == max_diff:
                max_diff_indices.append(i)

        if len(max_diff_indices) == 1:
            # No tie
            pair = entries[max_diff_indices[0]]
            ordered_entries.append(pair)
            entries.pop(max_diff_indices[0])
        else:
            # We have a tie, follow §2.10
            # Obtain the pairs, from the highest index to the lowest as to not mess up the indices when popping
            max_diff_indices.sort(reverse=True)
            equal_pairs = []
            for i in max_diff_indices:
                equal_pairs.append(entries[i])
                entries.pop(i)

            # 1. The equal pair with a loser that's already listed as a loser is put first
            loser_entries = [
            ]  # All losers that are already in the ordered pairs
            for i, equal_pair in enumerate(equal_pairs):
                # Find the loser of the equal pair
                equal_pair_loser = equal_pair[1]['loser']

                # Check if the loser is already in the ordered pairs as a loser
                ordered_index = None
                for n, ordered_entry in enumerate(ordered_entries):
                    ordered_loser = ordered_entry[1]['loser']
                    if equal_pair_loser == ordered_loser:
                        ordered_index = n
                        break
                if ordered_index is not None:
                    loser_entries.append({'eq_i': i, 'or_i': ordered_index})
            loser_entries.sort(
                reverse=True,
                key=lambda x: x['or_i'])  # Don't mess up indices when popping

            new_ordered_loser_entries = []
            for i, loser_entry in enumerate(loser_entries):
                next_loser_entry = None
                try:
                    next_loser_entry = loser_entries[i + 1]
                except IndexError:
                    pass
                if next_loser_entry is None or next_loser_entry[
                        'or_i'] > loser_entry['or_i']:
                    new_ordered_loser_entries.append(loser_entry['eq_i'])
            new_ordered_loser_entries.sort(
                reverse=True)  # Don't mess up indices when popping
            for i in new_ordered_loser_entries:
                ordered_entries.append(equal_pairs[i])
                equal_pairs.pop(i)

            # 2. The pair with a winner that's already listed as a winner is put first
            winner_entries = [
            ]  # All winners that are already in the ordered pairs
            for i, equal_pair in enumerate(equal_pairs):
                # Find the winner of the equal pair
                equal_pair_winner = equal_pair[1]['winner']

                # Check if the winner is already in the ordered pairs as a winner
                ordered_index = None
                for n, ordered_entry in enumerate(ordered_entries):
                    ordered_winner = ordered_entry[1]['winner']
                    if equal_pair_winner == ordered_winner:
                        ordered_index = n
                        break
                if ordered_index is not None:
                    winner_entries.append({'eq_i': i, 'or_i': ordered_index})
            winner_entries.sort(
                reverse=True,
                key=lambda x: x['or_i'])  # Don't mess up indices when popping

            new_ordered_winner_entries = []
            for i, winner_entry in enumerate(winner_entries):
                next_winner_entry = None
                try:
                    next_winner_entry = winner_entries[i + 1]
                except IndexError:
                    pass
                if next_winner_entry is None or next_winner_entry[
                        'or_i'] > winner_entry['or_i']:
                    new_ordered_winner_entries.append(winner_entry['eq_i'])
            new_ordered_winner_entries.sort(
                reverse=True)  # Don't mess up indices when popping
            for i in new_ordered_winner_entries:
                ordered_entries.append(equal_pairs[i])
                equal_pairs.pop(i)

            if len(equal_pairs) > 1:
                # 3. The pair with a loser that is least preferred by the tie breaker balllot is put first
                if not tie_breaker:
                    raise TieBreakerNeededException()

                loser_pref_indices = []
                for i, equal_pair_entry in enumerate(equal_pairs):
                    loser = equal_pair_entry[1]['loser']
                    loser_pref_indices.append({
                        'eq_i':
                        i,
                        'or_i':
                        tie_breaker_list.index(loser)
                    })

                new_ordered_tie_breaker_pairs = []
                for i, pair in enumerate(loser_pref_indices):
                    next_pair = None
                    try:
                        next_pair = loser_pref_indices[i + 1]
                    except IndexError:
                        pass
                    if (next_pair is None or next_pair['or_i'] > pair['or_i']):
                        new_ordered_tie_breaker_pairs.append(pair['eq_i'])
                new_ordered_tie_breaker_pairs.sort(
                    reverse=True)  # Don't mess up indices when popping
                for i in new_ordered_tie_breaker_pairs:
                    ordered_entries.append(equal_pairs[i])
                    equal_pairs.pop(i)

            # There should only be one pair remaining at this point
            ordered_entries.extend(equal_pairs)

    debug('\nRanked pairs')
    debug(ordered_entries)

    # Make a graph of the winning pairs
    lock = {}
    for cand in candidates:
        lock[cand] = []
    lock_entries = []
    debug('\nLock:')
    for entry in ordered_entries:
        pair = entry[1]

        lock[pair['winner']].append(pair['loser'])
        if is_cyclic(lock):
            lock[pair['winner']].remove(pair['loser'])
            continue
        lock_entries.append((pair['winner'], pair['loser']))

        debug('%s → %s' % (pair['winner'], pair['loser']))

    # Find the candidate at the root of graph (with nothing pointing to it)
    possible_winners = list(candidates)
    cands_pointed_to = set(item for sublist in lock.values()
                           for item in sublist)
    for cand in cands_pointed_to:
        possible_winners.remove(cand)
    winner = possible_winners[0]

    debug('\nWinner: %s' % (winner))

    return {
        'ballots': len(ballots),
        'blank_ballots': blank_ballots,
        'winner': winner,
        'disqualified_candidates': disqualified_candidates,
        'comp_pairs': pairs,
        'ranked_pairs': ordered_entries,
        'cand_stats': cand_stats,
        'lock': lock_entries,
        'graph': lock
    }
Example #57
0
# https://answers.splunk.com/answers/306952/return-binary-data-such-as-images-via-rest-api-or.html

# curl examples
# https://www.keycdn.com/support/popular-curl-examples

if __name__ == "__main__":

    import os

    if not os.path.exists('output'):
        os.makedirs('output')
    # URL = 'http://localhost:5000'
    URL = 'http://0.0.0.0:33'
    cam = Camera()
    status = cam.allocate_camera(URL)
    debug(f"response: {status}")

    status = cam._frame(path='output/_frame.png')
    debug(f"response: {status}")
    assert 200 == status

    status = cam.get_frame(path='output/new_frame.png')
    debug(f"response: {status}")
    assert 200 == status

    status = cam.start_live('127.0.0.1:12345')
    debug(f"response: {status}")
    assert 200 == status

    status = cam.stop_live()
    debug(f"response: {status}")
Example #58
0
 def is_correct(self, users, directories):
     debug("checking for missing directories")
     return not bool(self.missing_directories(users, directories))
Example #59
0
 def correct(self, users, directories):
     for directory in self.missing_directories(users, directories):
         debug("creating missing directory '%s'" % directory)
         self.execute_safely(mkdir, directory, mode=700)
Example #60
0
 def free_camera(self):
     debug(f"=== free_camera ===")
     if self.init is True:
         self.init = False
         self.url = None
     return 200