import flask
from flask import Flask
from flask import jsonify
from flask import request
from flask_cors import CORS, cross_origin
from flask import render_template

import mwoauth
import requests_oauthlib
import os
import yaml
import mwapi

from tasks.main import Tasks
from save import Save
from db import DB

from typo.fix import TypoFix

app = Flask(__name__, static_folder="./frontend/build/static", template_folder="./frontend/build")
#app = Flask(__name__)
CORS(app)

user_agent = 'WikiBooster'

__dir__ = os.path.dirname(__file__)

configFile = open(os.path.join(__dir__, 'config.yaml'))
app.config.update(yaml.safe_load(configFile))

def authenticated_session(domain = 'meta.wikimedia.org'):
	if 'oauth_access_token' in flask.session:
		access_token = mwoauth.AccessToken(**flask.session['oauth_access_token'])
		auth = requests_oauthlib.OAuth1(client_key=app.config['CONSUMER_KEY'], client_secret=app.config['CONSUMER_SECRET'],
										resource_owner_key=access_token.key, resource_owner_secret=access_token.secret)
		return mwapi.Session(host='https://'+domain, auth=auth, user_agent=user_agent)
	else:
		return None

def getUserInfo(domain = 'meta.wikimedia.org'):
	session = authenticated_session(domain)

	if not session:
		return None, None, {'status':'error','message':'not logged in'}

	try:
		userinfo = session.get(action='query',
								meta='userinfo',
								uiprop=['groups', 'centralids'])['query']['userinfo']
		
		return True, session, {'status':'ok','username':userinfo['name']}
	except mwapi.errors.APIError as e:
		if e.code == 'mwoauth-invalid-authorization-invalid-user':
			# user is viewing a batch for a wiki where they do not have a local user account
			# treat as anonymous on the local wiki, but query Meta to find out if they’re a steward
			
			return None, None, {'status':'error','message':'server error'}

		else:
			raise e
			
	return None, None, {'status':'error','message':'server error'}

@app.route('/', methods=['GET'])
def index_page():
	return render_template('index.html')

#http://127.0.0.1:5000/task/lvwiki/1/Helēna Mārnija
@app.route('/task/<wiki>/<name>/<page>', methods=['GET'])
def getTaskResult(wiki,name,page):
	tasks = Tasks(wiki)

	articleInfo = tasks.getDataForTask(name,page)

	return jsonify(articleInfo)

@app.route('/testing', methods=['GET'])
def runTests():
	tasks = Tasks('lvwiki')

	articleInfo = tasks.runTests()

	return articleInfo

@app.route('/wikis', methods=['GET'])
def listWikis():
	db = DB()
	wikis = db.getAvailableWikis()
	return jsonify(wikis)

@app.route('/tasks/<wiki>', methods=['GET'])
def listJobs(wiki):
	db = DB()
	articles = db.getTasksForWiki(wiki)
	return jsonify(articles)

@app.route('/task/<wiki>/<task_id>/articles', methods=['GET'])
def listArticles(wiki,task_id):
	db = DB()
	articles = db.get_articles_for_task(wiki,task_id)
	return jsonify(articles)
#

@app.route('/typo/<wiki>', methods=['GET'])
def listTypos(wiki):
	db = DB()
	typos = db.getTyposForWiki(wiki)
	return jsonify(typos)


@app.route('/typo/articles', methods=['GET'])
def typo_list_for_wiki():
	db = DB()
	wiki = 'lvwiki'
	typos = db.get_typo_articles(wiki)
	return jsonify(typos)

@app.route('/typo/fix/<article>', methods=['GET'])
def fix_typos(article):
	db = DB()
	typoFixer = TypoFix()

	res = typoFixer.getData('lvwiki', article, db)

	return jsonify(res)

@app.route('/rules/<wiki>', methods=['GET'])
def listRules(wiki):
	db = DB()
	rules = db.getRulesForWiki(wiki)
	return jsonify(rules)

@app.route('/save', methods=['POST'])
def doSave():
	req = request.get_json()
	wiki = req['wiki']
	domain = "{}.wikipedia.org".format(wiki)
	userStatus, session, respFromGettingUserInfo = getUserInfo(domain)

	if not userStatus:
		return jsonify(respFromGettingUserInfo)
	#
	userName = respFromGettingUserInfo['username'] if 'username' in respFromGettingUserInfo else respFromGettingUserInfo['message']
	
	job = req['job']
	article = req['article']
	result = req['result']
	wikitext = req['wikitext']
	status = req['status']

	handlingSave = Save(session)
	respFromSave = handlingSave.saveArticle(job,article,result,wikitext,status,userName)

	return jsonify(respFromSave)

