예제 #1
0
def get_winner_item(attempts):
    # we won, we won, we won!
    config.put("lingo.last.action", "gamewon")
    # update the average moves taken

    won = config.get("games_won")
    played = config.get("games_played")
    average = config.get("average_moves")
    if config.get("stats"):
        won = won + 1
        played = played + 1
        average = ((won - 1) * average + len(attempts)) / ((won) * 1.0)
        config.put("average_moves", average)
        config.put("games_played", played)
        config.put("games_won", won)
        config.put("stats", False)
    subtitle = "won {1} of {0} played | {3:.0f}% | {2:.1f} attempts on average".format(
        played, won, average, (100.0 * won) / (played)
    )
    return alfred.Item(
        attributes={"uid": uuid4(), "arg": "another_round", "valid": "yes", "autocomplete": ""},
        title="You won!",
        subtitle=subtitle,
        icon="icon.png",
    )
예제 #2
0
파일: wifi.py 프로젝트: smeenka/esp32
def connect2ap(ssid=None, pw=None):
    """ If pw is None get the password from the config file 
        If pw is not None, write ssid,pw to the config file

        If ip is None in config file choose dhcp config
        else get ip. 
        If gw is None  it is assumed as 192.168.2.254, 
        If dns is None it is assumed as 192.168.2.254, 
        Deactivate the wlan, wait 1 second and activate with given ssid and pw
    """
    log.info("Connecting to ap %s", ssid)

    if not ssid:
        ssid = config.get("ssid", "xxxx")
    else:
        config.put("ssid", ssid)

    if not pw:
        pw = config.get(ssid, "geheim")
    else:
        config.put(ssid, pw)

    ip = config.get("wlan_ip")
    gw = config.get("wlan_gw", "192.168.2.254")
    dns = config.get("wlan_dns", "192.168.2.254")
    config.save()

    wlan.active(False)
    wlan.active(True)
    if ip:
        wconf = (ip, '255.255.255.0', gw, dns)
        wlan.ifconfig(wconf)
    wlan.connect(ssid, pw)
예제 #3
0
    def checkSummerWinter(self):
        now = time.localtime()
        offset = 1
        year = now[0]
        month = now[1]
        day = now[2]
        try:
            tup = self.zomertijdTabel[year]
            if 3 < month < 10:
                offset = 2

            elif month == 3 and day >= tup[0]:
                offset = 2
            elif month == 10 and day < tup[1]:
                offset = 2
        except:
            pass

        timeOffset = config.get('timeoffset', 1)

        if offset != timeOffset:
            if offset == 2:
                log.info("Changing to summertime")
            else:
                log.info("Changing to wintertime")
            config.put("timeoffset", offset)
예제 #4
0
파일: setup.py 프로젝트: BenziAhamed/todo
def update_todo_db_path(new_home):
    # move all yaml files that are present in the current home folder
    # to the destination home folder
    home, db = os.path.split(config.get(ck.KEY_TODO))
    if home == new_home:
        print "'{0}' is already your home folder".format(new_home)
        return

    lists, active = listmanager.get_todo_lists()
    conflicts = []
    for l in lists:
        src = os.path.join(home, l)
        dest = os.path.join(new_home, l)
        if os.path.exists(src):
            if not os.path.exists(dest):
                shutil.move(src, new_home)
            else:
                conflicts.append(listmanager.friendly_file(l))

    # update the active list
    config.put(ck.KEY_TODO, os.path.join(new_home, active))

    print "'{0}' is now your Todo home folder".format(new_home)
    if len(conflicts) > 0:
        print "not migrated: " + ",".join(conflicts)
예제 #5
0
def migrate_todo_list(source_path, destination_path, migration_option):
    source_file = os.path.join(source_path, "todo.yaml")
    destination_file = os.path.join(destination_path, "todo.yaml")

    if migration_option == "no_conflict":
        # Case A: file in source, move to destination
        if os.path.exists(source_file):
            shutil.move(source_file, destination_path)
        # Case B: no file in source, nothing to do
        # Case C: file in destination, leave it as is
        # Now update the config to point to new location
        config.put(ck.KEY_TODO, destination_file)

    elif migration_option == "keep_old":
        # Move the old file to the new location
        if os.path.exists(destination_file):
            os.remove(destination_file)
        shutil.move(source_file, destination_path)
        config.put(ck.KEY_TODO, destination_file)

    elif migration_option == "keep_new":
        # We do not touch the old file
        config.put(ck.KEY_TODO, destination_file)

    elif migration_option == "merge":
        old_todos = []
        with open(source_file) as source:
            old_todos = source.readlines()
        with open(destination_file, "a") as destination:
            destination.write(old_todos)
        config.put(ck.KEY_TODO, destination_file)

    config.put('todo.db.destination_path', '')
