#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: set fenc=utf-8:
# $Id$
#
# *** 랜덤여신님이 만드신 xchat script ***
#  + ACPI cpu온도 출력 추가 - sakuragi
#  + Audacious, Quod Libet의 재생곡 출력부분을 추가 - sakuragi
from __future__ import division

__module_name__ = 'barosl-xchat-script'
__module_description__ = 'barosl\'s xchat script'
__module_version__ = '0.1'

import xchat
import os, sys
import user; os.chdir(user.home+'/.xchat2/')
import time
import ftplib
import time
import re
try: import xmms
except ImportError: xmms = None
import random
execfile('barosl-xchat-script-config.txt')

lspci_cmds = ('/sbin/lspci', '/usr/sbin/lspci', os.popen('which lspci 2> /dev/null').read().strip())
lspci_cmd = ''
for x in lspci_cmds:
	if x and os.path.isfile(x): lspci_cmd = x

def fn_send_msg(msg):
	for x in msg.split('\n'):
		if x: xchat.command('say %s' % x)

def on_done(word, word_eol, userdata):
	if len(word) != 2:
		print '* usage: /done <server-name>'
		return xchat.EAT_ALL

	server_name = word[1]
	if server_name in cfg['cmd_rc']:
		for x in cfg['cmd_rc'][server_name]:
			xchat.command(x)

	return xchat.EAT_ALL

def on_scrshot(word, word_eol, userdata):
	f_name = cfg['scrshot']['filename'].replace('%d', str(int(time.time())))
	f_name_arg = ''
	delay = 0

	if len(word) > 1:
		try: delay = int(word[1])
		except: f_name = word[1]; f_name_arg = word[1]

	if len(word) > 2:
		try: delay = int(word[2])
		except: f_name = word[2]; f_name_arg = word[2]

	f_name += '.png'
	if delay < 0: delay = 0
	if delay > 30: delay = 30
	if delay:
		print '* %d 초 기다립니다.' % delay
		xchat.command('timer %d 스샷 %s' % (delay, f_name_arg))
		return xchat.EAT_ALL
#		time.sleep(delay)

	#res = os.system('import -window root -quality 100 /tmp/%s' % f_name)
	res = os.system('scrot /tmp/%s' % f_name)
	if res:
		#print '* import 명령 실행에 실패하였습니다. imagemagick 라이브러리가 설치되어 있는지 확인하세요.'
		print '* scrot 명령 실행에 실패하였습니다. scrot가 설치되어 있는지 확인하세요.'
		return xchat.EAT_ALL

	try:
		ftp = ftplib.FTP(cfg['scrshot']['ftp_host'], cfg['scrshot']['ftp_user'], cfg['scrshot']['ftp_passwd'])
		# passive mode setting ftp.set_pasv(0) : home, ftp.set_pasv(1) : school, ftp.set_pasv(1) is default
		ftp.set_pasv(0)
		ftp.cwd(cfg['scrshot']['ftp_path'])
		ftp.storbinary('STOR %s' % f_name, open('/tmp/%s' % f_name))
	except Exception, e:
		print '* failed to make screenshot: %s' % str(e)
		return xchat.EAT_ALL

	fn_send_msg('[데스크탑 스크린샷] %s' % (cfg['scrshot']['url_base'].replace('%s', f_name))) #xchat.get_info('nick'), 

	return xchat.EAT_ALL

def on_playing(word, word_eol, userdata):
	data = ''
	funcs = (get_playing_mplayer,get_playing_amarok,get_playing_audacious,get_playing_quodlibet,get_playing_noatun,get_playing_xmms_bmp,get_playing_kaffeine)
	for func in funcs:
		data = func()
		if data: break
	if data:
		fn_send_msg('[재생중] %s' % data)
		if func == get_playing_amarok:
			open('/tmp/barosl-playing', 'w').write(data)
			open('/tmp/barosl-playing-path', 'w').write(os.popen('dcop amarok player path').read()[:-1])
