#!/usr/bin/python
# -*- coding: utf-8 -*-
from slackbot.bot import respond_to
from slackbot.bot import listen_to

import re
import sys
import os
import MySQLdb

import requests
import lxml.html
import random

import json
from json import dumps, load
from random import randint
from slackbot import beauty_settings

DEBUG = False
fav_message = [u'我也覺得很正',u'哎呦讚喔，存起來',u'我要拿回家慢慢看',u'好，我記起來了！',u'這樣你也行？',u'+++',u'😍']
delete_message = [u'真挑剔',u'我很辛苦找圖耶',u'不合您胃口嗎',u'我也覺得不ok',u'嚴格帝',u'---']
beauty_config = beauty_settings.fileroot+"beauty_config"

def randomReply(message,messageSet):
	message.send(random.choice(messageSet))

def deleteImageFromTable(image,table):
	db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
	cursor = db.cursor()
	sql = "delete from %s where url='%s'" % (table, image)
	cursor.execute(sql)
	db.commit()
	db.close()

def favImageToDB(image):
	db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
	cursor = db.cursor()
	sql = "INSERT IGNORE INTO fav_images(url) VALUES ('%s')" % image
	cursor.execute(sql)
	db.commit()
	db.close()
	

def checkJsonExists():
	if not os.path.isfile(beauty_config):
		file = open(beauty_config, "w")
		file.write(u'{}')
		file.close()


def get_web_content(link):
	if not link:
		return None, lxml.html.fromstring(u'<html></html>')
	try:
		r = requests.get(link)
		try:
			content = r.content.decode('UTF-8')
		except UnicodeDecodeError, ude:
			if DEBUG:
				msg = (
					'The content is not in UTF-8 (ude=%s). '
					'Try ISO-8859-1 instead.\n' % ude)
				sys.stderr.write(msg)
			# Try another encoding. If fail, just let it fail.
			content = r.content.decode('ISO-8859-1')

		if DEBUG:
			sys.stderr.write(
				'Get content of link %s: %s\n' % (link, content[:50])
			)
		return r.status_code, lxml.html.fromstring(content)
	except Exception, e:
		if DEBUG:
			sys.stderr.write(
				'Fail to get content of link: %s (e=%s)\n' % (link, e)
			)
		return None, lxml.html.fromstring(u'<html></html>')


def get_image_from_page(pageurl):
	beautyimages = []

	code, pttBeautyPage = get_web_content(pageurl)

	pageimgurls = pttBeautyPage.xpath('//a/@href')

	for imgUrls in pageimgurls:
		if ".jpg" not in imgUrls:
			imgUrls += ".jpg"
		if "imgur" in imgUrls:
			beautyimages.append(imgUrls)

	if len(beautyimages) == 0:
		images = pttBeautyPage.xpath('//img')
		for img in images:
			try:
				beautyimages.append(img.attrib['data-src'])
			except Exception, e:
				pass

	if len(beautyimages) == 0:
		beautyimages.append("failed")
	return beautyimages


def get_pages_from_board(beauty=True, maxpage=14, push=10):
	code, pttBeautyBoard = get_web_content("https://www.ptt.cc/bbs/Beauty/index.html")
	pageurls = pttBeautyBoard.xpath('//a/@href')

	page_index = 0
	post_links = []

	if pageurls[7].endswith('.html'):
		pageurls[7] = pageurls[7][:-5]
		pageurls[7] = pageurls[7][-4:]
		page_index = int(pageurls[7])
		# print page_index

	for i in range(0, maxpage):
		pageurl = "https://www.ptt.cc/bbs/Beauty/index" + str(page_index - i) + ".html"
		code, pttBeautyPage = get_web_content(pageurl)

		for i, post in enumerate(pttBeautyPage.find_class("r-ent")):
			if len(post[0].text_content()) and u"公告" not in post[2].text_content():
				if beauty is True:
					if u"帥哥" not in post[2].text_content():
						if u'X' not in post[0].text_content():
							if u'爆' in post[0].text_content():
								if post[2].xpath('.//a/@href'):
									post_links.append(post[2].xpath('.//a/@href')[0])
							elif int(post[0].text_content()) >= push:
								if post[2].xpath('.//a/@href'):
									post_links.append(post[2].xpath('.//a/@href')[0])
				else:
					if u"帥哥" in post[2].text_content():
						if u'X' not in post[0].text_content():
							if u'爆' in post[0].text_content():
								if post[2].xpath('.//a/@href'):
									post_links.append(post[2].xpath('.//a/@href')[0])
							elif int(post[0].text_content()) >= push:
								if post[2].xpath('.//a/@href'):
									post_links.append(post[2].xpath('.//a/@href')[0])

	return post_links