예제 #6
0
def refresh_lists():
    if not is_enabled() or not is_authenticated():
        return

    (path, db) = os.path.split(config.get(ck.KEY_TODO))

    if is_authenticated():
        api = create_rtm()
        s = api.settings.getList()
        lists = api.lists.getList()
        for l in lists.lists.list:
            if l.archived == '0' and l.smart == '0' and l.deleted == '0':
                if l.name == 'Sent':
                    continue
                info = {'id': l.id,'name':l.name}
                # now that we have a list of todos, create local copies
                # of list files as reference, in JSON format
                # filename = 'name.rtm-todolist'
                list_file = os.path.join(path, l.name+'.rtm-todolist')
                if os.path.exists(list_file):
                    os.remove(list_file)
                with codecs.open(list_file, "w", "utf-8") as f:
                    json.dump(info, f)
                if s.settings.defaultlist == l.id:
                    config.put(ck.KEY_TODO, list_file)
예제 #7
0
파일: formats.py 프로젝트: BenziAhamed/todo
def set_format(format):
    config.put(ck.KEY_FORMAT_DEFAULT, format)
    # check if the current todo db exists
    # if not, update its extension
    todo_db = config.get(ck.KEY_TODO)
    if not todo_db.endswith(format):
        config.put(ck.KEY_TODO, os.path.splitext(todo_db)[0]+format)
    print mapping[format]['title'] + ' is now default'
예제 #8
0
파일: edit.py 프로젝트: BenziAhamed/todo
def integration_action(task):
    edit_item = config.get(ck.KEY_EDIT_ITEM)
    _id = helpers.extract_todo_id(edit_item)
    todo = itemlist.get_todo(_id)['title']
    if task.startswith("eggtimer:"):
        alarm_time = task.replace("eggtimer:", "")
        alarm_command = "alarm " + alarm_time + " " + todo
        config.put(ck.KEY_EDIT_ACTION, 'integration')
        config.put(ck.KEY_INTEGRATION_COMMAND, alarm_command)
예제 #9
0
def delete_list(todo_file):
    if not todo_file.startswith('action.'):
        (path, todo_filename) = os.path.split(todo_file)
        if store.Store().get_store(todo_file).delete_list():
            print "Removed list '" + friendly_file(todo_filename) + "'"
            lists, active = get_todo_lists()
            if todo_file==config.get(ck.KEY_TODO):
                config.put(ck.KEY_TODO, os.path.join(path, lists[0]))
    alfred.show('list ')
예제 #10
0
    def handleStationSettings(self, request):
        path = request.path
        value = json.loads(request.body)
        v = int(value["v"])
        log.debug("Path: %s Post:%s value %d", request.path, request.body, v)
        key = request.path[10:]
        config.put(key, v)
        log.debug("put dirty:%s", config.dirty)

        yield from request.sendOk()
예제 #11
0
def get_todo_lists():
    (path, db) = os.path.split(config.get(ck.KEY_TODO))
    lists = [f for f in os.listdir(path) if is_supported_file(f)]
    # remove config.yaml
    if 'config.yaml' in lists:
        lists.remove('config.yaml')
    if len(lists) == 0:
        lists.append('todo' + default_format())
        config.put(ck.KEY_TODO, os.path.join(path, 'todo'+default_format()))
    return sorted(lists), db
예제 #12
0
파일: edit.py 프로젝트: BenziAhamed/todo
def update_tag(old_tag, query):
    info = parser.parse(query)
    new_tag = info['tag']

    if not new_tag:
        return

    itemlist.update_tag(old_tag, new_tag)

    config.put(ck.KEY_EDIT_ACTION, 'edit_tag')
    print ("Updated tag #" + old_tag + " to #" + new_tag).encode('utf-8')