#			fn_send_msg('[같이듣기] %s' % 'http://note.barosl.com/onair.php')
	else:
		fn_send_msg('[재생중] 없음')
	return xchat.EAT_ALL

def get_playing_mplayer():
	data = os.popen('ps aux').read()
	pos_start = data.find('mplayer ')
	if pos_start == -1: return None
	pos_start += len('mplayer ')
	pos_end = data.find('\n', pos_start)
	if pos_end == -1: return None
	res = data[pos_start:pos_end].strip()
	pos = res.rfind('.')
	if pos != -1: res = res[:pos]
	pos = res.rfind('/')
	if pos != -1: res = res[pos+1:]
	return res

def get_playing_amarok():
	res = os.popen('dcop amarok player nowPlaying').read()[:-1]
	if res: return res + ' (%s)' % os.popen('dcop amarok player totalTime').read()[:-1] + ' on '+os.popen('dcop amarok player album').read()[:-1]+''
	return None

def get_playing_audacious():
	data = os.popen('audtool current-song').read()
	if data.find('not running!') != -1: return None
	if not data: return None
	res = data[:-1] + ' (' 
	res += os.popen('audtool current-song-length').read()[:-1] + ')'
	return res

def get_playing_quodlibet():
	data = os.popen('quodlibet --print-playing').read()
	if data.find('노래가 없습니다.') != -1: return None
	if not data: return None
	res = data[:-1] + ' ('
	for line in open(user.home+'/.quodlibet/current'):
		if line.startswith('~#length'):
			len = int(line[line.find('=')+1:-1])
	res += str(int(len/60)) + ':' + ('0' + str(int(len%60)))[-2:]  + ')'
	return res

def get_playing_noatun():
	res = os.popen('dcop noatun Noatun title').read()[:-1]
	if res: return res + ' (%s)' % os.popen('dcop noatun Noatun timeString').read().split('/')[1][:-1]
	return None

def get_playing_xmms_bmp():
	if not xmms: return None
	res = xmms.get_playlist_file(xmms.get_playlist_pos())
	if not res: return None
	return res

def get_playing_kaffeine():
	res = os.popen('dcop kaffeine KaffeineIface title').read()[:-1]
	return res

def on_misonyun(word, word_eol, userdata):
	fn_send_msg('/kick 미소년')
	channel = xchat.get_info('channel')
	xchat.command('part %s kicked' % channel)
	xchat.command('join %s' % channel)
	return xchat.EAT_ALL

def on_uname(word, word_eol, userdata):
	fn_send_msg(os.popen('uname -a').read())
	return xchat.EAT_ALL

def on_uptime(word, word_eol, userdata):
	uptime = int(float(open('/proc/uptime').read().split(' ',1)[0]))
	day, hour, minute = int(uptime/60/60/24), int(uptime/60/60)%24, int(uptime/60)%60
	if day: res = '%d일 %d시간 %d분' % (day, hour, minute)
	elif hour: res = '%d시간 %d분' % (hour, minute)
	else: res = '%d분' % (minute)
	fn_send_msg('[업타임] '+res)
	return xchat.EAT_ALL

def on_disk(word, word_eol, userdata):
	res = os.popen('df -m').read()
	res = re.sub('(\n?)(tmpfs|none).*\n', '\\1', res)
	res = re.sub('(\n?).*(/boot|/dev|/.dev)\n', '\\1', res)
	res = res[res.find('\n')+1:]
	size_total, size_used = 0, 0
	for line in res.split('\n'):
		if not line: continue
		if not line.startswith('/dev/'): continue
		arr = re.split('\s+', line)
		size_total += int(arr[1])
		size_used += int(arr[2])
	size_unused = size_total - size_used
	fn_send_msg('[디스크] 전체: %.1f GB | 사용중: %.1f GB (%.2f %%) | 남음: %.1f GB (%.2f %%)' % (size_total/1024, size_used/1024, size_used*100/size_total, size_unused/1024, size_unused*100/size_total))
	return xchat.EAT_ALL

