Mercurial > hg > horiscopes
diff V5/synastry.py @ 23:11d4e438045e
make version 5
author | DaveM |
---|---|
date | Mon, 09 Apr 2018 15:07:21 +0100 |
parents | |
children | d2bd074d9284 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/V5/synastry.py Mon Apr 09 15:07:21 2018 +0100 @@ -0,0 +1,340 @@ +import random +import csv +import re +import requests +import time +from bs4 import BeautifulSoup + +import pdb + +class compatibility: + def __init__(self): + self.rules = [] + self.uniqueID = 0 + print 'Warning, need to fix [Vertex, Ascendant House, South Node, IC/MC and None Location] issues' + + def addRule(self,planetTuple,aspectList,score): + rule = compatibilityRule(self.uniqueID,planetTuple,aspectList,score) + self.rules.append(rule) + self.uniqueID += 1 + + def findRule(self,planet): + ruleList = [r for r in self.rules if r.planet == planet] + print ruleList + return ruleList + + def readFile(self,filename): + text = [] + with open(filename) as fp: + line = fp.readline() + text.append(line.strip()) + while line: + line = fp.readline() + text.append(line.strip()) + return text + + def parseCompatRules(self,filename): + comList = self.readFile(filename) + for com in comList: + # print com + planetTuple = None + aspectList = None + score = None + c = com.split(',') + if len(c) == 4: + if len(c[1]) > 1: + aspectList = [] + planetTuple = tuple((c[0].lower(),c[2].lower())) + score = int(c[3]) + for subset in c[1].lower().split(' '): + aspectList.append(subset) + elif len(c[1]) == 0 : + if 'house' not in c[2]: + print 'some error where rule is not house' + planetTuple = (c[0].lower(),'house') + houseNo = re.findall('\d+', c[2]) + if len(houseNo) != 1: + print 'multiple house numbers found - ERROR' + aspectList = int(houseNo[0]) + score = int(c[3]) + self.addRule(planetTuple,aspectList,score) + + def calcCompatibility(self, horiscope): + score = 0 + for r in sorted(self.rules): + if 'vertex' in r.planet: + # print 'ERROR - catch Vertex issue' + pass + elif 'southnode' in r.planet: + # print 'ERROR - catch South Node issue' + pass + elif 'ic/mc' in r.planet: + # print 'ERROR - catch IC/MC issue' + pass + elif r.planet[1] == 'house' and r.planet[0] == 'asc': + # print 'ERROR - catch Ascendant House issue' + pass + elif horiscope.planets[r.planet[0]].angleA is None: + # print 'Error - None Location' + return None + elif r.planet[1] == 'house': + if horiscope.isInHouse(r.planet[0],r.aspect): + score += r.score + print r.planet[0] +' '+ r.planet[1] +' '+ str(aspect)+' '+str(r.score) + elif r.planet[0] == r.planet[1]: + aspect,variance = horiscope.calcAspect(r.planet[0],r.planet[1]) + if aspect is not None: + if aspect in r.aspect: + score += r.score + print r.planet[0]+' '+aspect +' '+ r.planet[1] +' '+ str(r.score) + else: + for order in [0,1]: + aspect,variance = horiscope.calcAspect(r.planet[order],r.planet[not order]) + if aspect is not None: + # print aspect + # currentR = r + # pdb.set_trace() + if aspect in r.aspect: + score += r.score + print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' '+ str(r.score) + else: + print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' 0' + print score + return score + + + + +class compatibilityRule: + def __init__(self,uniqueId,planetTuple,aspectList,score): + self.id = uniqueId + self.planet = planetTuple + self.aspect = aspectList + self.score = score + + +class Person: + url = 'https://horoscopes.astro-seek.com/calculate-love-compatibility/' + def __init__(self,personDict): + # self. = planetPositions() + self.id = personDict['ID'] + self.dob = personDict['DOB'] + self.tob = personDict['TOB'] + self.cob = personDict['COB'] + self.p_dob = personDict['pDOB'] + self.p_tob = personDict['pTOB'] + self.p_cob = personDict['pCOB'] + self.horiscope = None + self.resp = None + self.issue = 'INCOMPLETE' + + def identifyIssues(self): + if self.id is None: + self.issue = 'id' + elif self.dob is None: + self.issue = 'dob' + elif self.tob is None: + self.issue = 'tob' + elif self.cob is None: + self.issue = 'cob' + elif self.p_dob is None: + self.issue = 'p_dob' + elif self.p_tob is None: + self.issue = 'p_tob' + elif self.p_cob is None: + self.issue = 'p_cob' + else: + self.issue = None + return self.issue + + def makePayload(self): + if type(self.cob) is str: + cob_0 = float(self.cob.split(',')[0][1:]) + cob_1 = float(self.cob.split(',')[1]) + self.cob = (cob_0,cob_1) + if type(self.p_cob) is str: + pcob_0 = float(self.p_cob.split(',')[0][1:]) + pcob_1 = float(self.p_cob.split(',')[1]) + self.p_cob = (pcob_0,pcob_1) + if type(self.dob) is str: + self.dob = self.dob[1:-1].split(',') + if type(self.p_dob) is str: + self.p_dob = self.p_dob[1:-1].split(',') + if type(self.tob) is str: + self.tob = self.tob[1:-1].split(',') + if type(self.p_tob) is str: + self.p_tob = self.p_tob[1:-1].split(',') + + self.payload = {'send_calculation':'1', #Req + 'muz_narozeni_den':self.dob[0], + 'muz_narozeni_mesic':self.dob[1], + 'muz_narozeni_rok':self.dob[2], + 'muz_narozeni_hodina':self.tob[0], + 'muz_narozeni_minuta':self.tob[1], + 'muz_narozeni_city':'', + 'muz_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',#auto + 'muz_narozeni_stat_hidden':'XX', + 'muz_narozeni_podstat_kratky_hidden':'', + 'muz_narozeni_podstat_hidden':'', + 'muz_narozeni_podstat2_kratky_hidden':'', + 'muz_narozeni_podstat3_kratky_hidden':'', + 'muz_narozeni_input_hidden':'', + 'muz_narozeni_sirka_stupne':str(abs(self.cob[0])).split('.')[0], + 'muz_narozeni_sirka_minuty':str(float('0.'+str(self.cob[0]).split('.')[1])*60).split('.')[0], + 'muz_narozeni_sirka_smer': '1' if self.cob[0]<0 else '0', #address N Dir (0':'N',1':'S) + 'muz_narozeni_delka_stupne':str(abs(self.cob[1])).split('.')[0], #address E - Main + 'muz_narozeni_delka_minuty':str(float('0.'+str(self.cob[1]).split('.')[1])*60).split('.')[0], + 'muz_narozeni_delka_smer': '1' if self.cob[1]<0 else '0', #address E Dir (0':'E',1':'W) + 'muz_narozeni_timezone_form':'auto', + 'muz_narozeni_timezone_dst_form':'auto', + 'send_calculation':'1', + 'zena_narozeni_den':self.p_dob[0], + 'zena_narozeni_mesic':self.p_dob[1], + 'zena_narozeni_rok':self.p_dob[2], + 'zena_narozeni_hodina':self.p_tob[0], + 'zena_narozeni_minuta':self.p_tob[1], + 'zena_narozeni_city':'', + 'zena_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E', + 'zena_narozeni_stat_hidden':'XX', + 'zena_narozeni_podstat_kratky_hidden':'', + 'zena_narozeni_podstat_hidden':'', + 'zena_narozeni_podstat2_kratky_hidden':'', + 'zena_narozeni_podstat3_kratky_hidden':'', + 'zena_narozeni_input_hidden':'', + 'zena_narozeni_sirka_stupne':str(abs(self.p_cob[0])).split('.')[0], + 'zena_narozeni_sirka_minuty':str(float('0.'+str(self.p_cob[0]).split('.')[1])*60).split('.')[0], + 'zena_narozeni_sirka_smer': '1' if self.p_cob[0]<0 else '0', + 'zena_narozeni_delka_stupne':str(abs(self.p_cob[1])).split('.')[0], + 'zena_narozeni_delka_minuty':str(float('0.'+str(self.p_cob[1]).split('.')[1])*60).split('.')[0], + 'zena_narozeni_delka_smer': '1' if self.p_cob[1]<0 else '0', + 'zena_narozeni_timezone_form':'auto', + 'zena_narozeni_timezone_dst_form':'auto', + 'switch_interpretations':'0', + 'house_system':'placidus', + 'uhel_orbis':'#tabs_redraw'} + + def requestURL(self): + self.resp = requests.get(self.url, params=self.payload) + time.sleep(5) + return self.resp + + def parsePage(self): + self.horiscope = None + if('Please use valid date.' in self.resp.content): + self.issue = 'dob' + return self.horiscope + elif('Please use valid time.' in self.resp.content): + self.issue = 'tob' + return self.horiscope + gotLocation = 0 + self.horiscope = planetPositions() + soup = BeautifulSoup(self.resp.content, 'lxml') + tcCell = soup.find_all('div', attrs={'class':'right-sedy-banner-svetlejsi'}) + for cell in tcCell: + if "Planets in partner's house" in cell.get_text(): + gotLocation = 1 + divList = cell.find_all('div') + for i in range(len(divList)): + planetName = divList[i].getText().lower().strip().replace(':','').split(' ')[0] + if planetName in planetPositions.planetNames: + if gotLocation and not '/' in planetName: + self.horiscope.planets[planetName].setHouse(divList[i+2].getText(),divList[i+4].getText()) + else: + self.horiscope.planets[planetName].setLocation(divList[i+2].getText(),divList[i+1].img.attrs['alt'],0) + self.horiscope.planets[planetName].setLocation(divList[i+4].getText(),divList[i+3].img.attrs['alt'],1) + return self.horiscope + + + +class planetRelation: + noHouseList = ['asc','ic','dsc','mc','asc/mc','sun/moon'] + zodiacAngle = {'aries':0,'taurus':30,'gemini':60,'cancer':90,'leo':120,'virgo':150,'libra':180,'scorpio':210,'sagittarius':240,'capricorn':270,'aquarius':300,'pisces':330} + + def __init__(self,planetName): + self.name = planetName + self.angleA = None + self.angleB = None + if planetName not in planetRelation.noHouseList: + self.houseA = None + self.houseB = None + + def setLocation(self,value,sign,isB): + signVal = planetRelation.zodiacAngle[sign.lower()] + signVal+= float('.'.join(value.encode('ascii','replace').split('?'))[:-1]) + # print self.name,sign.lower(),planetRelation.zodiacAngle[sign.lower()],value,signVal + if not isB: + self.angleA = signVal + else: + self.angleB = signVal + + def setHouse(self,A,B): + self.houseA = int(A.encode('ascii','ignore')) + self.houseB = int(B.encode('ascii','ignore')) + + def test_random(self): + self.angleA = random.random()*360 + self.angleB = random.random()*360 + + +class planetPositions: + aspectDict = {'conjunction':0,'semi-square':45,'sextile':60,'square':90,'trine':120,'opposition':180} + # zodiacAngle = {'aries':0,'taurus':30,'gemini':60,'cancer':90,'leo':120,'virgo':150,'libra':180,'scorpio':210,'sagittarius':240,'capricorn':270,'aquarius':300,'pisces':330} + # Taken from https://en.wikipedia.org/wiki/Astrological_sign, with reference from https://en.wikipedia.org/wiki/Astrological_symbols#Signs_of_the_zodiac + planetNames = ['sun','moon','mercury','venus','mars','jupiter','saturn','uranus','neptune','pluto','node','lilith','chiron','asc','ic','dsc','mc','asc/mc','sun/moon'] + def __init__(self): + self.planets = {} + for p in planetPositions.planetNames: + self.planets[p] = planetRelation(p) + self.aspect = {} + + def test_random(self): + for planet in self.planets: + self.planets[planet].test_random() + + def calcAngle(self,componentA,componentB): + print componentA,componentB + self.angle = abs(self.planets[componentA].angleA - self.planets[componentB].angleB) + self.angleRange = self.angle-10,self.angle+10 + + def calcAspect(self,componentA,componentB): + self.calcAngle(componentA,componentB) + # print componentA,componentB,self.angle,self.planets[componentA].angleA,self.planets[componentB].angleB + for aspect in planetPositions.aspectDict: + if self.angleRange[0] < planetPositions.aspectDict[aspect] and self.angleRange[1] > planetPositions.aspectDict[aspect]: + # print aspect#,componentA,componentB,self.angle + aspectDiff = round(abs(self.angle - planetPositions.aspectDict[aspect]),2) + self.aspect[componentA,componentB] = (aspect,aspectDiff) + print componentA,componentB,self.angle,aspect,aspectDiff + return aspect,aspectDiff + return None,None + + def isInHouse(self,component,houseNo): + # print (self.planets[component].houseA,self.planets[component].houseB,houseNo) + if (self.planets[component].houseA == houseNo) or (self.planets[component].houseB == houseNo): + return True + return False + + def makeAllAspectTreple(self): + self.aspectTreple = {} + for p1 in planetPositions.planetNames: + for p2 in planetPositions.planetNames: + aspect = self.calcAspect(p1,p2)[0] + if aspect is not None: + self.aspectTreple[(p1,p2,aspect)] = 1 + + def calcAllAspects(self): + for p1 in planetPositions.planetNames: + for p2 in planetPositions.planetNames: + self.calcAspect(p1,p2) + + def printPositions(self): + for p in planetPositions.planetNames: + if p in planetRelation.noHouseList: + print p,self.planets[p].angleA,self.planets[p].angleB + else: + print p,self.planets[p].angleA,self.planets[p].angleB,self.planets[p].houseA,self.planets[p].houseB + + + + +