예제 #13
0
def get_timeline():
    # check if we have a saved timeline
    tl = config.get(ck.KEY_RTM_TIMELINE, None)
    tl_age = config.get(ck.KEY_RTM_TIMELINE_AGE, 0)
    diff = mktime(datetime.now().timetuple()) - tl_age
    # check if we need to refresh
    if tl is None or diff > 86400:
        api = create_rtm()
        config.put(ck.KEY_RTM_TIMELINE, api.timelines.create().timeline)
        config.put(ck.KEY_RTM_TIMELINE_AGE, mktime(datetime.now().timetuple()))
    return config.get(ck.KEY_RTM_TIMELINE, None)
예제 #14
0
def actionize(query):
	if len(query) <= 0:
		return
	have_tag = helpers.is_tag(query)
	have_todo = helpers.is_todo(query)

	if not (have_tag or have_todo):
		itemlist.save_todo(query)
	elif have_todo:
		itemlist.copy_todo_to_clipboard(helpers.extract_todo_id(query))
	elif have_tag:
		config.put('todo.tag.recent', "#"+helpers.extract_tag(query))
예제 #15
0
def main():
    (option, arg) = alfred.args2()
    if option == "-view":
        config.put('todo.db.destination_path', arg)
        generate_view(arg)
    elif option == "-migrate":
        migrate_todo_list(
            os.path.dirname(config.get(ck.KEY_TODO)),
            config.get('todo.db.destination_path'),
            arg
        )
    config.commit()
예제 #16
0
def actionize(query):
    if len(query) <= 0:
        return
    have_tag = helpers.is_tag(query)
    have_todo = helpers.is_todo(query)

    if not (have_tag or have_todo):
        itemlist.save_todo(query)
    elif have_todo:
        itemlist.copy_todo_to_clipboard(helpers.extract_todo_id(query))
    elif have_tag:
        config.put('todo.tag.recent', "#" + helpers.extract_tag(query))
예제 #17
0
 def recordDownloads(cls, key, count):
   config = BootConfiguration.get(key)
   
   now = datetime.datetime.now()
   decay_time = now - config.last_decay
   decay_fraction = timedelta_to_seconds(decay_time) / MEAN_DOWNLOAD_LIFETIME
   
   config.downloads = config.downloads * (math.e ** -decay_fraction) + count
   logging.warn(config.downloads)
   config.last_decay = now
   config.put()
   return config
예제 #18
0
파일: edit.py 프로젝트: BenziAhamed/todo
def process_query(query):
    if query.startswith("_integration:"):
        integration_action(query.replace("_integration:", ""))
        return
    edit_item = config.get(ck.KEY_EDIT_ITEM)
    have_tag = helpers.is_tag(edit_item)
    have_todo = helpers.is_todo(edit_item)
    if have_todo:
        _id = helpers.extract_todo_id(edit_item)
        update_todo(_id, query)
    elif have_tag:
        update_tag(helpers.extract_tag(edit_item), query)
    config.put(ck.KEY_EDIT_ITEM, '')
예제 #19
0
def toggle_feature(feature):
    current = False
    if not feature.startswith('special'):
        current = config.get(feature) == True
        config.put(feature, not current)
        feature = [f for f in features if f['id']==feature][0]
        print feature['title'] + ' ' + ("disabled" if current else "enabled")
    else:
        set_all( True if feature=='special_enable' else False )

    # post toggle actions
    if feature['id']==ck.KEY_FEATURE_RTM:
        if config.get(ck.KEY_FEATURE_RTM) == False:
            rtm.reset()
예제 #20
0
def update_todo_db_path(path_for_todo_db):
	# before updating the config, check if a todo file
	# is already present. If yes, move existing file to the
	# new location.
	# If a file already exists at the destination, issue a warning
	new_todo_db = os.path.join(path_for_todo_db, "todo.yaml")
	if os.path.exists(new_todo_db):
		print "Oops! Looks like a todo.yaml file already exists in {0}".format(path_for_todo_db)
		return

	old_todo_db = config.get('todo.db')
	if os.path.exists(old_todo_db):
		shutil.move(old_todo_db, path_for_todo_db)
	
	config.put('todo.db', new_todo_db)
	print "'{0}' is now configured as your Todo database folder".format(path_for_todo_db)