def on_ostype(word, word_eol, userdata):
	fn_send_msg('[운영체제] %s' % os.popen('uname -s').read()[:-1]+' '+os.popen('uname -r').read()[:-1])
	return xchat.EAT_ALL

def on_cpu(word, word_eol, userdata):
	res = ''
	for line in open('/proc/cpuinfo'):
		if line.startswith('model name'):
			res += ' '+line[line.find(': ')+2:-1]
		if line.startswith('cpu MHz'):
			res += ' ('+line[line.find(': ')+2:-1]+'MHz'
	if not res: res = ' (Unknown)'

	if os.path.isfile('/proc/acpi/thermal_zone/THRM/temperature'):
		res += ' / '+open('/proc/acpi/thermal_zone/THRM/temperature').read()[25:-1]
	res += ')'

	fn_send_msg('[프로세서] %s' % res[1:])
	return xchat.EAT_ALL

def on_mem(word, word_eol, userdata):
	res = ''
	for line in os.popen('free'):
		if line.startswith('-/+ buffers/cache:'):
			arr = re.split('\s+', line[len('-/+ buffers/cache:'):].strip())
			mem_used = int(arr[0])
			mem_total = mem_used + int(arr[1])
			mem_free = mem_total - mem_used
			res = '전체: %.1f MB | 사용중: %.1f MB (%.2f %%) | 남음: %.1f MB (%.2f %%)' % (mem_total/1024, mem_used/1024, mem_used*100/mem_total, mem_free/1024, mem_free*100/mem_total)
			break
	if not res: res = '(Unknown)'
	fn_send_msg('[메모리] %s' % res)
	return xchat.EAT_ALL

def on_gpu(word, word_eol, userdata):
	if not lspci_cmd: fn_send_msg('[그래픽] lspci 를 찾을 수 없습니다.'); return xchat.EAT_ALL
	res = ''
	for line in os.popen(lspci_cmd):
		try: line = line.split(' ', 1)[1].strip()
		except: continue
		if line.startswith('VGA') or line.startswith('Display'):
			res = '[그래픽] %s\n' % line
			break
	if not res: res = '[그래픽] (Unknown)'
	fn_send_msg(res)
	return xchat.EAT_ALL

def on_resolution(word, word_eol, userdata):
	res = ''
	dimensions, depth = '', ''
	for line in os.popen('xdpyinfo'):
		line = line.strip()
		if line.startswith('dimensions:'):
			dimensions = line[len('dimensions:'):].strip().replace('pixels', '픽셀').replace('millimeters', '밀리미터')
		if line.startswith('depth of root window:'):
			depth = line[len('depth of root window:'):].strip().replace(' planes', ' 비트')
	if dimensions: res += ' '+dimensions
	if depth: res += ' | 색상: '+depth
	if not res: res = ' (Unknown)'
	fn_send_msg('[해상도] %s' % res[1:])
	return xchat.EAT_ALL

def on_sound(word, word_eol, userdata):
	if not lspci_cmd: fn_send_msg('[사운드] lspci 를 찾을 수 없습니다.'); return xchat.EAT_ALL
	res = ''
	for line in os.popen(lspci_cmd):
		try: line = line.split(' ', 1)[1].strip()
		except: continue
		if line.startswith('Multimedia audio controller:'):
			res += '[사운드] %s\n' % line[len('Multimedia audio controller:'):].strip()
	if not res: res = '[사운드] (Unknown)'
	fn_send_msg(res)
	return xchat.EAT_ALL

def on_network(word, word_eol, userdata):
	if not lspci_cmd: fn_send_msg('[네트워크] lspci 를 찾을 수 없습니다.'); return xchat.EAT_ALL
	res = ''
	for line in os.popen(lspci_cmd):
		try: line = line.split(' ', 1)[1].strip()
		except: continue
		if line.startswith('Network') or line.startswith('Ethernet'):
			pos = line.find(': ')
			res += '[네트워크] %s\n' % line[pos+2:]
	if not res: res = '[네트워크] (Unknown)'
	fn_send_msg(res)
	return xchat.EAT_ALL

