#!/usr/bin/env python # -*- coding: utf-8 -*- # vim: set fenc=utf-8: # $Id$ 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 ' 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 += '.jpg' 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) if res: print '* import 명령 실행에 실패하였습니다. imagemagick 라이브러리가 설치되어 있는지 확인하세요.' return xchat.EAT_ALL try: ftp = ftplib.FTP(cfg['scrshot']['ftp_host'], cfg['scrshot']['ftp_user'], cfg['scrshot']['ftp_passwd']) 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_amarok,get_playing_noatun,get_playing_xmms_bmp,get_playing_mplayer,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_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_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_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_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)' 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[2] 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_scrshot) 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