@listen_to(u'\Abeauty stat\Z|\Abeauty status\Z', re.IGNORECASE)
@respond_to(u'\Abeauty stat\Z|\Abeauty status\Z', re.IGNORECASE)
def get_beauty_status(message):
	checkJsonExists()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)
	db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
	cursor = db.cursor()
	sql = "SELECT COUNT(url) FROM beauty_images"
	cursor.execute(sql)
	beauty_count = cursor.fetchone()[0]
	sql = "SELECT COUNT(url) FROM fav_images"
	cursor.execute(sql)
	fav_count = cursor.fetchone()[0]
	sql = "SELECT COUNT('url') FROM beauty_images WHERE Seen = 0"
	cursor.execute(sql)
	not_seen = cursor.fetchone()[0]
	db.close()
	if setting.has_key('cache') and setting.has_key('pages') and setting.has_key('push'):
		message.send(u'總圖片數：%s\n還沒看過：%s\n精華圖片：%s\n使用快取：%s\n抓取頁數：%s\n推文數大於：%s' % (beauty_count, not_seen, fav_count, setting['cache'], setting['pages'], setting['push']))
		setting['beauty_count'] = beauty_count
		with open(beauty_config, "w") as outfile:
			json.dump(setting, outfile, indent=2)
	else:
		message.send(u'嗚嗚，設定好像沒有弄好，請重新調整設定看看')


@listen_to(u'\Aset beauty (.*) (.*)\Z', re.IGNORECASE)
@respond_to(u'\Aset beauty (.*) (.*)\Z', re.IGNORECASE)
def set_beauty_status(message, first, second):
	checkJsonExists()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)

	if setting.has_key('cache'):
		if setting['cache'] == 'NO':
			if first == "push" and second.isdigit():
				if int(second) > 0 and int(second) <= 99:
					setting['push'] = second
					message.send(u'抓取範圍已設定為 %d 推以上的文章' % int(second))
				else:
					message.send(u'請把範圍設定在 1 到 99 之間喔！')
			elif (first == "pages" or first == "page") and second.isdigit():
				if int(second) > 0 and int(second) <= 20:
					setting['pages'] = second
					message.send(u'抓取範圍已設定為 %d 頁' % int(second))
				else:
					message.send(u'請把範圍設定在 1 到 20 之間喔！')
		elif first != "cache":
			message.send(u'先關閉 cache 吧（set beauty cache NO）')
	else:
		message.send(u'先關閉 cache 吧（set beauty cache NO）')
	
	if first == "cache":
		if second == "No" or second == "no" or second == "0" or second == "NO" or second == "disabled" or second == "False" or second == "false":
			setting['cache'] = "NO"
			message.send(u'已關閉快取')
		elif second == "Yes" or second == "yes" or second == "1" or second == "YES" or second == "enabled" or second == "True" or second == "true":
			setting['cache'] = "YES"
			message.send(u'已開啟快取')
	elif first == "push" or first == "page" or first == "pages":
		pass
	else:
		message.send(u'指令下錯啦，檢查看看吧，笨蛋！')

	with open(beauty_config, "w") as outfile:
		json.dump(setting, outfile, indent=2)


