<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor, defer

import os
from os import listdir, makedirs, path
from os.path import isfile, join
from io import StringIO

import sys, signal, json, logging
from twisted.internet.error import MulticastJoinError
import time
import pwd, grp
import re

sys.path.append('/opt/marcopolo')
from marco_conf import conf


__author__ = '<NAME>'

offered_services = []
user_services = {}

verify = re.compile('^([\d\w]+):([\d\w]+)$')

def reload_user_services(user):
	try:
		user = pwd.getpwnam(user)
	except KeyError:
		return
	
	if path.exists(user.pw_dir):
		polo_dir = path.join(user.pw_dir,conf.POLO_USER_DIR)
		username = user.pw_name
		user_services[username] = [service for service in user_services.get(username, []) if service[1] == False]
		
		servicefiles = [ join(polo_dir, f) for f in listdir(polo_dir) if isfile(join(polo_dir,f)) ]
		
		fileservices = []
		for service in servicefiles:
			try:
				with open(service, 'r', encoding='utf-8') as f:
					s = json.load(f)
					s["permanent"] = True
					if not verify.match(s['id']):
						fileservices.append(s)

			except ValueError:
				logging.debug(str.format("The file {0} does not have a valid JSON structures", conf.SERVICES_DIR+service))

		user_services[username] = user_services[username] + fileservices

def reload_services(sig, frame):
	signal.signal(signal.SIGUSR1, signal.SIG_IGN)
	global offered_services
	offered_services = []
	logging.info("Reloading services")
	
	servicefiles = [ f for f in listdir(conf.CONF_DIR + conf.SERVICES_DIR) if isfile(join('/etc/marcopolo/polo/services',f)) ]

	for service in servicefiles:
		try:
			with open(join(conf.CONF_DIR+conf.SERVICES_DIR, service), 'r', encoding='utf-8') as f:
				service = json.load(f)
				service["permanent"] = True
				offered_services.append(json.load(f))
		except ValueError:
			logging.debug(str.format("The file {0} does not have a valid JSON structures", conf.SERVICES_DIR+service))

	for user in user_services:
		reload_user_services(user)

	logging.info("Reloaded: Offering " + str(len(offered_services)) + " services")
	
	signal.signal(signal.SIGUSR1, reload_services)

def sanitize_path(path_str):
	return path.normpath("/"+path_str).lstrip('/')

def is_superuser(user):
	"""
	Returns `True` if the user is a 'superuser' (it is root or it a member of the `marcopolo` group)
	
	:param string user: `pwd` structure with all the information from the user
	<commit_msg>Minor fix with str formatting<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor, defer

import os
from os import listdir, makedirs, path
from os.path import isfile, join
from io import StringIO

import sys, signal, json, logging
from twisted.internet.error import MulticastJoinError
import time
import pwd, grp
import re

sys.path.append('/opt/marcopolo')
from marco_conf import conf


__author__ = '<NAME>'

offered_services = []
user_services = {}

verify = re.compile('^([\d\w]+):([\d\w]+)$')

def reload_user_services(user):
	try:
		user = pwd.getpwnam(user)
	except KeyError:
		return
	
	if path.exists(user.pw_dir):
		polo_dir = path.join(user.pw_dir,conf.POLO_USER_DIR)
		username = user.pw_name
		user_services[username] = [service for service in user_services.get(username, []) if service[1] == False]
		
		servicefiles = [ join(polo_dir, f) for f in listdir(polo_dir) if isfile(join(polo_dir,f)) ]
		
		fileservices = []
		for service in servicefiles:
			try:
				with open(service, 'r', encoding='utf-8') as f:
					s = json.load(f)
					s["permanent"] = True
					if not verify.match(s['id']):
						fileservices.append(s)

			except ValueError:
				logging.debug(str.format("The file {0} does not have a valid JSON structures", conf.SERVICES_DIR+service))

		user_services[username] = user_services[username] + fileservices

def reload_services(sig, frame):
	signal.signal(signal.SIGUSR1, signal.SIG_IGN)
	global offered_services
	offered_services = []
	logging.info("Reloading services")
	
	servicefiles = [ f for f in listdir(conf.CONF_DIR + conf.SERVICES_DIR) if isfile(join('/etc/marcopolo/polo/services',f)) ]

	for service in servicefiles:
		try:
			with open(join(conf.CONF_DIR+conf.SERVICES_DIR, service), 'r', encoding='utf-8') as f:
				service = json.load(f)
				service["permanent"] = True
				offered_services.append(json.load(f))
		except ValueError:
			logging.debug(str.format("The file {0} does not have a valid JSON structure", conf.SERVICES_DIR+service.get("id")))

	for user in user_services:
		reload_user_services(user)

	logging.info("Reloaded: Offering " + str(len(offered_services)) + " services")
	
	signal.signal(signal.SIGUSR1, reload_services)

def sanitize_path(path_str):
	return path.normpath("/"+path_str).lstrip('/')

def is_superuser(user):
	"""
	Returns `True` if the user is a 'superuser' (it is root or it a member of the `marcopolo` group)
	
	:param string user: `pwd` structure with all the information from the user
	
{'fraction_non_alphanumeric': 0.12629318758539917, 'fraction_numerical': 0.0035135662697638103, 'mean_word_length': 4.680709534368071, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3183931', 'n_tokens_mistral': 1888, 'n_tokens_neox': 1737, 'n_words': 448}