예제 #21
0
파일: wifi.py 프로젝트: smeenka/esp32
def startap(ssid=None, pw=None):
    if ssid:
        config.put("ap_ssid", ssid)
    ssid = config.get("ap_ssid", "micropython2")

    if pw:
        config.put("ap_pw", pw)
    pw = config.get("ap_pw", "12345678")
    config.save()

    log.info("Starting AP with ssid:%s", ssid)

    ap.active(False)
    time.sleep_ms(100)
    ap.active(True)
    time.sleep_ms(100)
    ap.config(essid=ssid, channel=11, password=pw)
예제 #22
0
파일: neostate.py 프로젝트: smeenka/esp32
    def updateFromConfig(self):
        self.neo.offset = config.get("offset")

        q = config.get("quarters")
        if q > 100:
            q = 100
            config.put("quarters", q)
        if q < 0:
            q = 0
            config.put("quarters", q)
        self.qColor = (q, q, q)
        b = config.get("brightness", 50)
        if b > 100:
            b = 100
        if b < 0:
            b = 0
        self.neo.brightness = b
예제 #23
0
def save_todo(raw_task, silent=False):
    newtodo = parse_todo_text(raw_task)
    task = newtodo['title']
    tag = newtodo['group']
    if len(task) == 0:
        return

    smartcontent.process_todo(newtodo)
    datastore.instance.save_todo(newtodo)

    if not silent:
        if tag != 'default':
            print ("Added '" + task + "' tagged #" + tag).encode('utf-8')
        else:
            print ("Added '" + task + "'").encode('utf-8')

    config.put(ck.KEY_USER_QUERY_NOITEMPREFIX, '')
    config.update_state(command='add_todo', tag='#'+tag)
예제 #24
0
def action(query):
    if query.startswith("action."):
        # custom actions from list view
        # for now, its all todo with Remember the Milk
        action_options = {
            'action.rtm.init_auth': lambda: action_rtm_init_auth(),
            'action.rtm.end_auth': lambda: action_rtm_end_auth(),
            'action.rtm.refresh': lambda: action_rtm_refresh()
        }
        action_options[query]()
        alfred.show('list ')
    else:
        todo_file = query
        if todo_file!=config.get(ck.KEY_TODO):
            if not os.path.exists(todo_file):
                store.Store().get_store(todo_file).clear_all_todos()
            config.put(ck.KEY_TODO, todo_file)
        alfred.show('todo ')
예제 #25
0
파일: todo.py 프로젝트: BenziAhamed/todo
def actionize(query):
    if len(query) <= 0:
        return
    have_tag = helpers.is_tag(query)
    have_todo = helpers.is_todo(query)

    if not (have_tag or have_todo):
        itemlist.save_todo(query)
    elif have_todo:
        _id = helpers.extract_todo_id(query)

        # smart content is a bit rudimentary at the moment
        if smartcontent.smartcontent_enabled():
            smartcontent.perform_action(_id)
        else:
            itemlist.copy_todo_to_clipboard(_id)

    elif have_tag:
        config.put(ck.KEY_TAG_RECENT, "#"+helpers.extract_tag(query))
예제 #26
0
def get_solution_item():
    config.put("lingo.last.action", "gameover")
    if config.get("stats"):
        config.put("games_played", config.get("games_played") + 1)
        config.put("games_lost", config.get("games_lost") + 1)
        config.put("stats", False)
    return alfred.Item(
        attributes={"uid": uuid4(), "arg": "another_round", "valid": "yes", "autocomplete": ""},
        title="The word was {0}".format(config.get("target").upper()),
        subtitle="Why not try another round?",
        icon="icon.png",
    )
예제 #27
0
def delete_list(todo_file):
    if not todo_file.startswith('action.'):
        (path, todo_filename) = os.path.split(todo_file)
        # rtm special
        if todo_filename.endswith('.rtm-todolist'):
            if todo_filename.startswith("Inbox"):
                print "Cannot delete Inbox"
                todo_file = ''
            else:
                print "Deleting an RTM list is currently not allowed"
                todo_file = ''
        else:
            if os.path.exists(todo_file):
                os.remove(todo_file)
            print "Removed list '" + friendly_file(todo_filename) + "'"
        # if we removed the active one, switch to a new active list
        lists, active = get_todo_lists()
        if todo_file==config.get(ck.KEY_TODO):
            config.put(ck.KEY_TODO, os.path.join(path, lists[0]))
    alfred.show('list ')