@listen_to(u'\Abeauty\Z|給我一個妹|給一個妹', re.IGNORECASE)
@respond_to(u'\Abeauty\Z|給我一個妹|給一個妹', re.IGNORECASE)
def beauty_image(message):
	if not os.path.isfile(beauty_config):
		file = open(beauty_config, "w")
		file.write(u'{}')
		file.close()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)

	cache = False
	load_pages = 11
	min_push = 30

	if setting.has_key('cache'):
		if setting['cache'] == 'NO':
			cache = False
		else:
			cache = True

	if setting.has_key('pages'):
		load_pages = int(setting['pages'])

	if setting.has_key('push'):
		in_push = int(setting['push'])


	if cache == True:
		db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
		cursor = db.cursor()
		seen = 0
		sql = "SELECT url FROM beauty_images WHERE Seen = %d ORDER BY RAND() LIMIT 1" % seen
		cursor.execute(sql)
		
		while cursor.rowcount < 1:
			seen += 1
			sql = "SELECT url FROM beauty_images WHERE Seen = %d ORDER BY RAND() LIMIT 1" % seen
			cursor.execute(sql)
	
		last_image = cursor.fetchone()[0]

		sql = "UPDATE beauty_images SET Seen = %d WHERE url = '%s'" % (seen+1, last_image)
		cursor.execute(sql)
		db.commit()
		db.close()

		setting['last_image'] = last_image
		message.send(last_image)
		if setting.has_key('votes'):
			setting['votes'] = 0
		if setting.has_key('vote_people'):
			setting['vote_people'] = 0
		with open(beauty_config, "w") as outfile:
			json.dump(setting, outfile, indent=2)
	else:
		page = "https://www.ptt.cc" + random.choice(get_pages_from_board(maxpage=load_pages, push=min_push))
		message.send(random.choice(get_image_from_page(page)))


@listen_to(u'\Ahandsome\Z|給我一個歐巴', re.IGNORECASE)
@respond_to(u'\Ahandsome\Z|給我一個歐巴', re.IGNORECASE)
def handsome_image(message):
	page = "https://www.ptt.cc" + random.choice(get_pages_from_board(beauty=False, maxpage=15, push=30))
	message.send(random.choice(get_image_from_page(page)))


@listen_to(u'\A給我正妹', re.IGNORECASE)
@respond_to(u'\A給我正妹', re.IGNORECASE)
def beauty_fav_image(message):
	db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
	cursor = db.cursor()
	sql = "SELECT url FROM fav_images ORDER BY RAND() LIMIT 1"
	cursor.execute(sql)
	last_image = cursor.fetchone()[0]
	db.close()
	message.send(last_image)


@listen_to(u'\Abuild beauty\Z|建立正妹資料庫|\A爬表特版\Z|\Aupdate beauty\Z|\Abeauty update\Z', re.IGNORECASE)
@respond_to(u'\Abuild beauty\Z|建立正妹資料庫|\A爬表特版\Z|\Aupdate beauty\Z|\Abeauty update\Z', re.IGNORECASE)
def build_beauty_image(message):
	checkJsonExists()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)

	if setting.has_key('beauty_count'):
		last_beauty_count = int(setting['beauty_count'])

	beauty_images = []
	randomReply(message,[u'更新正妹資料庫中',u'讓我看看有哪些正妹',u'爬文中...',u'Let me see...',u'等我一下，不要急喔...🐢'])

	for url in get_pages_from_board(maxpage=10, push=30):
		for image in get_image_from_page("https://www.ptt.cc" + url):
			try:
				beauty_images.append(image)
			except Exception, e:
				message.send("Failed %s", e)

	db = MySQLdb.connect("localhost",beauty_settings.db['user'],beauty_settings.db['password'],beauty_settings.db['database'])
	cursor = db.cursor()
	for line in beauty_images:
		if line != "failed":
			sql = "INSERT IGNORE INTO beauty_images(url, seen) VALUES ('%s', 0)" % line
			cursor.execute(sql)
			db.commit()
	

	sql = "SELECT COUNT(url) FROM beauty_images"
	cursor.execute(sql)
	beauty_count = cursor.fetchone()[0]
	db.close()
	randomReply(message,[u'更新完成',u'找到好多正妹了！',u'爬文完畢！',u'今天的正妹不錯喔！'])
	delta = beauty_count - last_beauty_count
	beauty_added = u'增加了 %d 張正妹照' % delta
	message.send(beauty_added)
	setting['beauty_count'] = beauty_count
	with open(beauty_config, "w") as outfile:
		json.dump(setting, outfile, indent=2)


