annotate V5/synastry.py @ 25:a5482a6afe9b

update timesheet for localRequests module
author DaveM
date Mon, 23 Apr 2018 12:19:21 +0100
parents d2bd074d9284
children 585edbea35b1
rev   line source
DaveM@23 1 import random
DaveM@23 2 import csv
DaveM@23 3 import re
DaveM@23 4 import requests
DaveM@23 5 import time
DaveM@23 6 from bs4 import BeautifulSoup
DaveM@23 7
DaveM@23 8 import pdb
DaveM@23 9
DaveM@23 10 class compatibility:
DaveM@23 11 def __init__(self):
DaveM@23 12 self.rules = []
DaveM@23 13 self.uniqueID = 0
DaveM@23 14 print 'Warning, need to fix [Vertex, Ascendant House, South Node, IC/MC and None Location] issues'
DaveM@23 15
DaveM@23 16 def addRule(self,planetTuple,aspectList,score):
DaveM@23 17 rule = compatibilityRule(self.uniqueID,planetTuple,aspectList,score)
DaveM@23 18 self.rules.append(rule)
DaveM@23 19 self.uniqueID += 1
DaveM@23 20
DaveM@23 21 def findRule(self,planet):
DaveM@23 22 ruleList = [r for r in self.rules if r.planet == planet]
DaveM@23 23 print ruleList
DaveM@23 24 return ruleList
DaveM@23 25
DaveM@23 26 def readFile(self,filename):
DaveM@23 27 text = []
DaveM@23 28 with open(filename) as fp:
DaveM@23 29 line = fp.readline()
DaveM@23 30 text.append(line.strip())
DaveM@23 31 while line:
DaveM@23 32 line = fp.readline()
DaveM@23 33 text.append(line.strip())
DaveM@23 34 return text
DaveM@23 35
DaveM@23 36 def parseCompatRules(self,filename):
DaveM@23 37 comList = self.readFile(filename)
DaveM@23 38 for com in comList:
DaveM@23 39 # print com
DaveM@23 40 planetTuple = None
DaveM@23 41 aspectList = None
DaveM@23 42 score = None
DaveM@23 43 c = com.split(',')
DaveM@23 44 if len(c) == 4:
DaveM@23 45 if len(c[1]) > 1:
DaveM@23 46 aspectList = []
DaveM@23 47 planetTuple = tuple((c[0].lower(),c[2].lower()))
DaveM@23 48 score = int(c[3])
DaveM@23 49 for subset in c[1].lower().split(' '):
DaveM@23 50 aspectList.append(subset)
DaveM@23 51 elif len(c[1]) == 0 :
DaveM@23 52 if 'house' not in c[2]:
DaveM@23 53 print 'some error where rule is not house'
DaveM@23 54 planetTuple = (c[0].lower(),'house')
DaveM@23 55 houseNo = re.findall('\d+', c[2])
DaveM@23 56 if len(houseNo) != 1:
DaveM@23 57 print 'multiple house numbers found - ERROR'
DaveM@23 58 aspectList = int(houseNo[0])
DaveM@23 59 score = int(c[3])
DaveM@23 60 self.addRule(planetTuple,aspectList,score)
DaveM@23 61
DaveM@23 62 def calcCompatibility(self, horiscope):
DaveM@23 63 score = 0
DaveM@23 64 for r in sorted(self.rules):
DaveM@23 65 if 'vertex' in r.planet:
DaveM@23 66 # print 'ERROR - catch Vertex issue'
DaveM@23 67 pass
DaveM@23 68 elif 'southnode' in r.planet:
DaveM@23 69 # print 'ERROR - catch South Node issue'
DaveM@23 70 pass
DaveM@23 71 elif 'ic/mc' in r.planet:
DaveM@23 72 # print 'ERROR - catch IC/MC issue'
DaveM@23 73 pass
DaveM@23 74 elif r.planet[1] == 'house' and r.planet[0] == 'asc':
DaveM@23 75 # print 'ERROR - catch Ascendant House issue'
DaveM@23 76 pass
DaveM@23 77 elif horiscope.planets[r.planet[0]].angleA is None:
DaveM@23 78 # print 'Error - None Location'
DaveM@23 79 return None
DaveM@23 80 elif r.planet[1] == 'house':
DaveM@23 81 if horiscope.isInHouse(r.planet[0],r.aspect):
DaveM@23 82 score += r.score
DaveM@23 83 print r.planet[0] +' '+ r.planet[1] +' '+ str(aspect)+' '+str(r.score)
DaveM@23 84 elif r.planet[0] == r.planet[1]:
DaveM@23 85 aspect,variance = horiscope.calcAspect(r.planet[0],r.planet[1])
DaveM@23 86 if aspect is not None:
DaveM@23 87 if aspect in r.aspect:
DaveM@23 88 score += r.score
DaveM@23 89 print r.planet[0]+' '+aspect +' '+ r.planet[1] +' '+ str(r.score)
DaveM@23 90 else:
DaveM@23 91 for order in [0,1]:
DaveM@23 92 aspect,variance = horiscope.calcAspect(r.planet[order],r.planet[not order])
DaveM@23 93 if aspect is not None:
DaveM@23 94 # print aspect
DaveM@23 95 # currentR = r
DaveM@23 96 # pdb.set_trace()
DaveM@23 97 if aspect in r.aspect:
DaveM@23 98 score += r.score
DaveM@23 99 print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' '+ str(r.score)
DaveM@23 100 else:
DaveM@23 101 print r.planet[0] +' '+ aspect +' '+ r.planet[1] +' 0'
DaveM@23 102 print score
DaveM@23 103 return score
DaveM@23 104
DaveM@23 105
DaveM@23 106
DaveM@23 107
DaveM@23 108 class compatibilityRule:
DaveM@23 109 def __init__(self,uniqueId,planetTuple,aspectList,score):
DaveM@23 110 self.id = uniqueId
DaveM@23 111 self.planet = planetTuple
DaveM@23 112 self.aspect = aspectList
DaveM@23 113 self.score = score
DaveM@23 114
DaveM@23 115
DaveM@23 116 class Person:
DaveM@23 117 url = 'https://horoscopes.astro-seek.com/calculate-love-compatibility/'
DaveM@23 118 def __init__(self,personDict):
DaveM@23 119 # self. = planetPositions()
DaveM@23 120 self.id = personDict['ID']
DaveM@23 121 self.dob = personDict['DOB']
DaveM@23 122 self.tob = personDict['TOB']
DaveM@23 123 self.cob = personDict['COB']
DaveM@23 124 self.p_dob = personDict['pDOB']
DaveM@23 125 self.p_tob = personDict['pTOB']
DaveM@23 126 self.p_cob = personDict['pCOB']
DaveM@23 127 self.horiscope = None
DaveM@23 128 self.resp = None
DaveM@23 129 self.issue = 'INCOMPLETE'
DaveM@23 130
DaveM@23 131 def identifyIssues(self):
DaveM@23 132 if self.id is None:
DaveM@23 133 self.issue = 'id'
DaveM@23 134 elif self.dob is None:
DaveM@23 135 self.issue = 'dob'
DaveM@23 136 elif self.tob is None:
DaveM@23 137 self.issue = 'tob'
DaveM@23 138 elif self.cob is None:
DaveM@23 139 self.issue = 'cob'
DaveM@23 140 elif self.p_dob is None:
DaveM@23 141 self.issue = 'p_dob'
DaveM@23 142 elif self.p_tob is None:
DaveM@23 143 self.issue = 'p_tob'
DaveM@23 144 elif self.p_cob is None:
DaveM@23 145 self.issue = 'p_cob'
DaveM@23 146 else:
DaveM@23 147 self.issue = None
DaveM@23 148 return self.issue
DaveM@23 149
DaveM@23 150 def makePayload(self):
DaveM@23 151 if type(self.cob) is str:
DaveM@23 152 cob_0 = float(self.cob.split(',')[0][1:])
DaveM@23 153 cob_1 = float(self.cob.split(',')[1])
DaveM@23 154 self.cob = (cob_0,cob_1)
DaveM@23 155 if type(self.p_cob) is str:
DaveM@23 156 pcob_0 = float(self.p_cob.split(',')[0][1:])
DaveM@23 157 pcob_1 = float(self.p_cob.split(',')[1])
DaveM@23 158 self.p_cob = (pcob_0,pcob_1)
DaveM@23 159 if type(self.dob) is str:
DaveM@23 160 self.dob = self.dob[1:-1].split(',')
DaveM@23 161 if type(self.p_dob) is str:
DaveM@23 162 self.p_dob = self.p_dob[1:-1].split(',')
DaveM@23 163 if type(self.tob) is str:
DaveM@23 164 self.tob = self.tob[1:-1].split(',')
DaveM@23 165 if type(self.p_tob) is str:
DaveM@23 166 self.p_tob = self.p_tob[1:-1].split(',')
DaveM@23 167
DaveM@23 168 self.payload = {'send_calculation':'1', #Req
DaveM@23 169 'muz_narozeni_den':self.dob[0],
DaveM@23 170 'muz_narozeni_mesic':self.dob[1],
DaveM@23 171 'muz_narozeni_rok':self.dob[2],
DaveM@23 172 'muz_narozeni_hodina':self.tob[0],
DaveM@23 173 'muz_narozeni_minuta':self.tob[1],
DaveM@23 174 'muz_narozeni_city':'',
DaveM@23 175 'muz_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',#auto
DaveM@23 176 'muz_narozeni_stat_hidden':'XX',
DaveM@23 177 'muz_narozeni_podstat_kratky_hidden':'',
DaveM@23 178 'muz_narozeni_podstat_hidden':'',
DaveM@23 179 'muz_narozeni_podstat2_kratky_hidden':'',
DaveM@23 180 'muz_narozeni_podstat3_kratky_hidden':'',
DaveM@23 181 'muz_narozeni_input_hidden':'',
DaveM@23 182 'muz_narozeni_sirka_stupne':str(abs(self.cob[0])).split('.')[0],
DaveM@23 183 'muz_narozeni_sirka_minuty':str(float('0.'+str(self.cob[0]).split('.')[1])*60).split('.')[0],
DaveM@23 184 'muz_narozeni_sirka_smer': '1' if self.cob[0]<0 else '0', #address N Dir (0':'N',1':'S)
DaveM@23 185 'muz_narozeni_delka_stupne':str(abs(self.cob[1])).split('.')[0], #address E - Main
DaveM@23 186 'muz_narozeni_delka_minuty':str(float('0.'+str(self.cob[1]).split('.')[1])*60).split('.')[0],
DaveM@23 187 'muz_narozeni_delka_smer': '1' if self.cob[1]<0 else '0', #address E Dir (0':'E',1':'W)
DaveM@23 188 'muz_narozeni_timezone_form':'auto',
DaveM@23 189 'muz_narozeni_timezone_dst_form':'auto',
DaveM@23 190 'send_calculation':'1',
DaveM@23 191 'zena_narozeni_den':self.p_dob[0],
DaveM@23 192 'zena_narozeni_mesic':self.p_dob[1],
DaveM@23 193 'zena_narozeni_rok':self.p_dob[2],
DaveM@23 194 'zena_narozeni_hodina':self.p_tob[0],
DaveM@23 195 'zena_narozeni_minuta':self.p_tob[1],
DaveM@23 196 'zena_narozeni_city':'',
DaveM@23 197 'zena_narozeni_mesto_hidden':'Manually+place%3A+%C2%B0%27N%2C+%C2%B0%27E',
DaveM@23 198 'zena_narozeni_stat_hidden':'XX',
DaveM@23 199 'zena_narozeni_podstat_kratky_hidden':'',
DaveM@23 200 'zena_narozeni_podstat_hidden':'',
DaveM@23 201 'zena_narozeni_podstat2_kratky_hidden':'',
DaveM@23 202 'zena_narozeni_podstat3_kratky_hidden':'',
DaveM@23 203 'zena_narozeni_input_hidden':'',
DaveM@23 204 'zena_narozeni_sirka_stupne':str(abs(self.p_cob[0])).split('.')[0],
DaveM@23 205 'zena_narozeni_sirka_minuty':str(float('0.'+str(self.p_cob[0]).split('.')[1])*60).split('.')[0],
DaveM@23 206 'zena_narozeni_sirka_smer': '1' if self.p_cob[0]<0 else '0',
DaveM@23 207 'zena_narozeni_delka_stupne':str(abs(self.p_cob[1])).split('.')[0],
DaveM@23 208 'zena_narozeni_delka_minuty':str(float('0.'+str(self.p_cob[1]).split('.')[1])*60).split('.')[0],
DaveM@23 209 'zena_narozeni_delka_smer': '1' if self.p_cob[1]<0 else '0',
DaveM@23 210 'zena_narozeni_timezone_form':'auto',
DaveM@23 211 'zena_narozeni_timezone_dst_form':'auto',
DaveM@23 212 'switch_interpretations':'0',
DaveM@23 213 'house_system':'placidus',
DaveM@23 214 'uhel_orbis':'#tabs_redraw'}
DaveM@23 215
DaveM@23 216 def requestURL(self):
DaveM@23 217 self.resp = requests.get(self.url, params=self.payload)
DaveM@23 218 time.sleep(5)
DaveM@23 219 return self.resp
DaveM@23 220
DaveM@23 221 def parsePage(self):
DaveM@23 222 self.horiscope = None
DaveM@23 223 if('Please use valid date.' in self.resp.content):
DaveM@23 224 self.issue = 'dob'
DaveM@23 225 return self.horiscope
DaveM@23 226 elif('Please use valid time.' in self.resp.content):
DaveM@23 227 self.issue = 'tob'
DaveM@23 228 return self.horiscope
DaveM@23 229 gotLocation = 0
DaveM@23 230 self.horiscope = planetPositions()
DaveM@23 231 soup = BeautifulSoup(self.resp.content, 'lxml')
DaveM@23 232 tcCell = soup.find_all('div', attrs={'class':'right-sedy-banner-svetlejsi'})
DaveM@23 233 for cell in tcCell:
DaveM@23 234 if "Planets in partner's house" in cell.get_text():
DaveM@23 235 gotLocation = 1
DaveM@23 236 divList = cell.find_all('div')
DaveM@23 237 for i in range(len(divList)):
DaveM@23 238 planetName = divList[i].getText().lower().strip().replace(':','').split(' ')[0]
DaveM@23 239 if planetName in planetPositions.planetNames:
DaveM@23 240 if gotLocation and not '/' in planetName:
DaveM@23 241 self.horiscope.planets[planetName].setHouse(divList[i+2].getText(),divList[i+4].getText())
DaveM@23 242 else:
DaveM@23 243 self.horiscope.planets[planetName].setLocation(divList[i+2].getText(),divList[i+1].img.attrs['alt'],0)
DaveM@23 244 self.horiscope.planets[planetName].setLocation(divList[i+4].getText(),divList[i+3].img.attrs['alt'],1)
DaveM@23 245 return self.horiscope
DaveM@23 246
DaveM@23 247
DaveM@23 248
DaveM@23 249 class planetRelation:
DaveM@23 250 noHouseList = ['asc','ic','dsc','mc','asc/mc','sun/moon']
DaveM@23 251 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}
DaveM@23 252
DaveM@23 253 def __init__(self,planetName):
DaveM@23 254 self.name = planetName
DaveM@23 255 self.angleA = None
DaveM@23 256 self.angleB = None
DaveM@23 257 if planetName not in planetRelation.noHouseList:
DaveM@23 258 self.houseA = None
DaveM@23 259 self.houseB = None
DaveM@23 260
DaveM@23 261 def setLocation(self,value,sign,isB):
DaveM@23 262 signVal = planetRelation.zodiacAngle[sign.lower()]
DaveM@23 263 signVal+= float('.'.join(value.encode('ascii','replace').split('?'))[:-1])
DaveM@23 264 # print self.name,sign.lower(),planetRelation.zodiacAngle[sign.lower()],value,signVal
DaveM@23 265 if not isB:
DaveM@23 266 self.angleA = signVal
DaveM@23 267 else:
DaveM@23 268 self.angleB = signVal
DaveM@23 269
DaveM@23 270 def setHouse(self,A,B):
DaveM@23 271 self.houseA = int(A.encode('ascii','ignore'))
DaveM@23 272 self.houseB = int(B.encode('ascii','ignore'))
DaveM@23 273
DaveM@23 274 def test_random(self):
DaveM@23 275 self.angleA = random.random()*360
DaveM@23 276 self.angleB = random.random()*360
DaveM@23 277
DaveM@23 278
DaveM@23 279 class planetPositions:
DaveM@23 280 aspectDict = {'conjunction':0,'semi-square':45,'sextile':60,'square':90,'trine':120,'opposition':180}
DaveM@24 281 aspectRange = {'conjunction':10,'semi-square':2,'sextile':4,'square':10,'trine':10,'opposition':10}
DaveM@23 282 # 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}
DaveM@23 283 # Taken from https://en.wikipedia.org/wiki/Astrological_sign, with reference from https://en.wikipedia.org/wiki/Astrological_symbols#Signs_of_the_zodiac
DaveM@23 284 planetNames = ['sun','moon','mercury','venus','mars','jupiter','saturn','uranus','neptune','pluto','node','lilith','chiron','asc','ic','dsc','mc','asc/mc','sun/moon']
DaveM@23 285 def __init__(self):
DaveM@23 286 self.planets = {}
DaveM@23 287 for p in planetPositions.planetNames:
DaveM@23 288 self.planets[p] = planetRelation(p)
DaveM@23 289 self.aspect = {}
DaveM@23 290
DaveM@23 291 def test_random(self):
DaveM@23 292 for planet in self.planets:
DaveM@23 293 self.planets[planet].test_random()
DaveM@23 294
DaveM@23 295 def calcAngle(self,componentA,componentB):
DaveM@23 296 self.angle = abs(self.planets[componentA].angleA - self.planets[componentB].angleB)
DaveM@23 297
DaveM@23 298 def calcAspect(self,componentA,componentB):
DaveM@23 299 self.calcAngle(componentA,componentB)
DaveM@23 300 for aspect in planetPositions.aspectDict:
DaveM@24 301 if self.angle-self.aspectRange[aspect] < self.aspectDict[aspect] and self.angle+self.aspectRange[aspect] > self.aspectDict[aspect]:
DaveM@23 302 aspectDiff = round(abs(self.angle - planetPositions.aspectDict[aspect]),2)
DaveM@23 303 self.aspect[componentA,componentB] = (aspect,aspectDiff)
DaveM@24 304 print componentA,self.planets[componentA].angleA,componentB,self.planets[componentB].angleB,self.angle,aspect,aspectDiff
DaveM@23 305 return aspect,aspectDiff
DaveM@23 306 return None,None
DaveM@23 307
DaveM@23 308 def isInHouse(self,component,houseNo):
DaveM@23 309 # print (self.planets[component].houseA,self.planets[component].houseB,houseNo)
DaveM@23 310 if (self.planets[component].houseA == houseNo) or (self.planets[component].houseB == houseNo):
DaveM@23 311 return True
DaveM@23 312 return False
DaveM@23 313
DaveM@23 314 def makeAllAspectTreple(self):
DaveM@23 315 self.aspectTreple = {}
DaveM@23 316 for p1 in planetPositions.planetNames:
DaveM@23 317 for p2 in planetPositions.planetNames:
DaveM@23 318 aspect = self.calcAspect(p1,p2)[0]
DaveM@23 319 if aspect is not None:
DaveM@23 320 self.aspectTreple[(p1,p2,aspect)] = 1
DaveM@23 321
DaveM@23 322 def calcAllAspects(self):
DaveM@23 323 for p1 in planetPositions.planetNames:
DaveM@23 324 for p2 in planetPositions.planetNames:
DaveM@23 325 self.calcAspect(p1,p2)
DaveM@23 326
DaveM@23 327 def printPositions(self):
DaveM@23 328 for p in planetPositions.planetNames:
DaveM@23 329 if p in planetRelation.noHouseList:
DaveM@23 330 print p,self.planets[p].angleA,self.planets[p].angleB
DaveM@23 331 else:
DaveM@23 332 print p,self.planets[p].angleA,self.planets[p].angleB,self.planets[p].houseA,self.planets[p].houseB
DaveM@23 333
DaveM@23 334
DaveM@23 335
DaveM@23 336
DaveM@23 337