Skip to content

Commit

Permalink
Merge pull request #73 from OpenInternet/updated_ui
Browse files Browse the repository at this point in the history
Updated ui
  • Loading branch information
seamustuohy committed May 26, 2015
2 parents b7a5c73 + 976c1db commit b03a6f5
Show file tree
Hide file tree
Showing 65 changed files with 1,831 additions and 663 deletions.
36 changes: 8 additions & 28 deletions copilot/controllers.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
from copilot.models.trainer import get_ap_status
from copilot.models.profile import get_profile_status
from flask import flash

#stat logging
import logging
log = logging.getLogger(__name__)

def get_status_items():
"""Get current status items.
icon: the ID of the svg to use.
value: The text to put under the icon
status: [off/on/error] The color of the icon background to use (off=grey, on=green, error=orange)
"""
log.warn("TODO: get_status_items is currently not fully implemented")
profile = get_profile_status()
access_point = get_ap_status()
status_items = [{"icon":"wifi",
"value":access_point['value'],
"status":access_point['status'],
"url":"config"},
{"icon":"config",
"value":"Configure",
"status":"off",
"url":"config"},
{"icon":"profile",
"value":profile['value'],
"status":profile['status'],
"url":"profile_current"},
{"icon":"load",
"value":"Load Profile",
"status":"off",
"url":"profile_load"}]
return status_items
def flash_errors(form):
for field, errors in form.errors.items():
for error in errors:
flash(u"Error in the %s field - %s" % (
getattr(form, field).label.text,
error
), "error")
362 changes: 236 additions & 126 deletions copilot/models/config.py

Large diffs are not rendered by default.

243 changes: 133 additions & 110 deletions copilot/models/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import os
import uuid
import subprocess
from copilot.models.config import get_config_dir, get_config_file, get_valid_targets, get_valid_actions
from copilot.models.config import get_config_dir, get_config_file, get_valid_targets, get_valid_actions, get_config_writer, ProfileConfig, ProfileWriter
from copilot.models.trainer import get_trainer
from config import DNSConfig
from copilot.utils.file_sys import get_usb_dirs
from werkzeug import secure_filename

#stat logging
import logging
Expand All @@ -19,151 +20,173 @@ def get_profile_status():
current_profile = False
try:
current_profile = trainer.current
log.debug("current profile found: {0}".format(current_profile))
except:
log.warn("FIX THIS SOON (function get_profile_status)")
log.debug("No current trainer found. Returning broken profile.")
log.warn("FIX THIS SOON: wildcard exception (function get_profile_status)")
if current_profile:
if current_profile == "0":
current_profile = "No Active Profile"
profile['status'] = "on"
profile['value'] = current_profile
else:
profile['status'] = "off"
profile['value'] = "NONE"
return profile

class Profile:
def __init__(self, name, description=None, rules={}):
def get_all_profiles():
_profile_dirs = get_usb_dirs()
_profile_dirs.append(get_config_dir("profiles"))
profiles = []
for _dir in _profile_dirs:
if os.path.isdir(_dir):
for _prof in os.listdir(_dir):
p_path = os.path.join(_dir, _prof)
if os.path.isfile(p_path):
_test = ProfileConfig(p_path)
if _test.valid():
profiles.append(_prof)
return profiles


class Profile(object):
def __init__(self, name, description="A co-pilot profile", rules={}):
self.rules = []
self._profile_dir = get_config_dir("profiles")
self.profile_dir = "profiles"
self.name = name
self.profile_file = os.path.join(self.profile_dir, secure_filename(self.name))
self.description = description
if rules:
try:
for rule in rules:
self.add_rule(rule)
except ValueError as _err: #TODO add real error correction here
raise _err
@property
def profile_dir(self):
return self._profile_dir

