<commit_before>fs = require('fs')
fogbugz = require('../index')
read = require('read')
askfor = require('askfor')
Table = require('cli-table')
memo = require('memoizee')
iz = require('iz')
Q = require('q')
print = require('node-more')

fcall = (f) -> f()
# promise duck
done =
	then: fcall
	done: fcall
	fail: fcall

# instance of fogbugz client
fb = null
currentCase = null
lastCases = []

help = ->
	cmds =
		[
			['ls', 'list active cases from current filter'],
			['ls f', 'list available filters'],
			['ls p', 'list available projects'],
			['ls m', 'list available milestones']
			['ls u', 'list available users'],
			['ls c', 'list available case categories'],
			['ls s', 'list available case statuses'],
			['u id', 'print user info'],
			['search q', 'searches cases by specified q'],
			['take #case [comment]', 'assign given case to logon user'],
			['resolve [#case] [comment]', 'resolves current or given case']
			['close #case [comment]', 'close given case'],
			['reopen #case [comment]', 'reopen given case'],
			['assign #case userId [comment]', 'assign given case to given user'],
			['kick #case [comment]', 'return given case back to team'],
			['log [#case] [comment]', 'logs specified comment to given case'],
			['q[uit]', 'exit from this shell'],
			['exit', 'exit from this shell'],
			['help', 'print this command list'],
		]
	console.log 'commands:'
	col = Math.max.apply(null, cmds.map (x) -> x[0].length)
	list = cmds.map (x) -> '  ' + padr(x[0], col) + ' - ' + x[1]
	list.forEach (s) -> console.log(s)
	done

padr = (s,len) -> s + Array(len-s.length).join ' '

repl = -> read {prompt: '>>> '}, (err, l) -> printError(run(l)).done(repl)

# evals specified line
run = (l) ->
	args = []
	rx = /('[^']*')|("[^"]*")|(\w|\d)+/g
	while (m = rx.exec(l)) != null
		args.push unquote m[0]
	cmd = args[0]
	switch cmd
		when 'help' then do help
		when 'ls' then ls args
		when 'search' then search args
		when 'take' then take args
		when 'resolve' then resolve args
		when 'assign' then assign args
		when 'close' then close args
		when 'reopen' then reopen args
		when 'kick' then kick args
		when 'log' then log args
		when 'u' then resolveUser(args[1]).then((x) -> [x]).then(printUsers)
		when 'q' then process.exit 0
		when 'quit' then process.exit 0
		when 'exit' then process.exit 0
		else unkcmd cmd

unquote = (s) ->
	if s[0] == '"' or s[0] == "'" then s.substr 1, s.length - 2 else s
unkcmd = (cmd) ->
	console.log 'unknown command: %s', cmd
	done

# CONFIG
cfgfile = __dirname + '/fbsh.conf.json'

auth = (cb) ->
	if fs.existsSync cfgfile
		options = require(cfgfile)
		# TODO check token
		if options.token then start options, false, cb else askcfg cb
	else askcfg cb

askcfg = (cb) ->
	askfor ['fogbugz url', 'user', 'password'], (answers) ->
		options =
			url: answers['fogbugz url']
			user: answers.user,
			password: answers.password
		start options, true, cb

start = (options, updateConfig, cb) ->
	p = fogbugz(options)
	p.fail (error) ->
		console.log(error)
		# TODO auth again
		process.exit(-1)
	p.done (client) ->
		if updateConfig
			delete options.password
			options.token = client.token
			fs.writeFileSync(cfgfile, toJson(options), 'utf8')
		fb = client
		cb()

# list command handler
ls = (args) ->
	switch args[1]
		when 'f' then filters().then printTable
		when 'p' then projects().then printProjects
		when 'u' then users().then printUsers
		when 'm' then milestones().then printMilestones
		when 'c' then categories().then printTable
		when 's' then statuses().then printTable
		else
			id = if args[1] then parseInt(args[1], 10) else NaN
			if isNaN id
					listActiveCases()
			else
					caseObj = lastCases.filter((x) -> x.id == id)[0]
					if caseObj then caseObj.events().then printEvents else done

# returns memoized Fb method
fbmemo = (method) ->
		fn = null
		->
			if fn == null
				fn = memo(fb[method])
			fn.apply fb, [].slice.call(arguments)

filters = fbmemo('filters')
projects = fbmemo('projects')
users = fbmemo('people')
milestones = fbmemo('milestones')
categories = fbmemo('categories')
statuses = fbmemo('statuses')

listActiveCases = ->
	fb.search()
		.then(filterActiveCases)
		.then((list) -> lastCases = list)
		.then printCases

# TODO do not hardcode active status
filterActiveCases = (list) -> list.filter (x) -> x.status.id == 1
<commit_msg>list priorities<commit_after>fs = require('fs')
fogbugz = require('../index')
read = require('read')
askfor = require('askfor')
Table = require('cli-table')
memo = require('memoizee')
iz = require('iz')
Q = require('q')
print = require('node-more')