예제 #28
0
def get_typed_item(guess):
    length = len(guess)
    already_attempted = word_in_attempts(guess)

    valid = length == 5 and not already_attempted
    subtitle = "Enter a guess"
    config.put("lingo.last.action", False)

    if already_attempted:
        subtitle = "You already played that"
    elif length == 5:
        subtitle = "Have a go!"
        config.put("lingo.last.word", guess)
        config.put("lingo.last.action", True)
    elif length > 5:
        subtitle = "Must be 5 letters long"

    if length > 5:
        guess = guess[:5]

    guess = guess.replace(" ", "_") + "_" * (5 - length)

    return alfred.Item(
        attributes={"uid": uuid4(), "arg": guess, "valid": "no", "autocomplete": ""},
        title=guess.upper() + "   ",  # hack
        subtitle=subtitle,
        icon="guess.png",
    )
예제 #29
0
def make_new_game():
    config.put('inplay', True)
    config.put('attempts', [])

    difficulty = config.get('difficulty')
    words = []
    with open(difficulty + '.txt') as f:
        words = [line.strip() for line in f]
    target = choice(words)
    hint1 = randrange(0, 5)
    hint2 = randrange(0, 4)
    if hint2 >= hint1:
        hint2 = (hint2 + 1) % 5
    hint = ['_', '_', '_', '_', '_']
    hint[hint1] = target[hint1].upper()
    hint[hint2] = target[hint2].upper()
    hint = "".join(hint)
    config.put('target', target)
    config.put('hint', hint)
    config.put('stats', True)

    print(target, hint)
예제 #30
0
def make_new_game():
	config.put('inplay', True)
	config.put('attempts', [])

	difficulty = config.get('difficulty')
	words = []
	with open(difficulty + '.txt') as f:
		words = [line.strip() for line in f]
	target = choice(words)
	hint1 = randrange(0,5)
	hint2 = randrange(0,4)
	if hint2>=hint1:
		hint2 = (hint2+1)%5
	hint = [ '_', '_', '_', '_', '_']
	hint[hint1] = target[hint1].upper()
	hint[hint2] = target[hint2].upper()
	hint = "".join(hint)
	config.put('target', target)
	config.put('hint', hint)
	config.put('stats', True)
	
	print (target, hint)
예제 #31
0
파일: edit.py 프로젝트: BenziAhamed/todo
def update_todo(_id, query):
    info = parser.parse(query)
    todo = itemlist.get_todo(_id)

    done = itemlist.feature(todo, 'done')

    edit_tag = info['tag']
    edit_text = info['task']
    edit_due = info['due']
    edit_clear_due = info['clear_due']
    todo_tag = todo['group']
    todo_text = todo['title']
    todo_due = itemlist.feature(todo, 'due')

    tag_changed = edit_tag and edit_tag != todo_tag
    task_changed = len(edit_text) > 0 and edit_text != todo_text
    due_changed = edit_due and edit_due != todo_due
    title = todo['title']
    tag = todo['group']
    update_info = {}
    if (task_changed):
        update_info['title'] = edit_text
        title = edit_text
    if (tag_changed):
        update_info['group'] = edit_tag
        tag = edit_tag
    if (due_changed):
        update_info['due'] = edit_due
    if edit_clear_due:
        update_info['due'] = None

    itemlist.update_todo(_id, update_info)

    config.put(ck.KEY_EDIT_ACTION, 'edit_done' if done else 'edit_todo')
    if tag != 'default':
        print ("Updated '" + title + "' tagged #" + tag).encode('utf-8')
    else:
        print ("Updated '" + title + "'").encode('utf-8')