@listen_to(u'\Adelete (.*)\Z|\A刪除 (.*)\Z', re.IGNORECASE)
@respond_to(u'\Adelete (.*)\Z|\A刪除 (.*)\Z', re.IGNORECASE)
def delete_image(message, image, image2):
	if not image and image2:
		image = image2

	image = image[:-1]
	image = image[1:]
	if len(image) > 1:
		deleteImageFromTable(image,'beauty_images')
		message.send(u"已經刪除 %s" % image)


@listen_to(u'\Adelete from fav (.*)\Z|\A刪除精華 (.*)\Z', re.IGNORECASE)
@respond_to(u'\Adelete from fav (.*)\Z|\A刪除精華 (.*)\Z', re.IGNORECASE)
def delete_image(message, image, image2):
	if not image and image2:
		image = image2

	image = image[:-1]
	image = image[1:]
	if len(image) > 1:
		deleteImageFromTable(image,'fav_images')
		message.send(u"已經從精華區刪除 %s" % image)


@listen_to(u'\A刪除這張\Z|\A刪掉這張\Z|\A給我刪掉\Z|\A刪！\Z|\A刪\Z', re.IGNORECASE)
def delete_this_image(message):
	checkJsonExists()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)

	if setting.has_key('cache') and setting.has_key('last_image'):
		if setting['cache'] == 'YES':
			if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
				image = setting['last_image']
				deleteImageFromTable(image,'beauty_images')
				num = randint(0,100)
				if num < 20:
					randomReply(message,delete_message)
				message.send(u"已經刪除 %s" % image)
		else:
			message.send(u'在快取沒開啟的時候不能刪除圖片哦！')
	else:
		message.send(u'在快取沒開啟的時候不能刪除圖片哦！')


@listen_to(u'\Afav\Z|加到精華|加入精華', re.IGNORECASE)
def fav_this_image(message):
	checkJsonExists()

	setting_file = open(beauty_config).read()
	setting = json.loads(setting_file)

	if setting.has_key('cache') and setting.has_key('last_image'):
		if setting['cache'] == 'YES':
			if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
				image = setting['last_image']
				favImageToDB(image)
		
				num = randint(0,100)
				if num < 20:
					randomReply(message,fav_message)
				message.send(u"已經把 %s 加入精華區" % image)
		else:
			message.send(u'在快取沒開啟的時候不能加入精華區哦！')
	else:
		message.send(u'在快取沒開啟的時候不能加入精華區哦！')


@listen_to(u'\A\+\Z|\A\+\+\Z|\A\+\+\+\Z|\A\+\+\+\+|\A＋\Z|\A＋＋\Z|\A＋＋＋\Z|\A＋＋＋＋', re.IGNORECASE)
def vote_up_this_image(message):
	for channel in message._client.channels:
			if not channel.startswith('C') and not channel.startswith('G'):
				pass
			else:
				if message._client.channels[channel]['name'] == 'beauty':
					checkJsonExists()

					setting_file = open(beauty_config).read()
					setting = json.loads(setting_file)

					if setting.has_key('votes'):
						votes = int(setting['votes'])
					else:
						votes = 0

					if setting.has_key('vote_people'):
						vote_people = int(setting['vote_people'])
					else:
						vote_people = 0

					if message.body['text'] == "+" or message.body['text'] == u"＋":
						votes += 1
					elif message.body['text'] == "++" or message.body['text'] == u"＋＋":
						votes += 2
					elif message.body['text'] == "+++" or message.body['text'] == u"＋＋＋":
						votes += 3
					else:
						votes += 4

					vote_people += 1

					if (votes >= 5 and vote_people >= 3) or (votes >= 7 and vote_people == 2) :
						if setting.has_key('cache') and setting.has_key('last_image'):
							if setting['cache'] == 'YES':
								if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
									image = setting['last_image']
									favImageToDB(image)
									num = randint(0,100)
									if num < 20:
										randomReply(message,fav_message)
									message.send(u"已經自動把 %s 加入精華區" % image)
									votes = 0
									vote_people = 0

					setting['votes'] = votes
					setting['vote_people'] = vote_people

					with open(beauty_config, "w") as outfile:
						json.dump(setting, outfile, indent=2)