@app.route('/save_typo', methods=['POST'])
def doSaveTypo():
	req = request.get_json()
	wiki = req['wiki']
	domain = "{}.wikipedia.org".format(wiki.replace('wiki',''))
	userStatus, session, respFromGettingUserInfo = getUserInfo(domain)

	if not userStatus:
		return jsonify(respFromGettingUserInfo)
	
	userName = respFromGettingUserInfo['username'] if 'username' in respFromGettingUserInfo else respFromGettingUserInfo['message']
	
	active = req['active']
	case = req['case']
	comment = req['comment']
	dumpsearch = req['dumpsearch']
	minor = req['minor']
	name = req['name']
	regex = req['regex']
	replace_with = req['replace_with']
	search_for = req['search_for']
	test_cases = req['test_cases']
	whole = req['whole']
	id = req['id']
	
	db = DB()
	typoData = db.saveTypo(active,case,comment,dumpsearch,minor,name,regex,replace_with,search_for,test_cases,whole,wiki,userName,id)

	return jsonify({'status':'ok', 'info':typoData})

@app.route('/save_rule', methods=['POST'])
def saveRule():
	req = request.get_json()
	wiki = req['wiki']
	domain = "{}.wikipedia.org".format(wiki.replace('wiki',''))
	userStatus, session, respFromGettingUserInfo = getUserInfo(domain)

	if not userStatus:
		return jsonify(respFromGettingUserInfo)
	
	userName = respFromGettingUserInfo['username'] if 'username' in respFromGettingUserInfo else respFromGettingUserInfo['message']
	
	wiki = req['wiki']
	rule_name = req['rule_name']
	rule_object = req['rule_object']
	rule = req['rule']
	result = req['result']
	id = req['id']
	
	db = DB()
	db.saveRule(id, wiki, rule_name, rule_object, rule, result)

	return jsonify({'status':'ok'})

@app.route('/info', methods=['GET'])
def user_info():
	userStatus, _,respFromGettingUserInfo = getUserInfo()
	
	return jsonify(respFromGettingUserInfo)