def add_rule(self, rule):
log.debug("adding rule {0} {1} {2}".format(rule.action, rule.target, rule.sub_target))
@profile_dir.setter
def profile_dir(self, plaintext):
try:
_dir = get_config_dir(plaintext)
self._profile_dir = _dir
try:
self.profile_file = os.path.join(self.profile_dir, secure_filename(self.name))
except AttributeError as ee:
log.debug("cannot set profile_file as {0} is not initialized yet.".format(ee))
except ValueError:
raise ValueError("\"{0}\" is not a valid co-pilot directory. It cannot be set.".format(plaintext))

def add_rule(self, ruleset):
# Rapid prototyping means that I just want the rule, I don't care how it is formatted.
if isinstance(ruleset, dict):
rule = ruleset
elif isinstance(ruleset ,list):
rule = {"action":ruleset[0], "target":ruleset[1], "sub_target":ruleset[2]}
log.debug("adding rule {0} {1} {2}".format(rule['action'], rule['target'], rule['sub_target']))
config_obj = get_config_writer(rule['target'])
try:
_rule = Rule(rule.target, rule.action, rule.sub_target)
config_obj.add_rule([rule['action'], rule['target'], rule['sub_target']])
except ValueError as _err:
log.error("Error Encountered in add_rule()")
raise ValueError(_err) #TODO add real error correction here
if _rule.is_valid():
log.info("Rule is valid")
self.rules.append(_rule)
else:
log.info("Rule is NOT valid")
raise ValueError(_err) #TODO add real error correction here
self.rules.append([rule['action'], rule['target'], rule['sub_target']])

def save(self):
log.info("saving profile {0}".format(self.name))
if not os.path.exists(self._profile_dir):
os.makedirs(self._profile_dir)
profile_file = (self._profile_dir + self.name)
#Empty the file
open(profile_file, 'w').close()
#Save rules to file
for rule in self.rules:
rule.save(profile_file)
log.info("Saving profile {0} to {1}".format(self.name, self.profile_file))
if not os.path.exists(self.profile_dir):
os.makedirs(self.profile_dir)
with open(self.profile_file, "w+") as config_file:
_prof = ProfileWriter()
_prof.add_section("info")
_prof.set("info", "name", self.name)
_prof.set("info", "description", self.description)
for rule in self.rules:
_prof.set_rule(rule)
_prof.write(config_file)
log.info("Profile {0} saved".format(self.name))

def exist(self):
profile_file = (self._profile_dir + self.name)
if os.path.isfile(profile_file):
if os.path.isfile(self.profile_file):
log.info(" profile {0} exists".format(self.name))
return True
else:
log.info(" profile {0} does NOT exists".format(self.name))
return False

def refresh(self):
"""
Reload all profile values from its file.
NOTE: Does not change the profile directory.
"""
log.info("Refreshing profile from file.")
config = ProfileConfig(self.profile_file)
if not config.valid():
raise ValueError("Config file is not valid. Cannot reload config")
log.debug("Current name: {0}".format(self.name))
self.name = config.data["info"]["name"][0]
log.debug("Set profile name to {0}".format(self.name))
log.debug("Current profile file: {0}".format(self.profile_file))
self.profile_file = os.path.join(self.profile_dir, secure_filename(self.name))
log.debug("Set profile file to {0}".format(self.profile_file))
log.debug("Current description: {0}".format(self.description))
if "description" in config.data["info"]:
self.description = config.data["info"]["description"][0]
log.debug("Set description to {0}".format(self.description))
log.debug("Current rules: {0}".format(self.rules))
log.debug("clearing all existing rules")
self.rules = []
_rules = config.get_rules()
for r in _rules:
self.add_rule(r)
log.debug("Set rules to {0}".format(self.rules))