@listen_to(u'\A-\Z|\A--\Z|\A---|\A——\Z|\A————\Z|\A——————|\A－\Z|\A－－\Z|\A－－－', re.IGNORECASE)
# @respond_to(u'\A-\Z|\A--\Z|\A---|\A——\Z|\A————\Z|\A——————', re.IGNORECASE)
def vote_down_this_image(message):
	for channel in message._client.channels:
			if not channel.startswith('C') and not channel.startswith('G'):
				pass
			else:
				if message._client.channels[channel]['name'] == 'beauty':
					checkJsonExists()

					setting_file = open(beauty_config).read()
					setting = json.loads(setting_file)

					if setting.has_key('votes'):
						votes = int(setting['votes'])
					else:
						votes = 0

					if setting.has_key('vote_people'):
						vote_people = int(setting['vote_people'])
					else:
						vote_people = 0

					if message.body['text'] == "-" or message.body['text'] == u"——" or message.body['text'] == u'－':
						votes = votes - 1
					elif message.body['text'] == "--" or message.body['text'] == u"————" or message.body['text'] == u'－－':
						votes = votes - 2
					else:
						votes = votes - 3

					vote_people += 1

					if (votes <= -3 and vote_people >= 3) or (votes <= -5 and vote_people == 2):
						if setting.has_key('cache') and setting.has_key('last_image'):
							if setting['cache'] == 'YES':
								if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
									image = setting['last_image']
									deleteImageFromTable(image,'beauty_images')
									num = randint(0,100)
									if num < 20:
										randomReply(message,delete_message)
									message.send(u"已經自動刪除 %s" % image)
									votes = 0
									vote_people = 0

					setting['votes'] = votes
					setting['vote_people'] = vote_people

					with open(beauty_config, "w") as outfile:
						json.dump(setting, outfile, indent=2)


@listen_to(u'\A\|\Z|\A\｜\Z', re.IGNORECASE)
@respond_to(u'\A\|\Z|\A\｜\Z', re.IGNORECASE)
def vote_mid_this_image(message):
	for channel in message._client.channels:
		if not channel.startswith('C') and not channel.startswith('G'):
			pass
		else:
			if message._client.channels[channel]['name'] == 'beauty':
				checkJsonExists()

				setting_file = open(beauty_config).read()
				setting = json.loads(setting_file)

				if setting.has_key('votes'):
						votes = int(setting['votes'])
				else:
					votes = 0
				
				if setting.has_key('vote_people'):
					vote_people = int(setting['vote_people'])
				else:
					vote_people = 0

				vote_people += 1

				if (votes <= -3 and vote_people >= 3) or (votes <= -5 and vote_people == 2):
					if setting.has_key('cache') and setting.has_key('last_image'):
						if setting['cache'] == 'YES':
							if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
								image = setting['last_image']
								deleteImageFromTable(image,'beauty_images')
								num = randint(0,100)
								if num < 20:
									randomReply(message,delete_message)
								message.send(u"已經自動刪除 %s" % image)
								votes = 0
								vote_people = 0

				if (votes >= 5 and vote_people >= 3) or (votes >= 7 and vote_people == 2) :
					if setting.has_key('cache') and setting.has_key('last_image'):
						if setting['cache'] == 'YES':
							if len(setting['last_image']) > 10 and ".jpg" in setting['last_image']:
								image = setting['last_image']
								favImageToDB(image)
								num = randint(0,100)
								if num < 20:
									randomReply(message,fav_message)
								message.send(u"已經自動把 %s 加入精華區" % image)
								votes = 0
								vote_people = 0

				setting['votes'] = votes
				setting['vote_people'] = vote_people

				with open(beauty_config, "w") as outfile:
					json.dump(setting, outfile, indent=2)