@app.route('/login')
def login():
	consumer_token = mwoauth.ConsumerToken(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET'])
	redirect, request_token = mwoauth.initiate('https://meta.wikimedia.org/w/index.php', consumer_token, user_agent=user_agent)
	flask.session['oauth_request_token'] = dict(zip(request_token._fields, request_token))
	return flask.redirect(redirect)

@app.route('/oauth-callback')
def oauth_callback():
	consumer_token = mwoauth.ConsumerToken(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET'])
	request_token = mwoauth.RequestToken(**flask.session.pop('oauth_request_token'))
	access_token = mwoauth.complete('https://meta.wikimedia.org/w/index.php', consumer_token, request_token, flask.request.query_string, user_agent=user_agent)
	flask.session['oauth_access_token'] = dict(zip(access_token._fields, access_token))
	return flask.redirect(flask.url_for('index_page'))

@app.route('/logout')
def logout():
	"""Log the user out by clearing their session."""
	flask.session.clear()
	return flask.redirect(flask.url_for('index_page'))

if __name__ == '__main__':
	app.run(debug=True)
[((348, 445), 'flask.Flask', 'Flask', (['__name__'], {'static_folder': '"""./frontend/build/static"""', 'template_folder': '"""./frontend/build"""'}), "(__name__, static_folder='./frontend/build/static', template_folder=\n    './frontend/build')\n", (353, 445), False, 'from flask import Flask\n'), ((464, 473), 'flask_cors.CORS', 'CORS', (['app'], {}), '(app)\n', (468, 473), False, 'from flask_cors import CORS, cross_origin\n'), ((513, 538), 'os.path.dirname', 'os.path.dirname', (['__file__'], {}), '(__file__)\n', (528, 538), False, 'import os\n'), ((558, 594), 'os.path.join', 'os.path.join', (['__dir__', '"""config.yaml"""'], {}), "(__dir__, 'config.yaml')\n", (570, 594), False, 'import os\n'), ((614, 640), 'yaml.safe_load', 'yaml.safe_load', (['configFile'], {}), '(configFile)\n', (628, 640), False, 'import yaml\n'), ((2000, 2029), 'flask.render_template', 'render_template', (['"""index.html"""'], {}), "('index.html')\n", (2015, 2029), False, 'from flask import render_template\n'), ((2185, 2196), 'tasks.main.Tasks', 'Tasks', (['wiki'], {}), '(wiki)\n', (2190, 2196), False, 'from tasks.main import Tasks\n'), ((2254, 2274), 'flask.jsonify', 'jsonify', (['articleInfo'], {}), '(articleInfo)\n', (2261, 2274), False, 'from flask import jsonify\n'), ((2341, 2356), 'tasks.main.Tasks', 'Tasks', (['"""lvwiki"""'], {}), "('lvwiki')\n", (2346, 2356), False, 'from tasks.main import Tasks\n'), ((2473, 2477), 'db.DB', 'DB', ([], {}), '()\n', (2475, 2477), False, 'from db import DB\n'), ((2518, 2532), 'flask.jsonify', 'jsonify', (['wikis'], {}), '(wikis)\n', (2525, 2532), False, 'from flask import jsonify\n'), ((2605, 2609), 'db.DB', 'DB', ([], {}), '()\n', (2607, 2609), False, 'from db import DB\n'), ((2655, 2672), 'flask.jsonify', 'jsonify', (['articles'], {}), '(articles)\n', (2662, 2672), False, 'from flask import jsonify\n'), ((2775, 2779), 'db.DB', 'DB', ([], {}), '()\n', (2777, 2779), False, 'from db import DB\n'), ((2839, 2856), 'flask.jsonify', 'jsonify', (['articles'], {}), '(articles)\n', (2846, 2856), False, 'from flask import jsonify\n'), ((2931, 2935), 'db.DB', 'DB', ([], {}), '()\n', (2933, 2935), False, 'from db import DB\n'), ((2978, 2992), 'flask.jsonify', 'jsonify', (['typos'], {}), '(typos)\n', (2985, 2992), False, 'from flask import jsonify\n'), ((3073, 3077), 'db.DB', 'DB', ([], {}), '()\n', (3075, 3077), False, 'from db import DB\n'), ((3139, 3153), 'flask.jsonify', 'jsonify', (['typos'], {}), '(typos)\n', (3146, 3153), False, 'from flask import jsonify\n'), ((3236, 3240), 'db.DB', 'DB', ([], {}), '()\n', (3238, 3240), False, 'from db import DB\n'), ((3254, 3263), 'typo.fix.TypoFix', 'TypoFix', ([], {}), '()\n', (3261, 3263), False, 'from typo.fix import TypoFix\n'), ((3322, 3334), 'flask.jsonify', 'jsonify', (['res'], {}), '(res)\n', (3329, 3334), False, 'from flask import jsonify\n'), ((3408, 3412), 'db.DB', 'DB', ([], {}), '()\n', (3410, 3412), False, 'from db import DB\n'), ((3455, 3469), 'flask.jsonify', 'jsonify', (['rules'], {}), '(rules)\n', (3462, 3469), False, 'from flask import jsonify\n'), ((3530, 3548), 'flask.request.get_json', 'request.get_json', ([], {}), '()\n', (3546, 3548), False, 'from flask import request\n'), ((4013, 4026), 'save.Save', 'Save', (['session'], {}), '(session)\n', (4017, 4026), False, 'from save import Save\n'), ((4122, 4143), 'flask.jsonify', 'jsonify', (['respFromSave'], {}), '(respFromSave)\n', (4129, 4143), False, 'from flask import jsonify\n'), ((4213, 4231), 'flask.request.get_json', 'request.get_json', ([], {}), '()\n', (4229, 4231), False, 'from flask import request\n'), ((4889, 4893), 'db.DB', 'DB', ([], {}), '()\n', (4891, 4893), False, 'from db import DB\n'), ((5034, 5077), 'flask.jsonify', 'jsonify', (["{'status': 'ok', 'info': typoData}"], {}), "({'status': 'ok', 'info': typoData})\n", (5041, 5077), False, 'from flask import jsonify\n'), ((5143, 5161), 'flask.request.get_json', 'request.get_json', ([], {}), '()\n', (5159, 5161), False, 'from flask import request\n'), ((5659, 5663), 'db.DB', 'DB', ([], {}), '()\n', (5661, 5663), False, 'from db import DB\n'), ((5734, 5759), 'flask.jsonify', 'jsonify', (["{'status': 'ok'}"], {}), "({'status': 'ok'})\n", (5741, 5759), False, 'from flask import jsonify\n'), ((5879, 5911), 'flask.jsonify', 'jsonify', (['respFromGettingUserInfo'], {}), '(respFromGettingUserInfo)\n', (5886, 5911), False, 'from flask import jsonify\n'), ((5965, 6050), 'mwoauth.ConsumerToken', 'mwoauth.ConsumerToken', (["app.config['CONSUMER_KEY']", "app.config['CONSUMER_SECRET']"], {}), "(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET']\n    )\n", (5986, 6050), False, 'import mwoauth\n'), ((6073, 6174), 'mwoauth.initiate', 'mwoauth.initiate', (['"""https://meta.wikimedia.org/w/index.php"""', 'consumer_token'], {'user_agent': 'user_agent'}), "('https://meta.wikimedia.org/w/index.php', consumer_token,\n    user_agent=user_agent)\n", (6089, 6174), False, 'import mwoauth\n'), ((6267, 6291), 'flask.redirect', 'flask.redirect', (['redirect'], {}), '(redirect)\n', (6281, 6291), False, 'import flask\n'), ((6363, 6448), 'mwoauth.ConsumerToken', 'mwoauth.ConsumerToken', (["app.config['CONSUMER_KEY']", "app.config['CONSUMER_SECRET']"], {}), "(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET']\n    )\n", (6384, 6448), False, 'import mwoauth\n'), ((6542, 6686), 'mwoauth.complete', 'mwoauth.complete', (['"""https://meta.wikimedia.org/w/index.php"""', 'consumer_token', 'request_token', 'flask.request.query_string'], {'user_agent': 'user_agent'}), "('https://meta.wikimedia.org/w/index.php', consumer_token,\n    request_token, flask.request.query_string, user_agent=user_agent)\n", (6558, 6686), False, 'import mwoauth\n'), ((6909, 6930), 'flask.session.clear', 'flask.session.clear', ([], {}), '()\n', (6928, 6930), False, 'import flask\n'), ((761, 819), 'mwoauth.AccessToken', 'mwoauth.AccessToken', ([], {}), "(**flask.session['oauth_access_token'])\n", (780, 819), False, 'import mwoauth\n'), ((829, 1026), 'requests_oauthlib.OAuth1', 'requests_oauthlib.OAuth1', ([], {'client_key': "app.config['CONSUMER_KEY']", 'client_secret': "app.config['CONSUMER_SECRET']", 'resource_owner_key': 'access_token.key', 'resource_owner_secret': 'access_token.secret'}), "(client_key=app.config['CONSUMER_KEY'],\n    client_secret=app.config['CONSUMER_SECRET'], resource_owner_key=\n    access_token.key, resource_owner_secret=access_token.secret)\n", (853, 1026), False, 'import requests_oauthlib\n'), ((1037, 1110), 'mwapi.Session', 'mwapi.Session', ([], {'host': "('https://' + domain)", 'auth': 'auth', 'user_agent': 'user_agent'}), "(host='https://' + domain, auth=auth, user_agent=user_agent)\n", (1050, 1110), False, 'import mwapi\n'), ((3709, 3741), 'flask.jsonify', 'jsonify', (['respFromGettingUserInfo'], {}), '(respFromGettingUserInfo)\n', (3716, 3741), False, 'from flask import jsonify\n'), ((4411, 4443), 'flask.jsonify', 'jsonify', (['respFromGettingUserInfo'], {}), '(respFromGettingUserInfo)\n', (4418, 4443), False, 'from flask import jsonify\n'), ((5341, 5373), 'flask.jsonify', 'jsonify', (['respFromGettingUserInfo'], {}), '(respFromGettingUserInfo)\n', (5348, 5373), False, 'from flask import jsonify\n'), ((6791, 6818), 'flask.url_for', 'flask.url_for', (['"""index_page"""'], {}), "('index_page')\n", (6804, 6818), False, 'import flask\n'), ((6954, 6981), 'flask.url_for', 'flask.url_for', (['"""index_page"""'], {}), "('index_page')\n", (6967, 6981), False, 'import flask\n'), ((6484, 6524), 'flask.session.pop', 'flask.session.pop', (['"""oauth_request_token"""'], {}), "('oauth_request_token')\n", (6501, 6524), False, 'import flask\n')]