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)
[((20, 6, 20, 98), 'flask.Flask', 'Flask', (), '', False, 'from flask import Flask\n'), ((22, 0, 22, 9), 'flask_cors.CORS', 'CORS', ({(22, 5, 22, 8): 'app'}, {}), '(app)', False, 'from flask_cors import CORS, cross_origin\n'), ((26, 10, 26, 35), 'os.path.dirname', 'os.path.dirname', ({(26, 26, 26, 34): '__file__'}, {}), '(__file__)', False, 'import os\n'), ((28, 18, 28, 54), 'os.path.join', 'os.path.join', ({(28, 31, 28, 38): '__dir__', (28, 40, 28, 53): '"""config.yaml"""'}, {}), "(__dir__, 'config.yaml')", False, 'import os\n'), ((29, 18, 29, 44), 'yaml.safe_load', 'yaml.safe_load', ({(29, 33, 29, 43): 'configFile'}, {}), '(configFile)', False, 'import yaml\n'), ((66, 8, 66, 37), 'flask.render_template', 'render_template', ({(66, 24, 66, 36): '"""index.html"""'}, {}), "('index.html')", False, 'from flask import render_template\n'), ((71, 9, 71, 20), 'tasks.main.Tasks', 'Tasks', ({(71, 15, 71, 19): 'wiki'}, {}), '(wiki)', False, 'from tasks.main import Tasks\n'), ((75, 8, 75, 28), 'flask.jsonify', 'jsonify', ({(75, 16, 75, 27): 'articleInfo'}, {}), '(articleInfo)', False, 'from flask import jsonify\n'), ((79, 9, 79, 24), 'tasks.main.Tasks', 'Tasks', ({(79, 15, 79, 23): '"""lvwiki"""'}, {}), "('lvwiki')", False, 'from tasks.main import Tasks\n'), ((87, 6, 87, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((89, 8, 89, 22), 'flask.jsonify', 'jsonify', ({(89, 16, 89, 21): 'wikis'}, {}), '(wikis)', False, 'from flask import jsonify\n'), ((93, 6, 93, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((95, 8, 95, 25), 'flask.jsonify', 'jsonify', ({(95, 16, 95, 24): 'articles'}, {}), '(articles)', False, 'from flask import jsonify\n'), ((99, 6, 99, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((101, 8, 101, 25), 'flask.jsonify', 'jsonify', ({(101, 16, 101, 24): 'articles'}, {}), '(articles)', False, 'from flask import jsonify\n'), ((106, 6, 106, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((108, 8, 108, 22), 'flask.jsonify', 'jsonify', ({(108, 16, 108, 21): 'typos'}, {}), '(typos)', False, 'from flask import jsonify\n'), ((113, 6, 113, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((116, 8, 116, 22), 'flask.jsonify', 'jsonify', ({(116, 16, 116, 21): 'typos'}, {}), '(typos)', False, 'from flask import jsonify\n'), ((120, 6, 120, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((121, 13, 121, 22), 'typo.fix.TypoFix', 'TypoFix', ({}, {}), '()', False, 'from typo.fix import TypoFix\n'), ((125, 8, 125, 20), 'flask.jsonify', 'jsonify', ({(125, 16, 125, 19): 'res'}, {}), '(res)', False, 'from flask import jsonify\n'), ((129, 6, 129, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((131, 8, 131, 22), 'flask.jsonify', 'jsonify', ({(131, 16, 131, 21): 'rules'}, {}), '(rules)', False, 'from flask import jsonify\n'), ((135, 7, 135, 25), 'flask.request.get_json', 'request.get_json', ({}, {}), '()', False, 'from flask import request\n'), ((151, 16, 151, 29), 'save.Save', 'Save', ({(151, 21, 151, 28): 'session'}, {}), '(session)', False, 'from save import Save\n'), ((154, 8, 154, 29), 'flask.jsonify', 'jsonify', ({(154, 16, 154, 28): 'respFromSave'}, {}), '(respFromSave)', False, 'from flask import jsonify\n'), ((158, 7, 158, 25), 'flask.request.get_json', 'request.get_json', ({}, {}), '()', False, 'from flask import request\n'), ((181, 6, 181, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((184, 8, 184, 49), 'flask.jsonify', 'jsonify', ({(184, 16, 184, 48): "{'status': 'ok', 'info': typoData}"}, {}), "({'status': 'ok', 'info': typoData})", False, 'from flask import jsonify\n'), ((188, 7, 188, 25), 'flask.request.get_json', 'request.get_json', ({}, {}), '()', False, 'from flask import request\n'), ((205, 6, 205, 10), 'db.DB', 'DB', ({}, {}), '()', False, 'from db import DB\n'), ((208, 8, 208, 32), 'flask.jsonify', 'jsonify', ({(208, 16, 208, 31): "{'status': 'ok'}"}, {}), "({'status': 'ok'})", False, 'from flask import jsonify\n'), ((214, 8, 214, 40), 'flask.jsonify', 'jsonify', ({(214, 16, 214, 39): 'respFromGettingUserInfo'}, {}), '(respFromGettingUserInfo)', False, 'from flask import jsonify\n'), ((218, 18, 218, 98), 'mwoauth.ConsumerToken', 'mwoauth.ConsumerToken', ({(218, 40, 218, 66): "app.config['CONSUMER_KEY']", (218, 68, 218, 97): "app.config['CONSUMER_SECRET']"}, {}), "(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET']\n    )", False, 'import mwoauth\n'), ((219, 27, 219, 124), 'mwoauth.initiate', 'mwoauth.initiate', (), '', False, 'import mwoauth\n'), ((221, 8, 221, 32), 'flask.redirect', 'flask.redirect', ({(221, 23, 221, 31): 'redirect'}, {}), '(redirect)', False, 'import flask\n'), ((225, 18, 225, 98), 'mwoauth.ConsumerToken', 'mwoauth.ConsumerToken', ({(225, 40, 225, 66): "app.config['CONSUMER_KEY']", (225, 68, 225, 97): "app.config['CONSUMER_SECRET']"}, {}), "(app.config['CONSUMER_KEY'], app.config['CONSUMER_SECRET']\n    )", False, 'import mwoauth\n'), ((227, 16, 227, 156), 'mwoauth.complete', 'mwoauth.complete', (), '', False, 'import mwoauth\n'), ((234, 1, 234, 22), 'flask.session.clear', 'flask.session.clear', ({}, {}), '()', False, 'import flask\n'), ((33, 17, 33, 75), 'mwoauth.AccessToken', 'mwoauth.AccessToken', ({}, {}), "(**flask.session['oauth_access_token'])", False, 'import mwoauth\n'), ((34, 9, 35, 89), 'requests_oauthlib.OAuth1', 'requests_oauthlib.OAuth1', (), '', False, 'import requests_oauthlib\n'), ((36, 9, 36, 80), 'mwapi.Session', 'mwapi.Session', (), '', False, 'import mwapi\n'), ((141, 9, 141, 41), 'flask.jsonify', 'jsonify', ({(141, 17, 141, 40): 'respFromGettingUserInfo'}, {}), '(respFromGettingUserInfo)', False, 'from flask import jsonify\n'), ((164, 9, 164, 41), 'flask.jsonify', 'jsonify', ({(164, 17, 164, 40): 'respFromGettingUserInfo'}, {}), '(respFromGettingUserInfo)', False, 'from flask import jsonify\n'), ((194, 9, 194, 41), 'flask.jsonify', 'jsonify', ({(194, 17, 194, 40): 'respFromGettingUserInfo'}, {}), '(respFromGettingUserInfo)', False, 'from flask import jsonify\n'), ((229, 23, 229, 50), 'flask.url_for', 'flask.url_for', ({(229, 37, 229, 49): '"""index_page"""'}, {}), "('index_page')", False, 'import flask\n'), ((235, 23, 235, 50), 'flask.url_for', 'flask.url_for', ({(235, 37, 235, 49): '"""index_page"""'}, {}), "('index_page')", False, 'import flask\n'), ((226, 40, 226, 80), 'flask.session.pop', 'flask.session.pop', ({(226, 58, 226, 79): '"""oauth_request_token"""'}, {}), "('oauth_request_token')", False, 'import flask\n')]