def on_sysinfo(word, word_eol, userdata):
	fn_send_msg('== %s 시스템 정보 ==' % os.popen('uname -n').read()[:-1])
	on_ostype(word, word_eol, userdata)
	on_uptime(word, word_eol, userdata)
	on_cpu(word, word_eol, userdata)
	on_mem(word, word_eol, userdata)
	on_gpu(word, word_eol, userdata)
	on_resolution(word, word_eol, userdata)
	on_network(word, word_eol, userdata)
	on_sound(word, word_eol, userdata)
	on_disk(word, word_eol, userdata)
	return xchat.EAT_ALL

def on_invited(word, word_eol, userdata):
	xchat.command('join %s' % word[0])
#	print '* 초대되었습니다: %s by %s' % (word[0], word[1])

def on_msg(word, word_eol, userdata):
	user = word[0]
	msg = word_eol[3][1:]
	if user.endswith('@도연.users.HanIRC.org'):
		if msg.startswith('!music '):
			song = msg[len('!music '):]
			if song.find('\'') == -1:
				os.system('noatun \'/home/barosl/box/기타/rod/%s.mp3\' &' % song)
	return xchat.EAT_NONE

def on_play_amarok(word, word_eol, userdata):
	query = word_eol[1]
	query_for_cli = query.replace('\'','\'\\\'\'').replace('"','\\"')
	data = os.popen('dcop amarok collection query \'select * from artist where name = "%s" limit 1\'' % query_for_cli).read()[:-1]
	if data:
		fn_send_msg('* 이 아티스트의 음악 중 하나를 무작위로 선택합니다: %s' % query)
		data2 = os.popen('dcop amarok collection query \'select count(*) from tags where artist = "%s" limit 1\'' % data.split('\n')[0]).read()[:-1]
		data = os.popen('dcop amarok collection query \'select * from tags where artist = "%s" limit %d,1\'' % (data.split('\n')[0], random.randrange(int(data2)))).read()[:-1]
	else:
		fn_send_msg('* 음악을 검색합니다: %s' % query)
		data = os.popen('dcop amarok collection query \'select * from tags where title like "%%%s%%" limit 1\'' % query_for_cli).read()[:-1]
	arr = data.split('\n')
#	for i in xrange(len(arr)): print i, arr[i]
	if not data:
		fn_send_msg('* 음악을 찾지 못했습니다.')
	if data:
		url = arr[0]
		artist = os.popen('dcop amarok collection query \'select name from artist where id="%s"\'' % int(arr[4])).read()[:-1]
		album = os.popen('dcop amarok collection query \'select name from album where id="%s"\'' % int(arr[3])).read()[:-1]
		title = arr[6]
		length = int(arr[-3])
		fn_send_msg('* 음악을 찾았습니다. 재생합니다: %s - %s (%d:%02d) on %s' % (artist, title, length/60, length%60, album))
		os.popen('dcop amarok playlist playMedia \'%s\'' % url.replace('\'','\'\\\'\'').replace('"','\\"'))
	return xchat.EAT_ALL

def on_topic(word, word_eol, userdata):
	global is_etopic
	if globals().get('is_etopic'):
		xchat.command('settext %stopic %s' % (xchat.get_prefs('input_command_char'), word[1]))
		return xchat.EAT_ALL
	return xchat.EAT_NONE

def on_topic_change_or_creation(word, word_eol, userdata):
	global is_etopic
	if globals().get('is_etopic'):
		is_etopic = False
		return xchat.EAT_ALL
	return xchat.EAT_NONE

def on_etopic(word, word_eol, userdata):
	global is_etopic
	is_etopic = True
	xchat.command('topic')
	return xchat.EAT_ALL

