import json
import sys
import string
import random
import re

from argparse import ArgumentParser

def read_conf():
	return json.load(open('test.json'))

def sites_by_category(conf, category):
	return [site for site in conf["sites"] if site["category"] == category]

def look_for_available_keycode(conf, name, category):
	letters = set(name)
	for site in sites_by_category(conf, category):
		letters = letters.difference(site["keycode"])
	return list(letters)

def random_keycode(conf, category):
	return random.sample(set(string.ascii_lowercase).difference(set("".join(site["keycode"] for site in sites_by_category(conf, category)))), 1)[0]

def add_category(conf, category):
	new_obj = dict()
	try:
		keycode = look_for_available_keycode(conf, args.name, args.category)[0]
		shown_name = args.name.replace(keycode, "[%s]"%keycode, 1) #replace only the first one
	except:
		print "all keys are taken, giving random keycode..."
		keycode = random_keycode(doc, args.category)
		shown_name = args.name + " [%s]"%keycode
	new_obj["keycode"] = keycode
	new_obj["shown_name"] = shown_name
	new_obj["name"] = category
	conf["category"].append(new_obj)


def add_site(parameters):
	parser = ArgumentParser()
	parser.add_argument('link', metavar='link',
		               type=str,
		               help="the link to the site you want to add")
	parser.add_argument('name', metavar="name", type=str,
		               help="the name you want to see on the screen")
	parser.add_argument('category', type=str,
		               help="the category the site belongs to")
	args = parser.parse_args(parameters)

	doc = read_conf()
	new_obj = dict()
	try:
		keycode = look_for_available_keycode(doc, args.name, args.category)[0]
		shown_name = args.name.replace(keycode, "[%s]"%keycode)
	except:
		print "all keys are taken, giving random keycode..."
		keycode = random_keycode(doc, args.category)
		shown_name = args.name + " [%s]"%keycode
	new_obj["keycode"] = keycode
	new_obj["shown_name"] = shown_name
	new_obj["category"] = args.category
	new_obj["link_properties"] = {"link": args.link}
	doc["sites"].append(new_obj)
	if not sites_by_category(doc, args.category):
		add_category(doc, args.category)
	json.dump(doc, open("test.json", "w"))

def remove_site(parameters):
	parser = ArgumentParser()
	parser.add_argument('name', metavar="name", type=str,
		               help="the name you want to remove (with no [k]eycodes)")
	args = parser.parse_args(parameters)
	doc = read_conf()
	size_before_deletion = len(doc["sites"])
	doc["sites"] = filter(lambda site: site["shown_name"].replace("[", "").replace("]", "") != args.name, doc["sites"])
	if(size_before_deletion == len(doc["sites"])): #no removal
		doc["sites"] = filter(lambda site: re.sub(" \[[a-z]\]$", "", site["shown_name"]) != args.name, doc["sites"])
	#don't add the automatic category removal, for now
	json.dump(doc, open("test.json", "w"))

functions = {
	"site add": add_site,
	"site remove": remove_site
}

if __name__ == '__main__':
	try:
		functions[" ".join(sys.argv[1:3])](sys.argv[3:])

	except KeyError:
		print "it should be:", "\n* ".join(functions.keys())
@@ -1,12 +1,50 @@
+from __future__ import print_function%0A
 import json%0A
@@ -903,33 +903,33 @@
 %09except:%0A%09%09print
- 
+(
 %22all keys are ta
@@ -950,32 +950,33 @@
 ndom keycode...%22
+)
 %0A%09%09keycode = ran
@@ -1816,17 +1816,17 @@
 %0A%09%09print
- 
+(
 %22all key
@@ -1863,16 +1863,17 @@
 code...%22
+)
 %0A%09%09keyco
@@ -2926,16 +2926,533 @@
  %22w%22))%0A%0A
+def list_sites(parameters=None):%0A%09doc = read_conf()%0A%09categories = dict()%0A%09for site in doc%5B%22sites%22%5D:%0A#%09%09print(%22 %22.join((site%5B%22shown_name%22%5D, %22-%3E%22, site%5B%22link_properties%22%5D%5B%22link%22%5D, %22in category%22, site%5B%22category%22%5D)))%0A%09%09try: categories%5Bsite%5B%22category%22%5D%5D.append(site)%0A%09%09except: categories%5Bsite%5B%22category%22%5D%5D = %5Bsite%5D%0A    #print them all%0A%09for category in categories:%0A%09%09print(%22into category%22, category, %22:%22)%0A%09%09for site in categories%5Bcategory%5D:%0A%09%09%09print(%22 %22.join((site%5B%22shown_name%22%5D, %22-%3E%22, site%5B%22link_properties%22%5D%5B%22link%22%5D)))%0A%0A%0A
 function
@@ -3507,16 +3507,42 @@
 ove_site
+,%0A%09%22site list%22: list_sites
 %0A%7D%0A%0Aif _
@@ -3621,17 +3621,16 @@
 gv%5B3:%5D)%0A
-%0A
 %09except 
@@ -3646,17 +3646,17 @@
 %0A%09%09print
- 
+(
 %22it shou
@@ -3693,8 +3693,9 @@
 .keys())
+)

add 'site list'