Mercurial > hg > horiscopes
view V5/synastry.py @ 31:926b008ccb0c tip
resolving vertex and fixing description results - I believe everything works
author | DaveM |
---|---|
date | Sat, 19 May 2018 14:50:41 +0100 |
parents | 52ea10196da3 |
children |
line wrap: on
line source
import sys sys.path.insert(0,'/Volumes/Internal/Documents/localRequest') import random import csv import re import localRequests as lr import time from bs4 import BeautifulSoup import pdb DEFAULT_SOURCE = 'local' # DEFAULT_SOURCE = None class compatibility: def __init__(self): self.rules = [] self.uniqueID = 0 print 'Warning, need to fix [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 rule in sorted(self.rules): if rule.planet[1] == 'house' and rule.planet[0] == 'asc': angle = horiscope.calcAngle('asc','asc') if (angle > 210 and angle < 240) or (angle > 120 and angle < 150): score += rule.score elif horiscope.planets[rule.planet[0]].angleA is None: pdb.set_trace() print 'Error - None Location' return None elif rule.planet[1] == 'house': if horiscope.isInHouse(rule.planet[0],rule.aspect): score += rule.score elif rule.planet[0] == rule.planet[1]: aspect,variance = horiscope.calcAspect(rule.planet[0],rule.planet[1]) if aspect is not None: if aspect in rule.aspect: score += rule.score else: for order in [0,1]: aspect,variance = horiscope.calcAspect(rule.planet[order],rule.planet[not order]) if aspect is not None: if aspect in rule.aspect: score += rule.score return score def describeCompatibility(self, horiscope): score = 0 outString = [] for rule in sorted(self.rules): if rule.planet[1] == 'house' and rule.planet[0] == 'asc': angle = horiscope.calcAngle('asc','asc') if (angle > 210 and angle < 240) or (angle > 120 and angle < 150): score += rule.score outString += rule.planet[0] +' '+ rule.planet[1] +' '+ str(aspect)+' '+str(rule.score) + '\n' # aspect,variance = horiscope.calcAspect(rule.planet[order],rule.planet[not order]) elif horiscope.planets[rule.planet[0]].angleA is None: pdb.set_trace() # print 'Error - None Location' return None elif rule.planet[1] == 'house': if horiscope.isInHouse(rule.planet[0],rule.aspect): score += rule.score outString += rule.planet[0] +' '+ rule.planet[1] +' '+ str(aspect)+' '+str(rule.score)+ '\n' elif rule.planet[0] == rule.planet[1]: aspect,variance = horiscope.calcAspect(rule.planet[0],rule.planet[1]) if aspect is not None: if aspect in rule.aspect: score += rule.score outString += rule.planet[0]+' '+aspect +' '+ rule.planet[1] +' '+ str(rule.score) +'\n' else: for order in [0,1]: aspect,variance = horiscope.calcAspect(rule.planet[order],rule.planet[not order]) if aspect is not None: if aspect in rule.aspect: score += rule.score outString += rule.planet[0] +' '+ aspect +' '+ rule.planet[1] +' '+ str(rule.score)+'\n' else: outString += rule.planet[0] +' '+ aspect +' '+ rule.planet[1] +' 0'+'\n' return score,outString 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.vertex = 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) self.resp = lr.get(self.url, params=self.payload, timeout=5, source=DEFAULT_SOURCE, verbose=True) # time.sleep(5) return self.resp def parsePage(self): self.horiscope = None # pdb.set_trace() if self.resp is None: pdb.set_trace() 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) if planetName == 'node': self.horiscope.planets['southnode'].angleA = self.horiscope.planets['node'].angleA+180 self.horiscope.planets['southnode'].angleB = self.horiscope.planets['node'].angleB+180 vertex = requestVertex(None, self.payload) self.horiscope.planets['vertex'].setLocation(vertex[0][0],vertex[0][1],0) self.horiscope.planets['vertex'].setLocation(vertex[1][0],vertex[1][1],1) return self.horiscope def parseVertex(content): soup = BeautifulSoup(content, 'lxml') tcCell = soup.find('div', attrs={'class':'detail-rozbor-obalka'}) tableList = tcCell.find_all('table')[0] row = tableList.find_all('tr')[1] box = row.find_all('td')[2] num = box.getText() zone = box.img.attrs['alt'] return num,zone def slicedict(d, s): return {k.replace(s,''):v for k,v in d.iteritems() if k.startswith(s)} def setVertexPayload(payload,isPartner): if isPartner: head = 'zena_' else: head = 'muz_' vPayload = slicedict(payload, head) vPayload['send_calculation'] = 1 # pdb.set_trace() return vPayload def requestVertex(url,payload): resp = dict() vertex = dict() if url == None: url = 'https://horoscopes.astro-seek.com/calculate-vertex-sign/' for i in [0,1]: # 0 is individual, 1 is partner vPayload = setVertexPayload(payload,i) resp[i] = lr.get(url, params=vPayload, timeout=5, source=DEFAULT_SOURCE, verbose=True) # pdb.set_trace() vertex[i] = parseVertex(resp[i]['content']) # pdb.set_trace() return vertex class planetRelation: noHouseList = ['asc','ic','dsc','mc','asc/mc','sun/moon','sNode'] 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} aspectRange = {'conjunction':10,'semi-square':2,'sextile':4,'square':10,'trine':10,'opposition':10} reduceAspectPlanets = {'sun':10,'moon':10,'mercury':10,'venus':10,'mars':10,'jupiter':10,'saturn':10,'uranus':10,'neptune':10,'pluto':10,'node':10,'southnode':10,'lilith':10,'chiron':10,'asc':10,'ic':10,'dsc':10,'mc':10,'asc/mc':2,'sun/moon':2,'vertex':2} # 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','southnode','lilith','chiron','asc','ic','dsc','mc','asc/mc','sun/moon','vertex'] 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): self.angle = abs(self.planets[componentA].angleA - self.planets[componentB].angleB) def calcAspect(self,componentA,componentB): self.calcAngle(componentA,componentB) for aspect in planetPositions.aspectDict: compareRange = min(self.aspectDict[aspect], self.reduceAspectPlanets[componentA]) if self.angle-self.aspectRange[aspect] < compareRange and self.angle+self.aspectRange[aspect] > compareRange: aspectDiff = round(abs(self.angle - planetPositions.aspectDict[aspect]),2) self.aspect[componentA,componentB] = (aspect,aspectDiff) # print componentA,self.planets[componentA].angleA,componentB,self.planets[componentB].angleB,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