def on_run(word, word_eol, userdata):
	fn_send_msg('!실행 %s' % word_eol[1])
	xchat.command('exec -o %s' % word_eol[1])
	return xchat.EAT_ALL

def on_away(word, word_eol, userdata):
	away = xchat.get_info('away') and True or False
	nick = xchat.get_info('nick')
	away_new = not away
	nick_new = nick
	reason = (len(word_eol) > 1 and word_eol[1]) or ''
	if reason: away_new = True
	if not away_new and nick_new.endswith('부재'):
		nick_new = nick_new[:-len('부재')]
		if nick_new.endswith('^') or nick_new.endswith('_'):
			nick_new = nick_new[:-1]
	elif away_new:
		nick_new += '^부재'
	if nick != nick_new:
		xchat.command('nick %s' % nick_new)
	if away != away_new:
		if away_new: xchat.command('away %s' % reason)
		else: xchat.command('away')
	return xchat.EAT_ALL

# 알리미를 위해...
def on_server_text(word, word_eol, userdata):
	# ping/pong 오류 메시지인가?
	msg = word[0]
	pos = msg.find('/QUOTE')
	if pos != -1:
		# 맞다면, pong 답변 보냄. (pong 을 fong 으로 치환해서)
		cmd = msg[pos+7:].replace('PONG', 'FONG')
		cmd = cmd
		xchat.command(cmd)

	return xchat.EAT_NONE

# 알리미를 위해...
def on_connected(word, word_eol, userdata):
	xchat.hook_timer(500, alimi_timer)
	return xchat.EAT_NONE

# 알리미를 위해...
def alimi_timer(userdata): 
	context = xchat.find_context(server='alimi.cafe24.com')
	if context: context.command('QUOTE FONG abc')
	return 0

# 알리미를 위해...
xchat.hook_print('Server Text', on_server_text)
xchat.hook_print('Connected', on_connected)

xchat.hook_command('done', on_done)
xchat.hook_command('스샷', on_scrshot)
xchat.hook_command('scrshot', on_scrshot)
xchat.hook_command('곡', on_playing)
xchat.hook_command('gok', on_playing)
xchat.hook_command('music', on_playing)
xchat.hook_command('미소년', on_misonyun)

xchat.hook_command('uname', on_uname)
xchat.hook_command('uptime', on_uptime)
xchat.hook_command('disk', on_disk)
xchat.hook_command('sysinfo', on_sysinfo)
xchat.hook_command('정보', on_sysinfo)
xchat.hook_command('os', on_ostype)
xchat.hook_command('운영체제', on_ostype)
xchat.hook_command('cpu', on_cpu)
xchat.hook_command('mem', on_mem)
xchat.hook_command('메모리', on_mem)
xchat.hook_command('gpu', on_gpu)
xchat.hook_command('그래픽', on_gpu)
xchat.hook_command('graphic', on_gpu)
xchat.hook_command('resol', on_resolution)
xchat.hook_command('해상도', on_resolution)
xchat.hook_command('resolution', on_resolution)
xchat.hook_command('sound', on_sound)
xchat.hook_command('사운드', on_sound)
xchat.hook_command('network', on_network)
xchat.hook_command('네트워크', on_network)

xchat.hook_command('재생', on_play_amarok)
xchat.hook_command('play', on_play_amarok)

xchat.hook_print('Invited', on_invited)
xchat.hook_server('PRIVMSG', on_msg)

xchat.hook_print('Topic', on_topic)
xchat.hook_print('Topic Change', on_topic_change_or_creation)
xchat.hook_print('Topic Creation', on_topic_change_or_creation)
xchat.hook_command('etopic', on_etopic)

xchat.hook_command('run', on_run)

xchat.hook_command('부재', on_away)
#xchat.hook_command('away', on_away) # 기존 기능과 충돌함

print '* barosl\'s xchat script loaded'

# EndOfFile
