chiark / gitweb /
9135befc362e277a064735879f9d2851148bb895
[familyTree.git] / familyTree / askQuestion.py
1 #!/usr/bin/python
2
3 import sqlite3
4 import findYear
5 from string import Template
6
7 global link_Template 
8 link_Template= Template(\
9         "<a href = http://www.chiark.greenend.org.uk/ucgi/~naath/$script"\
10         +" title=$title>$text</a>")
11 def add_quotes(s):
12         s = str(s)
13         return "'"+s+"'"
14
15 def run_query(s,t):
16         c = make_cursor()
17         return c.execute(s,t)
18
19 def print_row(row,newLine):
20         out = ''
21         for item in row:
22                 out = out + str(item)+'|'
23         return out[:-1] + newLine
24
25 def print_query(s,t,newLine):
26         printMe = ''
27         for row in run_query(s,t):
28                 printMe = printMe + print_row(row,newLine)              
29         return printMe
30
31 def is_number(s):
32     try:
33         float(s)
34         return 1
35     except ValueError:
36         return 0
37
38 def print_tagged_query(relationship,s,t,newLine):
39         mine = ''
40         for row in run_query(s,t):
41                 mine = mine + print_tagged_name(relationship,row,newLine)
42         return mine
43
44
45 def relationship_html(ID,ID2,newLine):
46         if newLine=='<br>':
47                 relationship = common_ancestors(ID,ID2,newLine)[2]
48                         
49                 if relationship[-11:] != 'not related':
50                         script = "ancestors.py?ID="+str(ID)+"&ID2="+str(ID2)
51                         url = link_Template.substitute\
52                                 (script = script,title = "Common ancestors"\
53                                         ,text = "Common ancestors")
54                         return relationship + ' '+url + newLine
55                 else:
56                         return relationship + newLine
57         else:
58                 return ''
59
60 def terr_html(terr,newLine,start,stop):
61         if newLine=='<br>':
62                 if start == 0 and stop ==0:
63                         myTitle = add_quotes(terr)
64
65                 else:
66                         s = "SELECT name,people.id"\
67                         +" FROM people INNER JOIN territories"\
68                         +" ON people.id = territories.id"\
69                         +" WHERE territory = ? AND stopyear <= ?"\
70                         +" ORDER BY startyear DESC;"
71
72                         t = (terr,start)
73                         myTitle = ''
74                         for row in run_query(s,t):
75                                 myTitle = myTitle +"previous - " + row[0] \
76                                 + ',' + str(row[1])
77                                 break
78
79                         u = "SELECT name,people.id"\
80                         +" FROM people INNER JOIN territories"\
81                         +" ON people.id = territories.id"\
82                         +" WHERE territory = ? AND startyear >= ?"\
83                         +" ORDER BY startyear;"
84                 
85                         v = (terr,stop)
86                         for r in run_query(u,v):
87                                 myTitle = myTitle + '&#xA' +"next - " + r[0] \
88                                 + ',' + str(r[1])
89                                 break
90
91                         myTitle = add_quotes(myTitle)
92
93                 return link_Template.substitute(\
94                         script = "territory.py?terr="+terr, title=myTitle,\
95                         text = terr)
96         else:
97                 return terr
98 def name_html(row,html):
99         if html=='<br>':
100                 html=1
101         elif html=='\n':
102                 html=0
103
104         if row[0] == None:
105                 return row[1]
106         else:
107                 if html==1:
108                         script = "person.py?ID=" + str(row[1])
109                         name = row[0]
110                         return link_Template.substitute(script = script\
111                                 ,title = add_quotes(name),text = name)
112                 else:
113                         return row[0] + "," +str(row[1])
114
115 def print_people(n):
116         if n>1:
117                 return ' people '
118         else:
119                 return ' person '
120
121 def print_age_child_count(row,newLine):
122         if newLine == '<br>':
123                 script = "age.py?age="+str(row[0])
124                 link = link_Template.substitute(script = \
125                         script, title = add_quotes(row[0]), text = row[0])
126                 out = str(row[1])+print_people(row[1])
127
128                 out = out + 'had children at age '+ link + newLine
129                 return out
130         else:
131                 return print_row(row,newLine)
132
133 def print_age_death_count(row,newLine):
134         if newLine =='<br>':
135                 script = "ageDeath.py?age="+str(row[0])
136                 link = link_Template.substitute(script = script,\
137                         title = add_quotes(row[0]),text = row[0])
138                 out = str(row[1])+print_people(row[1])
139                 out = out + "died at age " + link + newLine
140                 return out
141         else:
142                 return print_row(row,newLine)
143
144 def print_name_count(row,newLine):
145         if newLine=='<br>':
146                 script = "name.py?name=" + row[0]
147                 link = link_Template.substitute(script =\
148                         script, title = add_quotes(row[0]),text = row[0])
149                 return str(row[1]) + " people called "+link + newLine
150         else:
151                 return print_row(row,newLine)   
152
153 def print_tagged_name(relationship,row,newLine):
154         if row[0]==None:
155                 out = relationship + " not yet entered: " + row[1]
156         else:
157                 if newLine == '<br>':
158                         html = 1
159                 else:
160                         html=0
161                 if relationship =='':
162                         out = name_html(row,html) + '   '
163                 else:
164                         out = relationship + ": " + name_html(row,html)
165         return out + newLine
166
167 def month_numbers(monthN):
168         if monthN == 0:
169                 month ='unknown month'
170         elif monthN == 1:
171                 month ='January'
172         elif monthN==2:
173                 month ='February'
174         elif monthN==3:
175                 month ='March'
176         elif monthN==4:
177                 month ='April'
178         elif monthN==5:
179                 month ='May'
180         elif monthN==6:
181                 month ='June'
182         elif monthN==7:
183                 month ='July'
184         elif monthN==8:
185                 month ='August'
186         elif monthN==9:
187                 month ='September'
188         elif monthN==10:
189                 month ='October'
190         elif monthN==11:
191                 month ='November'
192         elif monthN==12:
193                 month ='December'
194         else:
195                 month = 'Incorrectly entered month ' + str(monthN)
196         return month
197
198 def ordinal_numbers(number):
199         number = int(number)
200         if number % 10==1 and number/10 % 10 !=1:
201                 out = str(number) +'st'
202         elif number % 10==2 and number/10 % 10 !=1:
203                 out = str(number) +'nd'
204         elif number % 10==3 and number/10 % 10 !=1:
205                 out = str(number) +'rd'
206         else:
207                 out = str(number) +'th'
208         return out
209
210 def list_territories(newLine):
211         s = "SELECT DISTINCT territory"\
212         +" FROM territories"\
213         +" ORDER BY territory;"
214
215         out = ''
216         for row in run_query(s,()):
217                 out =out + terr_html(row[0],newLine,0,0) +newLine
218         return out
219
220 def list_people_parents():
221         s = "SELECT name,id"\
222                 +" FROM people"\
223                 +" ORDER BY id;"
224
225         output = []
226         for row in run_query(s,()):
227
228                 ID = row[1]
229                 [parents, parentIDs,parentNames] = find_parents(ID)
230                 [spouses,spousesID,spousesNames] = find_spouses(ID)
231                 
232
233                 myName = row[0]
234                 myID = str(row[1])
235                 output.append([myName+ ','+ myID,parents,spouses])
236         return output
237
238
239 def list_people(newLine):
240         s = "SELECT name,id,bornyear"\
241         +" FROM people"\
242         +" ORDER BY bornyear;"
243
244         out = ''
245         year = 0
246         out = out + 'born in unknown year:' +newLine
247         for row in run_query(s,()):
248                 if row[2]!=0 and row[2]/100==0:
249                         out = out +newLine+ 'born in 1st century:' +newLine
250
251                 if row[2]/100!=year/100:
252                         century = row[2]/100 + 1
253                         out = out +newLine+ 'born in ' 
254
255                         out = out +ordinal_numbers(century) \
256                                 + ' century:' + newLine
257
258                 out = out + name_html(row,newLine) +newLine
259
260                 if row[2] == 0: #unknown year
261
262                         t = (row[1],) #person ID
263
264
265                         #died
266                         u = "SELECT diedyear FROM people WHERE ID = ?;"
267
268                         bornAfter = 0
269                         for r in run_query(u,t):
270                                 if r[0] !=0:
271                                         out = out + "died: "\
272                                          + str(r[0]) + newLine
273                                         bornAfter = r[0] -100
274
275                         #find children
276                         u = "Select people.bornYear from"\
277                                 +" people INNER JOIN parents"\
278                                 +" ON people.ID = parents.ID"\
279                                 +" WHERE parents.parentID = ?"\
280                                 + " ORDER BY people.bornYear;"
281                         
282                         hadChild=[]
283                         
284                         for r in run_query(u,t):
285                                 if r[0] != 0:
286                                         hadChild.append(r[0])
287                         
288                         bornBefore = 0
289                         if len(hadChild)!=0:
290                                 out = out + "had children in: "
291                                 for c in hadChild:
292                                         out = out + str(c) + ','
293                                 out = out[:-1] + newLine
294
295                                 bornBefore = hadChild[0]-12
296                                 if bornAfter==0:
297                                         bornAfter = hadChild[0]-100
298                         
299                         u = "Select styles.startYear, styles.style from"\
300                                 +" people INNER JOIN styles"\
301                                 +" ON people.ID = styles.ID"\
302                                 +" WHERE people.ID = ? and"\
303                                 +" styles.startYear <>0"\
304                                 +" ORDER BY styles.startYear;"
305
306                         for r in run_query(u,t):
307                                 out = out + r[1] + " from " + str(r[0])\
308                                 + newLine
309                                 if bornAfter ==0:
310                                         bornAfter = r[0] -100
311                                 break
312
313                         if bornAfter!=0:
314                                 if bornBefore == 0: 
315                                         out = out + "probably born "\
316                                                 +"after " + str(bornAfter)
317                                 else:
318                                         out = out + "probably born "\
319                                                 +"betwen " + str(bornAfter)\
320                                                 +" and " + str(bornBefore)
321                                 out = out + newLine
322
323                 year = row[2]
324         return out
325
326 def count_names(newLine):
327         s = "SELECT firstName, count(*)"\
328         +" FROM people"\
329         +" GROUP BY firstName"\
330         +" ORDER BY count(*) DESC;"
331
332         out = ''
333         for row in run_query(s,()):
334                 out = out + print_name_count(row,newLine)
335
336         return out
337
338
339 def search_name(name,newLine):
340         s = "SELECT name, ID"\
341         +" FROM people"\
342         +" WHERE name LIKE ?;"
343
344         out = ''
345
346         out = out + 'Names start with ' + name + ':' + newLine
347         t = (name + '%',)
348         fullIDs=[]
349         for row in run_query(s,t):
350                 out = out + name_html(row,newLine) + newLine
351                 fullIDs.append(row[1])
352         t = ('%' + name + '%',)
353         out = out+newLine + 'Names contain ' + name + ':' + newLine
354         for row in run_query(s,t):
355                 if row[1] not in fullIDs:
356                         out = out + name_html(row,newLine) + newLine
357         
358         s = "SELECT name,people.ID,style"\
359         +" FROM people INNER JOIN styles"\
360         +" ON styles.id = people.id"\
361         +" WHERE style LIKE ?;"
362         out = out +newLine+ 'Styles contain ' + name + ':' + newLine
363         for row in run_query(s,t):
364                 out = out + name_html(row,newLine)+' ' + row[2] + newLine
365
366         return out
367
368
369 def people_with_name(name,newLine):
370         s = "SELECT name, ID"\
371         +" FROM people"\
372         +" WHERE firstname LIKE ?;"
373
374         out = ''
375
376         t = (name,)
377
378         for row in run_query(s,t):
379                 out = out + name_html(row,newLine) + newLine
380
381         return out
382
383 def count_birth_month(newLine):
384         s = "SELECT bornMonth, count(*)"\
385                 +" FROM people"\
386                 +" GROUP BY bornMonth"\
387                 +" ORDER BY bornMonth;"
388
389         t = "SELECT * FROM people WHERE bornMonth = ?;"
390
391         out = ''
392         for row in run_query(s,()):
393                 month = month_numbers(row[0])
394                 out = out + month + ': ' + str(row[1]) + newLine
395
396                 if row[0]>12:
397                         u = (row[0],)
398                         out =  out +print_query(t,u,newLine)
399                 
400         return out
401
402 def count_death_month(newLine):
403         s = "SELECT diedMonth, count(*)"\
404                 +" FROM people"\
405                 +" GROUP BY diedMonth"\
406                 +" ORDER BY diedMonth;"
407
408         t = "SELECT * FROM people WHERE diedMonth = ?;"
409
410         out = ''
411         for row in run_query(s,()):
412                 month = month_numbers(row[0])
413                 out = out + month + ': ' + str(row[1]) + newLine
414
415                 if row[0]>12:
416                         u = (row[0],)
417                         out =  out +print_query(t,u,newLine)
418
419         return out
420
421 def count_age_at_child(newLine):
422
423         s = "select p1.bornYear - p2.bornYear as age, count(*)"\
424                 +" FROM"\
425                 +" parents INNER JOIN people p1"\
426                 +" ON parents.ID = p1.ID"\
427                 +" INNER JOIN people p2"\
428                 +" ON parents.parentID = p2.ID"\
429                 +" WHERE p1.bornYear <> 0 and p2.bornYear<>0"\
430                 +" GROUP BY age;"
431
432         out = ''
433         for row in run_query(s,()):
434                 out = out + print_age_child_count(row,newLine)
435
436         return out
437
438 def people_had_child_at_age(age,newLine):
439
440         s = "select p1.bornYear - p2.bornYear as age, p1.name, p1.ID"\
441                 +",p2.name,p2.ID FROM"\
442                 +" parents INNER JOIN people p1"\
443                 +" ON parents.ID = p1.ID"\
444                 +" INNER JOIN people p2"\
445                 +" ON parents.parentID = p2.ID"\
446                 +" WHERE age = ? AND p1.bornYear<>0 AND p2.bornYear<>0"
447
448         t = (int(age),)
449
450         out = ''
451         out = 'At age ' + str(age) + ' :'
452         for row in run_query(s,t):
453                 out = out + newLine
454                 out =out + name_html([row[3],row[4]],newLine) + ' had '\
455                         +name_html([row[1],row[2]],newLine)
456
457         return out
458
459 def count_age_at_death(newLine):
460         s = "select diedYear-bornYear as age,count(*)"\
461                 +" FROM people"\
462                 +" WHERE diedYear<>0 AND bornYear<>0"\
463                 +" GROUP BY age;"
464         out=''
465         for row in run_query(s,()):
466                 out = out + print_age_death_count(row,newLine)
467
468         return out
469 def people_died_at_age(age,newLine):
470         s = "SELECT diedYear-bornYear as age, name,ID"\
471                 +" FROM people"\
472                 +" WHERE age = ? AND bornYear<>0 AND diedYear<>0;"
473         t = (int(age),)
474         out =''
475         out = 'These people died at age ' +str(age) + ' :'
476         for row in run_query(s,t):
477                 out = out +newLine
478                 out = out + name_html([row[1],row[2]],newLine)
479         return out
480
481 def all_ancestors(personID,newLine):
482         #find parents
483         s = "SELECT people.Name,parents.parentID FROM"\
484                 +" parents LEFT JOIN people"\
485                 +" ON parents.parentID = people.ID"\
486                 +" WHERE parents.ID = ?"\
487                 +" AND parents.parentID <> '.';"
488
489
490         ancestors = [personID]
491         allAncestors = [personID]
492         trackLevel = [0]
493         level = 0
494
495         t = "SELECT name,id FROM people WHERE id==?"
496         id = (personID,)
497
498         out = "Ancestors of "
499         for row in run_query(t,id):
500                 out = out + name_html(row,newLine)+newLine
501
502         aDict={}
503         aDict[level] = ancestors
504         while len(ancestors)>0:
505                 level = level+1
506                 newA =[]
507                 thisout = newLine + parent_level(level,'parent') +\
508                         ':' + newLine
509                 for ancestor in ancestors:
510                         id = (ancestor,)
511                         for row in run_query(s,id):
512                                 thisout = thisout + \
513                                 name_html(row,newLine)+newLine
514                                 if row[1] not in allAncestors\
515                                 and is_number(row[1]):
516                                         newA.append(row[1])
517                                         allAncestors.append(row[1])
518                                         trackLevel.append(level)
519                                 
520                 ancestors = newA
521                 if len(ancestors)>0:
522                         aDict[level]=ancestors
523                 out  = out+thisout
524
525
526         image = "<img src = ancestorGraph.py?id="+str(personID)+">"
527         out = out+newLine + image+newLine
528         return [out, allAncestors,trackLevel,aDict]
529
530
531 def common_ancestors(IDA, IDB,newLine):
532         out = 'Common ancestors of:' + newLine
533
534         s = "SELECT name,id FROM people WHERE id==?"
535
536
537         names=[]
538         for id in (IDA,IDB):
539                 t = (id,)
540                 for row in run_query(s,t):
541                         out = out + name_html(row,newLine)+newLine
542                         names.append(row[0])
543                 if id==IDA:
544                         out = out + 'and'
545                 out = out + newLine
546
547         if len(names)!=2:
548                 related = 'No details held on one party'
549                 out = out + related
550                 return [out,[],related]
551         
552
553         a = all_ancestors(IDA,newLine)
554         b = all_ancestors(IDB,newLine)
555         
556         ancestorsB = set(b[1])
557         ancestorsA = set(a[1])
558
559         common = ancestorsA.intersection(ancestorsB)
560         common = list(common)
561
562
563         aLevels=[]
564         bLevels=[]
565         for c in common:
566                 i = a[1].index(c)
567                 aLevels.append(a[2][i])
568                 i = b[1].index(c)
569                 bLevels.append(b[2][i])
570
571         s = "SELECT Name, ID, bornyear"\
572         +" FROM people"\
573         +" WHERE ID IN ("
574         for i in range(len(common)):
575                 s = s+ "?,"
576         if len(common)>0:
577                 s = s[:-1]
578
579
580         s = s+") ORDER BY bornyear;"
581
582
583         if len(common)==0:
584                 related = names[0]+' and '+names[1]+' are not related'
585                 out = out + newLine + related
586                 return [out, common,related]
587
588
589         out = out + print_tagged_query('',s,common,newLine)
590
591         indexA=[]
592         indexB=[]
593
594         for i in range(len(common)):
595                 if aLevels[i] == min(aLevels):
596                         indexA.append(i)
597                 if bLevels[i] == min(bLevels):
598                         indexB.append(i)
599         
600
601
602         s = "SELECT name, id"\
603         +" FROM people"\
604         +" WHERE id=?"
605
606         out  = out + newLine + 'Most Recent Common Ancestors:' + newLine
607         mrca = []
608         for a in indexA:
609                 t = (common[a],)
610                 mrca.append(common[a])
611                 out = out + print_tagged_query('',s,t,newLine)
612                 if a!=indexA[-1]:
613                         out = out + 'and' + newLine
614
615         out = out + parent_level(aLevels[indexA[0]],'parent')
616         if len(indexA) >1:
617                 out = out + 's'
618
619         out = out + ' of ' + name_html([names[0],IDA],newLine)+newLine
620
621         #out = out + newLine
622         #for b in indexB:
623         #       t = (common[b],)
624         #       out = out + print_tagged_query('',s,t,newLine)
625         #       if b!=indexB[-1]:
626         #               out = out + 'and' + newLine
627
628         out = out + parent_level(bLevels[indexB[0]],'parent')
629         if len(indexB)>1:
630                 out = out + 's'
631         out = out + ' of ' + name_html([names[1],IDB],newLine)+newLine
632
633
634         al = aLevels[indexA[0]]
635         bl = bLevels[indexB[0]]
636
637         related = relationship(al,bl,names)
638         out = out+newLine + related
639
640
641         image = "<img src = jointAncestorGraph.py?id="+str(IDA)\
642                 +"&id2="+str(IDB) + "&LA=" + str(min(aLevels)) \
643                 +"&LB=" + str(min(bLevels))+">"
644
645
646
647         out = out+newLine + image+newLine
648
649         return [out,common,related]
650
651 def relationship(level1, level2,names):
652
653         if level1==0 and level2==0:
654                 return names[0] + ' is ' +names[1]
655         if level1==0:
656                 return names[0] + ' is ' + names[1] + '\'s '+ parent_level(level2,'parent')
657         if level2==0:
658                 return names[1] + ' is ' + names[0] + '\'s '+ parent_level(level1,'parent')
659
660
661         if level1>=level2:
662                 remove = level1-level2
663                 cousinNum = level2-1
664         else:
665                 remove = level2-level1
666                 cousinNum = level1-1
667
668         if cousinNum==0:
669                 uaLevel =  parent_level(remove,'uncle or aunt')
670                 if level1<= level2:
671                         return names[0] + ' is ' + names[1] + '\'s ' + uaLevel
672
673                 if level2<level1:
674                         return names[1] + ' is ' + names[0] + '\'s ' + uaLevel
675
676         c=ordinal_numbers(cousinNum)
677         if remove == 1:
678                 rem = 'once'
679         elif remove ==2:
680                 rem = 'twice'
681         else:
682                 rem = str(remove) + ' times'            
683
684         r = names[0] +' and '+names[1] +' are ' + c + ' cousins '
685         if remove !=0:
686                 r = r+ rem + ' removed'
687
688         return r
689
690 def parent_level(level,type):
691         if level == 0:
692                 if type=='parent':
693                         return 'self'
694                 else:           
695                         return 'sibling'
696         out = type
697         if level ==1:
698                 return out
699         if type =='parent':
700                 out = 'grand '+out
701         else:
702                 out = 'great '+out
703         if level ==2:
704                 return out
705         for i in range(2,level):
706                 out = 'great '+out
707         return out
708
709 def rulers_of(aTerritory,newLine):
710
711         tq = "SELECT name, people.ID, startyear,stopyear,territory"\
712                 +" FROM territories INNER JOIN people"\
713                 +" ON people.ID = territories.ID"\
714                 +" WHERE territory LIKE ?"\
715                 +" ORDER BY territory,startyear,stopyear;"
716
717
718
719         thisT  = ''
720         last = ''
721         out = ''
722         for row in run_query(tq,(aTerritory+'%',)):
723                 if row[4]!=last and last!='':
724                         out  = out + 'Rulers of '+terr_html(last,newLine,0,0) \
725                         +':'+ newLine +thisT +newLine
726                         thisT = ''
727
728                 thisT = thisT +name_html(row,newLine)
729                 thisT = thisT +' from ' + str(row[2])+' to '+str(row[3]) + newLine
730                 last = row[4]
731
732         out  = out + 'Rulers of '+terr_html(row[4],newLine,0,0) +':'+ \
733                 newLine +thisT
734
735         return out      
736
737
738 def find_parents(ID):
739         s = "SELECT name, parentID"\
740                 +" FROM parents LEFT JOIN people"\
741                 +" ON people.ID = parentID"\
742                 +" WHERE parents.ID = ?;"
743         t = (ID,)
744
745         parents = []
746         parentIDs =[]
747         parentNames=[]
748
749         for row in run_query(s,t):
750                 if row[0]!=None:
751                         p = row[0] + ',' + str(row[1])
752                         pID = row[1]
753                         pN = row[0]
754                 else:
755                         p = row[1] + ',p ' + str(ID)
756                         pID = 0
757                         pN = row[1]
758                 parents.append(p)
759                 parentIDs.append(pID)
760                 parentNames.append(pN)
761         
762         if parents[1]==parents[0]:
763                 parents[1] = parents[1] + ' 2'
764
765         return [parents,parentIDs,parentNames]
766
767 def find_spouses(ID):
768         t = (ID,)
769
770         order = [["IDb","IDa"],["IDa","IDb"]]
771
772         spouses = []
773         spousesID=[]
774         spousesNames=[]
775         for o in order:
776                 s = "SELECT name, marriages." + o[0]\
777                 +" FROM marriages LEFT JOIN people"\
778                 +" ON marriages." +o[0]+" = people.ID"\
779                 +" WHERE marriages."+o[1]+" = ?;"
780
781
782                 for row in run_query(s,t):
783                         if row[0]!=None:
784                                 s = row[0] + "," +str(row[1])
785                                 sID = row[1]
786                                 sN = row[0]
787                         elif row[1] !='':
788                                 s=row[1] + ",s " +str(ID)
789                                 sID = 0
790                                 sN = row[1]
791                         if row[1] !='':
792                                 spouses.append(s)
793                                 spousesID.append(sID)
794                                 spousesNames.append(sN)
795
796         return [spouses,spousesID,spousesNames]
797         
798
799 def find_children(ID):
800         s = "SELECT p1.name, p1.ID,p3.parentID,p4.name,p1.bornYear"\
801                 +" FROM people p1"\
802                 +" INNER JOIN parents p2"\
803                 +" ON p1.ID = p2.ID"\
804                 +" INNER JOIN parents p3"\
805                 +" ON p1.ID = p3.ID"\
806                 +" LEFT JOIN people"\
807                 +" p4 ON p3.parentID = p4.ID"\
808                 +" WHERE p2.parentID = ?"\
809                 +" AND p3.parentID<>?"\
810                 +" ORDER BY p1.bornYear;"
811
812         t = (ID,ID)
813
814         children =[]
815         childrenID=[]
816         childrenNames=[]
817         childrenBorn=[]
818         otherparents=[]
819         otherparentsID=[]
820         otherparentsNames=[]
821
822         for row in run_query(s,t):
823                 c = row[0] + ', ' + str(row[1])
824                 cID = row[1]
825                 cName = row[0]
826                 born = row[4]
827                 children.append(c)
828                 childrenID.append(cID)
829                 childrenNames.append(cName)
830                 childrenBorn.append(born)
831                 if row[3]!=None:
832                         op = row[3] + ', ' + str(row[2])
833                         opID = row[2]
834                         opN = row[3]
835                 else:
836                         op = row[2] + ',s ' + ID
837                         opID = 0
838                         opN = row[2]
839                 otherparents.append(op)
840                 otherparentsID.append(opID)
841                 otherparentsNames.append(opN)
842
843         return [children,childrenID,childrenNames\
844                 ,otherparents,otherparentsID,otherparentsNames\
845                 ,childrenBorn]
846
847 def person_info(personID,newLine):
848         t = (personID,)
849
850         mainDiv = ''    
851         #Id, Name, Dates, Style, Style-Dates
852         s = "SELECT * FROM people WHERE ID = ?"
853         for row in run_query(s,t):
854                 mainDiv = mainDiv + '<p>'
855                 mainDiv = mainDiv  + 'ID: '+str(row[0]) +newLine
856                 mainDiv = mainDiv + print_tagged_name('Name',[row[1], row[0]]\
857                         ,newLine)
858                 mainDiv = mainDiv + '</p>'
859                 name = row[1]
860                 url = row[9]
861                 picture = row[10]
862
863                 mainDiv = mainDiv + '<p>'
864                 mainDiv = mainDiv + newLine + 'Born: '+row[3] + newLine
865                 bornYear = row[4]
866                 mainDiv = mainDiv + 'Died: '+row[5]
867
868                 if row[6] != 0 and row[4] !=0:
869                         mainDiv = mainDiv + ", aged " \
870                                 +str(row[6]-row[4])
871                 mainDiv = mainDiv + '</p>'
872
873
874         s = "SELECT * FROM styles WHERE ID = ?"
875         for row in run_query(s,t):
876                 mainDiv = mainDiv + '<p>'
877                 mainDiv = mainDiv +newLine+ 'Style: '+row[1] + newLine
878
879                 mainDiv = mainDiv + 'Territories:' + newLine
880
881                 u = "SELECT * FROM territories"\
882                 +"  WHERE ID =? AND startYear =? AND stopYear=?"
883                 v=(personID,row[3],row[5])
884
885                 any = 0
886                 for r in run_query(u,v):
887                         mainDiv = mainDiv \
888                         + terr_html(r[1],newLine,r[3],r[5])\
889                         +','
890                         any = 1
891                 if any ==1:
892                         mainDiv = mainDiv[:-1] + newLine
893
894                 mainDiv = mainDiv +  'From: '+row[2] + newLine
895                 mainDiv = mainDiv +  'To: '+row[4]      
896
897                 mainDiv = mainDiv + '</p>'
898
899
900
901
902         mainDiv = mainDiv + '<p>'
903         s = "SELECT people.Name,consort "\
904                 +"FROM consorts LEFT JOIN people"\
905                 +" ON people.ID = consorts.consort"\
906                 +" WHERE consorts.ID = ?"
907         for row in run_query(s,t):
908                 mainDiv = mainDiv + print_tagged_name\
909                 ('Consort of',row,newLine)
910         mainDiv = mainDiv + '</p>'
911
912         #find parents
913
914         [parents,parentIDs,parentNames] = find_parents(personID)
915         mainDiv = mainDiv + '<p>'
916         for i in range(len(parents)):
917                 r = [parentNames[i],parentIDs[i]]
918                 mainDiv = mainDiv + print_tagged_name('Parent',r,newLine)
919         mainDiv = mainDiv + "</p>"
920
921         #find spouses
922
923         [spouses,spousesID,spousesNames] = find_spouses(personID)
924
925         mainDiv = mainDiv + '<p>'
926
927         for i in range(len(spouses)):
928                 r = [spousesNames[i],spousesID[i]]
929                 mainDiv = mainDiv + print_tagged_name('Spouse',r,newLine)
930                 mainDiv = mainDiv + \
931                 relationship_html(personID,r[1],newLine)
932
933         mainDiv  = mainDiv + '</p>'
934
935         #find children
936         [children,childrenID,childrenNames\
937                 ,otherparents,otherparentsID,otherparentsNames\
938                 ,childrenBorn] = \
939                 find_children(personID)
940
941         top = ''
942         for i in range(len(children)):
943                 cr = [childrenNames[i],childrenID[i]]
944                 thisChild = print_tagged_name('Child',cr,newLine)
945
946                 opr=[otherparentsNames[i],otherparentsID[i]]
947                 top = otherparentsNames[i]
948                 if i==0 or  top != otherparentsNames[i-1]:
949                         mainDiv = mainDiv +'</p>'
950                         mainDiv = mainDiv + '<p>'
951                         mainDiv = mainDiv + print_tagged_name\
952                         ('With',opr, newLine)
953
954
955                 #age when child born
956                 cb = childrenBorn[i]
957                 if  cb!=0 and  bornYear != 0:
958                         age = cb-bornYear
959                         thisChild = thisChild[:-4] + \
960                                 " at the age of "+str(age) + newLine
961                 mainDiv = mainDiv + thisChild
962         
963         mainDiv = mainDiv + '</p>'
964
965         output = '<div id = "main" style = " float:left">';
966         output = output + mainDiv +  "</div>"
967
968         output = output + "<div id = 'image' "\
969                 +"style = 'float:left; margin-left:20px'>"
970
971         imageDiv = ''
972         if picture!='.':
973                 imageDiv = imageDiv + "<a href=" + url+">"\
974                 +"<img src=" + picture +" alt = 'wiki link'"\
975                 +" title = 'wiki link'></a>"\
976                 + newLine
977
978         elif url!='.' and url!='. ':
979                 imageDiv = imageDiv + "<a href=" + url +">"\
980                 +name + " (wiki link)</a>"+newLine
981
982         output = output + imageDiv + "</div>"
983
984         graph =  "smallGraph.py?ID="+str(personID)
985
986         graph ="<img src ="+ graph + '>'
987
988         output = output + "<div id = 'graph' style = 'clear:both'>"
989         output = output +  graph
990         output = output + "</div>"
991
992
993
994         return output
995
996 def connect():
997         global conn
998         conn = sqlite3.connect('/home/naath/familyTreeProject/familyTree/tree.db')
999         return conn
1000
1001 def make_cursor():
1002         return conn.cursor()
1003         
1004 def close(conn):
1005         conn.close
1006
1007 #def main():
1008
1009 #       [c, conn] = connect()   
1010 #
1011 #       person_info(1,c)
1012 #       person_info(17,c)
1013 #       person_info(38,c)
1014 #       person_info(90,c)
1015 #
1016 #       close(conn)