예제 #32
0
def process_guess(guess):
    # a simple method to avoid the flickering Alfred
    # uses the autocomplete feature of non valid items
    # to maintain an internal state
    #
    # Knowing this state allows us to recognize that the user
    # is actioning a non-valid item but the state variable
    # helps us to validate the action none the less
    # This only works because Alfred fires the script on
    # every key press!
    feedback_items = []
    if config.get("lingo.last.action") == True and len(guess) == 0:
        add_guess(config.get("lingo.last.word"))
        config.put("lingo.last.action", False)
        config.put("lingo.last.word", "")
        # elif config.get('lingo.last.action') == 'gameover' or config.get('lingo.last.action') == 'gamewon':
        # 	newgame.make_new_game()
        #  	config.put('lingo.last.action', False)
        #  	config.put('lingo.last.word','')
    if config.get("inplay") == False:
        feedback_items.append(no_game())
    else:
        attempts = config.get("attempts")
        gameover = False
        if len(attempts) > 0 and attempts[-1]["outcome"] == "won":
            feedback_items.append(get_winner_item(attempts))
        elif len(attempts) == 5:
            feedback_items.append(get_solution_item())
            feedback_items.append(get_target_item(config.get("hint"), gameover=True))
        else:
            # feedback for typed item
            feedback_items.append(get_typed_item(guess.lower()))
            # feedback for word to guess
            feedback_items.append(get_target_item(config.get("hint")))
            # feedback for all attempted words
        feedback_items = feedback_items + get_attempt_items()
    alfred.write(alfred.xml(feedback_items))
예제 #33
0
def end_auth():
    api = rtm.createRTM(apikey, secret, token=None)
    api.setFrob(config.get(ck.KEY_RTM_FROB))
    token = api.getToken()
    config.put(ck.KEY_RTM_TOKEN, token)
    config.put(ck.KEY_RTM_AUTH_INPROGRESS, False)
예제 #34
0
def init_auth():
    api = rtm.createRTM(apikey, secret, token=None)
    config.put(ck.KEY_RTM_AUTH_INPROGRESS, True)
    config.put(ck.KEY_RTM_FROB, api.getFrob())
    config.put(ck.KEY_RTM_AUTH_STARTED, mktime(datetime.now().timetuple()))
    call(['open', api.getAuthURL()])
예제 #35
0
def reset():
    config.put(ck.KEY_RTM_TOKEN, '')
    config.put(ck.KEY_RTM_FROB, '')
    config.put(ck.KEY_RTM_AUTH_INPROGRESS, False)
    config.put(ck.KEY_RTM_AUTH_STARTED, 0)
    config.put(ck.KEY_RTM_TIMELINE, 0)
    config.put(ck.KEY_RTM_TIMELINE_AGE, 0)

    (path, db) = os.path.split(config.get(ck.KEY_TODO))

    # delete all saved lists
    lists = [f for f in os.listdir(path) if f.endswith('.rtm-todolist')]
    for l in lists:
        l = os.path.join(path, l)
        if os.path.exists(l):
            os.remove(l)
예제 #36
0
def add_guess(guess):
    # get the current list of attempts
    attempts = config.get("attempts")
    if len(attempts) == 5:
        return

    attempt = {}

    valid_word = word_in_list(guess)
    if not valid_word:
        g = list(guess.lower())
        # add some spacing for the guess
        i = 0
        while i < 5:
            if len(g[i]) == 1:
                g[i] = "_".format(g[i])
            i += 1
        final_guess = " ".join(g).strip()
        attempt = {"guess": final_guess, "original": guess, "outcome": "badword"}
    else:
        # make uppercase all letters in the right place
        t = list(config.get("target"))
        g = list(guess.lower())
        matched = [False, False, False, False, False]
        i = 0
        while i < 5:
            if g[i] == t[i]:
                g[i] = u"{0}".format(g[i].upper())
                matched[i] = True
            i += 1
            # highlight all letters in the guess word that may not be in the right pos
        i = 0
        while i < 5:
            if g[i].islower():  # unprocessed
                j = 0
                while j < 5:
                    if not matched[j] and g[i] == t[j]:
                        g[i] = u" [{0}]".format(g[i])
                        matched[j] = True
                    j += 1
            i += 1

            # update the original hint with all letters in correct place
        h = list(config.get("hint"))
        i = 0
        while i < 5:
            if g[i].isupper():
                h[i] = g[i]
            i += 1

            # add some spacing for the guess
        i = 0
        while i < 5:
            if len(g[i]) == 1:
                g[i] = " {0}".format(g[i])
            i += 1

        final_hint = "".join(h)
        final_guess = "".join(g).strip()
        config.put("hint", final_hint)
        attempt = {
            "guess": final_guess,
            "original": guess,
            "outcome": "won" if guess.upper() == final_hint else "inplay",
        }

    attempts.append(attempt)
    config.put("attempts", attempts)
예제 #37
0
def set_all(target):
    for f in features:
        config.put(f['id'], target)
    print "All features enabled" if target else "All features disabled"