def load(self):
profile_file = (self._profile_dir + self.name)
with open(profile_file, 'r') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in csv_reader:
_rule=Rule(row[0], row[1], row[2])
self.add_rule(_rule)
"""
Load a profile from a file.
NOTE: Does not change the profile directory.
"""
log.info("Loading profile.")
log.debug("Using profile at {0}".format(self.profile_file))
config = ProfileConfig(self.profile_file)
if not config.valid():
raise ValueError("Config file is not valid. Cannot load config")
self.name = config.data["info"]["name"][0]
log.debug("Set profile name to {0}".format(self.name))
self.profile_file = os.path.join(self.profile_dir, secure_filename(self.name))
log.debug("Set profile file to {0}".format(self.profile_file))
if "description" in config.data["info"]:
self.description = config.data["info"]["description"][0]
log.debug("Set description to {0}".format(self.description))
_rules = config.get_rules()
for r in _rules:
self.add_rule(r)
log.debug("Set rules to {0}".format(self.rules))

def apply_config(self):
_configs = {}
log.info("Applying profile {0}".format(self.name))
trainer = get_trainer() #Save as current profile for trainer.
trainer.current = self.name
db.session.commit()

configs = {}
log.info("looking for config files that need to be written.")
_targets = get_valid_targets()
for r in self.rules:
if r.target not in _configs:
#TODO This needs to be replaced with some sort of config file that checks the proper config object to instantiate when a specific config type is passed.
if r.target == "dns":
log.debug("Creating a {0} config".format("dnschef"))
_configs["dns"] = DNSConfig()
log.debug("Adding a rule ({0} {1}) to dnschef config.".format(r.action, r.sub_target))
_configs["dns"].add_rule(r.target, r.action, r.sub_target)
_action = r[0]
_tar = r[1]
_sub = r[2]
if _tar not in configs:
log.debug("Creating a {0} config".format(_tar))
configs[_tar] = get_config_writer(_tar)
log.debug("Adding a rule ({0} {1}) to {2} config.".format(_tar, _action, _sub))
configs[_tar].add_rule([_action, _tar, _sub])
else:
if r.target == "dns":
log.debug("Adding a rule ({0} {1}) to dnschef config.".format(r.action, r.sub_target))
_configs["dns"].add_rule(r.target, r.action, r.sub_target)
for c in _configs:
log.debug("Adding a rule ({0} {1}) to {2} config.".format(_tar, _action, _sub))
configs[_tar].add_rule([_action, _tar, _sub])
for c in configs:
log.debug("Writing {0} config.".format(c))
_configs[c].write()

class Rule:

def __init__(self, target, action, sub_target=""):
self.valid_actions = get_valid_actions()
self.valid_targets = get_valid_targets()
self.errors = {}
self.target = target
self.action = action
self.sub_target = sub_target
self.uuid = uuid.uuid4()

def init_validators(self):
"""TODO Make these actually validate address'"""
self.valid_sub_targets = {
url : True,
dns : True}

def save(self, save_file):
with open(save_file, 'a') as csvfile:
csv_writer = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
csv_writer.writerow([self.target, self.action, self.sub_target])

def is_valid(self):
if self.errors:
return False
else:
return True

@property
def target(self):
return self._target

@target.setter
def target(self, plaintext):
try:
value_to_set = self.valid_targets.index(string.lower(plaintext))
self._target = plaintext
except ValueError:
raise ValueError("The target \"{0}\" is invalid.".format(plaintext))

@property
def sub_target(self):
return self._sub_target

@sub_target.setter
def sub_target(self, plaintext):
#If a target is not set then we cannot check the sub-target against it.
if not self._target:
raise ValueError("The sub-target \"{0}\" cannot be set without a valid target.".format(plaintext))
print("TODO Validate sub-targets.")
self._sub_target = plaintext

@property
def action(self):
return self._action

@action.setter
def action(self, plaintext):
try:
value_to_set = self.valid_actions.index(string.lower(plaintext))
self._action = plaintext
except ValueError:
raise ValueError("The action \"{0}\" is invalid.".format(plaintext))
configs[c].write()
Loading

0 comments on commit b03a6f5

Please sign in to comment.