fcall = (f) -> f()
# promise duck
done =
	then: fcall
	done: fcall
	fail: fcall

# instance of fogbugz client
fb = null
currentCase = null
lastCases = []

help = ->
	cmds =
		[
			['ls', 'list active cases from current filter'],
			['ls f', 'list available filters'],
			['ls p', 'list available projects'],
			['ls m', 'list available milestones']
			['ls u', 'list available users'],
			['ls c', 'list available case categories'],
			['ls s', 'list available case statuses'],
			['ls l', 'list available priorities'],
			['u id', 'print user info'],
			['search q', 'searches cases by specified q'],
			['take #case [comment]', 'assign given case to logon user'],
			['resolve [#case] [comment]', 'resolves current or given case']
			['close #case [comment]', 'close given case'],
			['reopen #case [comment]', 'reopen given case'],
			['assign #case userId [comment]', 'assign given case to given user'],
			['kick #case [comment]', 'return given case back to team'],
			['log [#case] [comment]', 'logs specified comment to given case'],
			['q[uit]', 'exit from this shell'],
			['exit', 'exit from this shell'],
			['help', 'print this command list'],
		]
	console.log 'commands:'
	col = Math.max.apply(null, cmds.map (x) -> x[0].length)
	list = cmds.map (x) -> '  ' + padr(x[0], col) + ' - ' + x[1]
	list.forEach (s) -> console.log(s)
	done

padr = (s,len) -> s + Array(len-s.length).join ' '

repl = -> read {prompt: '>>> '}, (err, l) -> printError(run(l)).done(repl)

# evals specified line
run = (l) ->
	args = []
	rx = /('[^']*')|("[^"]*")|(\w|\d)+/g
	while (m = rx.exec(l)) != null
		args.push unquote m[0]
	cmd = args[0]
	switch cmd
		when 'help' then do help
		when 'ls' then ls args
		when 'search' then search args
		when 'take' then take args
		when 'resolve' then resolve args
		when 'assign' then assign args
		when 'close' then close args
		when 'reopen' then reopen args
		when 'kick' then kick args
		when 'log' then log args
		when 'u' then resolveUser(args[1]).then((x) -> [x]).then(printUsers)
		when 'q' then process.exit 0
		when 'quit' then process.exit 0
		when 'exit' then process.exit 0
		else unkcmd cmd

unquote = (s) ->
	if s[0] == '"' or s[0] == "'" then s.substr 1, s.length - 2 else s
unkcmd = (cmd) ->
	console.log 'unknown command: %s', cmd
	done

# CONFIG
cfgfile = __dirname + '/fbsh.conf.json'

auth = (cb) ->
	if fs.existsSync cfgfile
		options = require(cfgfile)
		# TODO check token
		if options.token then start options, false, cb else askcfg cb
	else askcfg cb

askcfg = (cb) ->
	askfor ['fogbugz url', 'user', 'password'], (answers) ->
		options =
			url: answers['fogbugz url']
			user: answers.user,
			password: answers.password
		start options, true, cb

start = (options, updateConfig, cb) ->
	p = fogbugz(options)
	p.fail (error) ->
		console.log(error)
		# TODO auth again
		process.exit(-1)
	p.done (client) ->
		if updateConfig
			delete options.password
			options.token = client.token
			fs.writeFileSync(cfgfile, toJson(options), 'utf8')
		fb = client
		cb()

# list command handler
ls = (args) ->
	switch args[1]
		when 'f' then filters().then printTable
		when 'p' then projects().then printProjects
		when 'u' then users().then printUsers
		when 'm' then milestones().then printMilestones
		when 'c' then categories().then printTable
		when 's' then statuses().then printTable
		when 'l' then priorities().then printTable
		else
			id = if args[1] then parseInt(args[1], 10) else NaN
			if isNaN id
					listActiveCases()
			else
					caseObj = lastCases.filter((x) -> x.id == id)[0]
					if caseObj then caseObj.events().then printEvents else done

# returns memoized Fb method
fbmemo = (method) ->
		fn = null
		->
			if fn == null
				fn = memo(fb[method])
			fn.apply fb, [].slice.call(arguments)

filters = fbmemo('filters')
projects = fbmemo('projects')
users = fbmemo('people')
milestones = fbmemo('milestones')
categories = fbmemo('categories')
statuses = fbmemo('statuses')
priorities = fbmemo('priorities')

listActiveCases = ->
	fb.search()
		.then(filterActiveCases)
		.then((list) -> lastCases = list)
		.then printCases

# TODO do not hardcode active status
filterActiveCases = (list) -> list.filter (x) -> x.status.id == 1

{'fraction_non_alphanumeric': 0.166571721544947, 'fraction_numerical': 0.005013102426797311, 'mean_word_length': 3.6716338477913784, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 61, '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': '2077266', 'n_tokens_mistral': 3336, 'n_tokens_neox': 3039, 'n_words': 989}