#/usr/bin/python2
#encoding=utf-8  
from __future__ import unicode_literals
import sys
import urllib
import urllib2
import json
import ssl
from datetime import datetime,timedelta


sys.path.append(r'C:\\Users\\admin\\Documents\\Visual Studio 2015\\Projects\\PythonApplication1\\PythonApplication1')  
from Tool import Tool 
from Model.Item import *
from Model.AnalyzeData import *
from Model.AttributeEvaluationResult import *
from Model.ItemTracking import *
from Model.ItemCountData import *
from Model.ItemReply import *
from Model.ResearchReport import *
from Model.ItemLabelData import *
from Model.Structured import *


#访问Https时不受信任SSL证书问题
ssl._create_default_https_context = ssl._create_unverified_context
class TaikorOauthClient:
    def __init__(self, userId, appSecert):
        self.userId = userId
        self.appSecert = appSecert
        self.baseApiUrl = "https://api.palaspom.com/"
        self.isAccessTokenSet = False
        self.tokenExpiresTime = datetime.min
        self.tokenType = ""
        self.accessToken = ""
        self.tool = Tool()
        if (not self.RequestToken()):
    	        raise TypeError("Init the client error, Please check UserId and AppSecert setting. Or you can retry it.")

    def IsAuthorized(self):
        if(self.isAccessTokenSet and self.accessToken and self.tokenType and self.tokenExpiresTime > (datetime.now() + timedelta(minutes = 10))):
            return True
        else:
            return False

    def httpGet(self, api, parameters, needAuthorized=True):
        if((not needAuthorized) or self.IsAuthorized() or self.RequestToken()):
            if(not api.startswith('http')):
                api = self.baseApiUrl + api
            if(parameters):
                if(api.find('?') < 0):
                    api = api + "?"
                else:
                    api = api + "&"
                for (d,x) in parameters.items():
                    api = api + d + "=" + str(x) + "&"                
                api = api.rstrip('&')
            req = urllib2.Request(api)  
            req.add_header('Content-Type', 'application/json') 
            if(needAuthorized):
                req.add_header('Authorization', self.tokenType + ' ' + self.accessToken)
            try:
                resp = urllib2.urlopen(req)
                content = resp.read()
                if(content):
                    result = json.loads(content)
                    return result
            except urllib2.HTTPError as e:
                if(e.code == 401 or e.code == 403):
                    self.RequestToken()
                    req.add_header('Authorization', self.tokenType + ' ' + self.accessToken)
                    resp = urllib2.urlopen(req)
                    content = resp.read()  
                    if(content):
                        result = json.loads(content,encoding="acsii")
                        return result
        else:
            raise TypeError("Error, Has refused to authorize this request.")

    def httpPost(self, api, parameters, needAuthorized=True):
        if((not needAuthorized) or self.IsAuthorized() or self.RequestToken()):
            if(not api.startswith('http')):
                api = self.baseApiUrl + api
            params = urllib.urlencode(parameters)
            req = urllib2.Request(api, params)  
            req.add_header('Content-Type', 'application/json') 
            if(needAuthorized):
                req.add_header('Authorization', self.tokenType + ' ' + self.accessToken)
            try:
                resp = urllib2.urlopen(req)
                content = resp.read()  
                if(content):
                    result = json.loads(content)
                    return result
            except urllib2.HTTPError as e:
                if(e.code == 401 or e.code == 403):
                    self.RequestToken()
                    req.add_header('Authorization', self.tokenType + ' ' + self.accessToken)
                    resp = urllib2.urlopen(req)
                    content = resp.read()  
                    if(content):
                        result = json.loads(content)
                        return result
        else:
            raise TypeError("Error, Has refused to authorize this request.")

    def RequestToken(self):
        if(not self.userId and not self.appSecert):
            raise TypeError("Please set the UserId and AppSecert before you request. You can get this from https://daas.palaspom.com/Login/Authority.")
        paramsData = {'userId': self.userId, 'appSecert': self.appSecert}   
        self.isAccessTokenSet = False
        api = "Oauth2/Authorize"
        result = self.httpGet(api,paramsData,False)
        #打印token，可以注释掉不打印
        print(result)
        if(result):
            if(result and (not result['IsError']) and (not result['IsHttpError']) and result['AccessToken']):
                self.tokenExpiresTime = datetime.now() + timedelta(seconds = int(result['ExpiresIn']))
                self.accessToken = result['AccessToken']
                self.tokenType = result['TokenType']
                self.isAccessTokenSet = True
                return True
        else:
            return False
 
   
      #公开函数：将返回的JSON字符串解析成多个Item的集合ItemList
    def handleItemList(self,returnJson,ItemList): 
            """
            :param returnJson: JSON对象 
            :param ItemList: 用于存储获取的数据
            :param count: 一页多少条（注意：可能不足规定条数）
            :return: list
            """
            try: 
                #各种反序列化、索引、解析、unicode编码都试了一遍，太坑了
                Temp_Json= returnJson.replace(":null" ,":''").replace(":true" ,":1").replace(":false" ,":0");
                Temp_jsonObj= eval(Temp_Json);
                count=len(Temp_jsonObj);
                num=0;
                for num in range(0,count): 
                    if(not Temp_jsonObj[num]):break;

                    #未实例化之前的对象列表 用TOOL_标注,实际包装时使用不带Tool_的
                    item = Item(); 
                    #region
                    #第一步:AnalyzeData构造 
                    Tool_ItemAnalyzeDataList=Temp_jsonObj[num]["AnalyzeData"];

                      #region for Temp_AnalyzeData
                    for  Temp_AnalyzeData in Tool_ItemAnalyzeDataList: #只有1个AnalyzeData
                            AnalyzeDataObj= AnalyzeData();
                            AnalyzeDataObj.IssueID=Temp_AnalyzeData["IssueID"]; 
                            AnalyzeDataObj.MergeMethod=Temp_AnalyzeData["MergeMethod"];
                            AnalyzeDataObj.CategoryIDs=Temp_AnalyzeData["CategoryIDs"];
                            AnalyzeDataObj.DepartmentIDs=Temp_AnalyzeData["DepartmentIDs"];
                            AnalyzeDataObj.IndustryIDs=Temp_AnalyzeData["IndustryIDs"];
                            AnalyzeDataObj.Product=Temp_AnalyzeData["Product"];
                            AnalyzeDataObj.TopicIDs=Temp_AnalyzeData["TopicIDs"];
                            AnalyzeDataObj.OrganizationIDs=Temp_AnalyzeData["OrganizationIDs"];
                            AnalyzeDataObj.People=Temp_AnalyzeData["People"];
                            AnalyzeDataObj.Region=Temp_AnalyzeData["Region"];
                            AnalyzeDataObj.Keywords=Temp_AnalyzeData["Keywords"];

                            for  Temp_AnalyzeData_Evaluation in Temp_AnalyzeData["Evaluation"]:
                               Temp_Evaluation= AttributeEvaluationResult(Temp_AnalyzeData_Evaluation["Attribute"],Temp_AnalyzeData_Evaluation["Value"],Temp_AnalyzeData_Evaluation["MatchedWords"]);
                               AnalyzeDataObj.Evaluation.append(Temp_Evaluation);

                            AnalyzeDataObj.MarketIDs=Temp_AnalyzeData["MarketIDs"];
                            AnalyzeDataObj.BlockIDs=Temp_AnalyzeData["BlockIDs"];
                            AnalyzeDataObj.StockIDs=Temp_AnalyzeData["StockIDs"];
                            AnalyzeDataObj.RelatedEventID=Temp_AnalyzeData["RelatedEventID"];
                            AnalyzeDataObj.DuplicationID=Temp_AnalyzeData["DuplicationID"];
               

                            AnalyzeDataObj.ProsdMedia=Temp_AnalyzeData["ProsdMedia"];
                            AnalyzeDataObj.ProsdSplite=Temp_AnalyzeData["ProsdSplite"];
                            AnalyzeDataObj.ProsdCategory=Temp_AnalyzeData["ProsdCategory"];
                            AnalyzeDataObj.ProsdDepartment=Temp_AnalyzeData["ProsdDepartment"];
                            AnalyzeDataObj.ProsdMedia=Temp_AnalyzeData["ProsdMedia"];
                            AnalyzeDataObj.ProsdIndustry=Temp_AnalyzeData["ProsdIndustry"];
                            AnalyzeDataObj.ProsdProduct=Temp_AnalyzeData["ProsdProduct"];
                            AnalyzeDataObj.ProsdPeople=Temp_AnalyzeData["ProsdPeople"];
                            AnalyzeDataObj.ProsdOrganization=Temp_AnalyzeData["ProsdOrganization"];
                            AnalyzeDataObj.ProsdRegion=Temp_AnalyzeData["ProsdRegion"];
                            AnalyzeDataObj.ProsdSentiment=Temp_AnalyzeData["ProsdSentiment"];
                            AnalyzeDataObj.ProsdSentiment8=Temp_AnalyzeData["ProsdSentiment8"];
                            AnalyzeDataObj.ProsdSentiment2=Temp_AnalyzeData["ProsdSentiment2"];
                            AnalyzeDataObj.ProsdKeyword=Temp_AnalyzeData["ProsdKeyword"];
                            AnalyzeDataObj.prosdIG=Temp_AnalyzeData["prosdIG"];

                            AnalyzeDataObj.Sentiment=Temp_AnalyzeData["Sentiment"];
                            AnalyzeDataObj.EmotionHappy=Temp_AnalyzeData["EmotionHappy"];
                            AnalyzeDataObj.EmotionAccept=Temp_AnalyzeData["EmotionAccept"];
                            AnalyzeDataObj.EmotionSurprise=Temp_AnalyzeData["EmotionSurprise"];
                            AnalyzeDataObj.EmotionFear=Temp_AnalyzeData["EmotionFear"];
                            AnalyzeDataObj.EmotionSad=Temp_AnalyzeData["EmotionSad"];
                            AnalyzeDataObj.EmotionHate=Temp_AnalyzeData["EmotionHate"];
                            AnalyzeDataObj.EmotionExpect=Temp_AnalyzeData["EmotionExpect"];
                            AnalyzeDataObj.EmotionAngry=Temp_AnalyzeData["EmotionAngry"];
                            AnalyzeDataObj.EmotionPositive=Temp_AnalyzeData["EmotionPositive"];
                            AnalyzeDataObj.EmotionNegative=Temp_AnalyzeData["EmotionNegative"];
                            AnalyzeDataObj.IG=Temp_AnalyzeData["IG"];
                            #第一步:将AnalyzeData加入item中的ItemAnalyzeDataList
                            item.ItemAnalyzeDataList.append(AnalyzeDataObj);
                            del AnalyzeDataObj;
                      #endregion endfor Temp_AnalyzeData
                    #第一步END:AnalyzeData构造

                    #第二步:Item构造 
                       #第二步:Item里几个“对象、列表 对象”，单独进行初始化和赋值 
                    item.UpdateTime=Temp_jsonObj[num]["UpdateTime"]; 
                    item.IndexTime=Temp_jsonObj[num]["IndexTime"]; 
                    item.ContentDetailLevel=Temp_jsonObj[num]["ContentDetailLevel"]; 
                    item.ItemID=Temp_jsonObj[num]["ItemID"]; 

                    item.ClientItemID=Temp_jsonObj[num]["ClientItemID"]; 
                    item.ParentItemID=Temp_jsonObj[num]["ParentItemID"]; 
                    item.Url=Temp_jsonObj[num]["Url"]; 
                    item.CleanTitle=Temp_jsonObj[num]["CleanTitle"]; 
                    item.ShortTitle=Temp_jsonObj[num]["ShortTitle"]; 
                    item.CleanText=Temp_jsonObj[num]["CleanText"]; 
                    item.Summary=Temp_jsonObj[num]["Summary"]; 
                    item.PubDate=Temp_jsonObj[num]["PubDate"]; 

                    item.AuthorName=Temp_jsonObj[num]["AuthorName"]; 
                    item.AuthorID=Temp_jsonObj[num]["AuthorID"]; 
                    item.AuthorTag=Temp_jsonObj[num]["AuthorTag"]; 
                    item.Source=Temp_jsonObj[num]["Source"]; 
                    item.RetweetID=Temp_jsonObj[num]["RetweetID"]; 

                    item.MediaID=Temp_jsonObj[num]["MediaID"]; 
                    item.MediaName=Temp_jsonObj[num]["MediaName"]; 
                    item.MediaChannel=Temp_jsonObj[num]["MediaChannel"]; 
                    item.Rank=Temp_jsonObj[num]["Rank"]; 

                    item.MediaType=Temp_jsonObj[num]["MediaType"]; 
                    item.MediaRegionType=Temp_jsonObj[num]["MediaRegionType"]; 
                    item.MediaWeight=Temp_jsonObj[num]["MediaWeight"]; 
                    item.MediaOrganType=Temp_jsonObj[num]["MediaOrganType"]; 
                    item.MediaStyle=Temp_jsonObj[num]["MediaStyle"]; 
                    item.MediaTendency=Temp_jsonObj[num]["MediaTendency"]; 
                    item.MediaIndustryIDs=Temp_jsonObj[num]["MediaIndustryIDs"]; 
                    item.MediaTag=Temp_jsonObj[num]["MediaTag"]; 

                    item.ProxyZone=Temp_jsonObj[num]["ProxyZone"]; 
                    item.ReproducedMediaID=Temp_jsonObj[num]["ReproducedMediaID"]; 
                    item.ReproducedMediaName=Temp_jsonObj[num]["ReproducedMediaName"]; 
                    item.ReproducedUrl=Temp_jsonObj[num]["ReproducedUrl"]; 
                    item.MediaCopyright=Temp_jsonObj[num]["MediaCopyright"]; 

                    #对象ItemTracking
                    Temp_Tracking=Temp_jsonObj[num]["Tracking"];
                    if(not Temp_Tracking or Temp_Tracking==""):
                            item.Tracking="";
                    else:
                            item.Tracking= ItemTracking(Temp_Tracking["FollowStatus"],
                                                        Temp_Tracking["FollowNextTime"],
                                                        Temp_Tracking["FollowPriority"],
                                                        Temp_Tracking["LastReplyUrl"],
                                                        Temp_Tracking["LastReplyPageNo"],
                                                        Temp_Tracking["LastReply_SinceID"],
                                                        Temp_Tracking["LastReplyDate"],
                                                        Temp_Tracking["LastReplyAuthorID"],
                                                        Temp_Tracking["LastReplyAuthorName"],
                                                        Temp_Tracking["ReplyCount,FollowCount"],
                                                        Temp_Tracking["FollowErrorCount"]);
                    
                    #对象ItemTracking
                    Temp_Tracking_Forward=Temp_jsonObj[num]["Tracking_Forward"];
                    if(not Temp_Tracking_Forward or Temp_Tracking_Forward==""):
                            item.Tracking_Forward="";
                    else:
                            item.Tracking_Forward=ItemTracking( Temp_Tracking_Forward["FollowStatus"],
                                                                Temp_Tracking_Forward["FollowNextTime"],
                                                                Temp_Tracking_Forward["FollowPriority"],
                                                                Temp_Tracking_Forward["LastReplyUrl"],
                                                                Temp_Tracking_Forward["LastReplyPageNo"],
                                                                Temp_Tracking_Forward["LastReply_SinceID"],
                                                                Temp_Tracking_Forward["LastReplyDate"],
                                                                Temp_Tracking_Forward["LastReplyAuthorID"],
                                                                Temp_Tracking_Forward["LastReplyAuthorName"],
                                                                Temp_Tracking_Forward["ReplyCount,FollowCount"],
                                                                Temp_Tracking_Forward["FollowErrorCount"]);

                    #对象ItemCountData
                    Temp_CurrentCount=Temp_jsonObj[num]["CurrentCount"]; 
                    if(not Temp_CurrentCount or Temp_CurrentCount==""):
                            item.CurrentCount="";
                    else:
                            item.CurrentCount=ItemCountData(Temp_CurrentCount["ViewCount"],
                                                            Temp_CurrentCount["ReplyCount"],
                                                            Temp_CurrentCount["ForwardCount"],
                                                            Temp_CurrentCount["FetchTime"]);

                    #列表 对象ItemCountData[]
                    for Temp_CountHistory in Temp_jsonObj[num]["CountHistory"]:
                           T_CountHistory=ItemCountData(Temp_CountHistory["ViewCount"],
                                                        Temp_CountHistory["ReplyCount"],
                                                        Temp_CountHistory["ForwardCount"],
                                                        Temp_CountHistory["FetchTime"]);
                           item.CountHistory.append(T_CountHistory);
                            
                    #列表 对象ItemReply[]
                    for Temp_Reply in Temp_jsonObj[num]["Reply"]:
                        T_Reply=ItemReply(  Temp_Reply["ItemID"],
                                            Temp_Reply["CleanText"],
                                            Temp_Reply["FetchTime"],
                                            Temp_Reply["PubDate"],
                                            Temp_Reply["AuthorName"],
                                            Temp_Reply["AuthorID"],
                                            Temp_Reply["Location"],
                                            Temp_Reply["Source"],
                                            Temp_Reply["Mark"]);
                        item.Reply.append(T_Reply);
                            

                    item.DuplicationID=Temp_jsonObj[num]["DuplicationID"]; 
                    item.SpliteTitle=Temp_jsonObj[num]["SpliteTitle"]; 
                    item.SpliteText=Temp_jsonObj[num]["SpliteText"]; 
                    item.ProsdDuplication=Temp_jsonObj[num]["ProsdDuplication"]; 
                    item.Tag=Temp_jsonObj[num]["Tag"]; 
                    #对象ResearchReport
                    Temp_ResearchReport=Temp_jsonObj[num]["ResearchReport"]; 
                    if(not Temp_ResearchReport or Temp_ResearchReport==""):
                            item.ResearchReport="";
                    else:
                            item.ResearchReport=ResearchReport(Temp_ResearchReport["ReportType"],Temp_ResearchReport["ReportAgency"]);

                    #列表对象ItemLabelData[] 
                    for Temp_LabelData in Temp_jsonObj[num]["LabelData"]:
                        T_LabelData=ItemLabelData(Temp_LabelData["IssueID"]);
                        item.LabelData.append(T_LabelData); 

                    item.IsOriginalDeleted=Temp_jsonObj[num]["IsOriginalDeleted"]; 
                    item.IsEPRPublished=Temp_jsonObj[num]["IsEPRPublished"]; 
                    #对象Structured
                    Temp_Struct=Temp_jsonObj[num]["Struct"];  
                    if(not Temp_Struct or Temp_Struct==""):
                            item.Struct="";
                    else:
                            item.Struct=Structured( Temp_Struct["StructId"],
                                                    Temp_Struct["Category"],
                                                    Temp_Struct["Subject"],
                                                    Temp_Struct["Keypoint"],
                                                    Temp_Struct["MarketImpact"]);

                    #第二步END:Item构造 

                    #endregion
                    #第二步:Item放入ItemList
                    ItemList.append(item);

                    #测试:能否取出来

                    #v=item.CleanTitle;
                    #if not (not item.Struct or item.Struct==""):
                    #    t=item.Struct.StructId;
                    #p=item.ItemAnalyzeDataList[0];
                    #k=p.IssueID

                    #测试END:能否取出来
                    del item;
                    #第二步END:Item放入ItemList
                else:# 循环正常执行完
                       print num, '解析完成1次'
                       return ItemList;
            except Exception,err:
             print err
      