#20191008 17:30
import pywikibot
from pywikibot import pagegenerators as pg

"""
Copy a selected number of claims through a chain of P155/vorige and P156/volgende items.
P5138: speelseizoen van club/team
P31  : is een
P17  : land
P641 : sport
P3450: competitie/sportseizoen van 
P2348: period -> shift to next/previous period
"""

prpPrev='P155'
prpNext='P156'
prpEdition='P393'

copyclaims=['P5138','P31','P641','P3450']
repo=pywikibot.Site('wikidata','wikidata').data_repository()
p17copyallowed=['Q1539532']
up=True
down=False

def genError(number=1,text=''):
  print(text)
  print(number/0)

def copyOneClaim(src,dest,copythis):
    if (copythis in src.claims) and (not(copythis in dest.claims)):
       newclaim=pywikibot.Claim(repo,copythis)
       newtarget=src.claims[copythis][0].getTarget()
       newclaim.setTarget(newtarget) 
       dest.addClaim(newclaim,summary=f'add {copythis} from {src.title()} in the P155/P156-chain') 
    

def copyOne(src,dest,up):
  #print('COPY!')  
  if (src==None) or (dest==None): return  
  #print(f'copy! {src.title()}->{dest.title()}')  
  for copythis in copyclaims:
     copyOneClaim(src,dest,copythis)
  if ('P31' in src.claims):
    for p31 in src.claims['P31']:
      if p31 in p17copyallowed:
        copyOneClaim(src,dest,'P17')
  if (prpEdition in src.claims) and (not(prpEdition in dest.claims)):
    editionnr=src.claims[prpEdition][0].getTarget()
    if (up): 
      editionnr=int(editionnr)+1
    else: 
      editionnr=int(editionnr)-1
    if (int(editionnr)>0):
      newclaim=pywikibot.Claim(repo,prpEdition)
      newtarget=str(editionnr)
      newclaim.setTarget(newtarget)
      genError(number=10,text=f'{src.title()}-{dest.title()}-{editionnr}-{up}')  
      dest.addClaim(newclaim,summary=f'add {copythis} from {src.title()} in the P155/P156-chain') 
    
def set_prev_next(prevOne,nextOne):
  if (prevOne==None) or (nextOne==None):
    return
  if not(prpNext in prevOne.claims):
    nxtclaim=pywikibot.Claim(repo,prpNext)
    nxtclaim.setTarget(nextOne)
    #genError(number=12,text=f'12-{prevOne.title()}-{nextOne.title()}--{nxtclaim.target}')
    prevOne.addClaim(nxtclaim,summary=f'add next from prev')
  if not(prpPrev in nextOne.claims):
    prevclaim=pywikibot.Claim(repo,prpPrev)
    prevclaim.setTarget(prevOne)
    genError(number=24,text=f'24-{prevOne.title()}-{nextOne.title()}---<<{prevclaim.target}>>')
    nextOne.addClaim(prevclaim,summary=f'add prev from next')
    
def wd_sparql_query(spq):
   generator=pg.WikidataSPARQLPageGenerator(spq,site=pywikibot.Site('wikidata','wikidata'))
   for wd in generator:
     try:
       wd.get(get_redirect=True)
       yield wd
     except:
       pass


def Up_a_Chain(wd):
  #print('up1')  
  if (wd!=None):  
   if (prpNext in wd.claims):
    next=wd.claims[prpNext][0].getTarget()
    next.get()
    return(next)
  return None

def Down_a_Chain(wd):
  #print('down1')  
  if (wd!=None):  
   if (prpPrev in wd.claims):
    next=wd.claims[prpPrev][0].getTarget()
    next.get()
    return(next)
  return None
    
def UpChain(wd):
  next=Up_a_Chain(wd)
  prev=wd
  while (next!=None):
     prev=next   
     next=Up_a_Chain(next)
     set_prev_next(prev,next)
     copyOne(prev,next,True)
     copyOne(next,prev,False)   
     yield(next)
    
def DownChain(wd): 
  next=Down_a_Chain(wd)
  prev=wd
  while (next!=None):
     prev=next   
     next=Down_a_Chain(next)
     set_prev_next(next,prev)
     copyOne(prev,next,False)
     copyOne(next,prev,True)   
     yield(next)

def testOne():
    older=pywikibot.ItemPage(repo,'Q3070180')
    newer=pywikibot.ItemPage(repo,'Q3070182')
    older.get()
    newer.get()
    copyOne(older,newer,True)
    set_prev_next(older,newer)

def oneQuery(q):
  for x in wd_sparql_query(q):
    #print(x.title()) 
    UpChain(x)
    DownChain(x)

def oneChain(start,direction):
  prev=pywikibot.ItemPage(repo,start)
  prev.get(get_redirect=True)
  if (direction==up):
    gen=UpChain
  else:
    gen=DownChain
  for nxt in gen(prev):
    #xx=prev.labels['nl']
    #yy=nxt.labels['nl']
    #print(f'{xx}->{yy}')
    copyOne(prev,nxt,direction)
    if (direction==up):
      set_prev_next(prev,nxt)
    else:
      set_prev_next(nxt,prev)  
    prev=nxt
    
    
print('Start')    
#testOne()    
#oneQuery('select ?item where {?item wdt:P155 ?volgende . ?item wdt:P393 ?editie . OPTIONAL{?volgende wdt:P393 ?next}filter (!bound(?next))  } ')
#oneQuery('select ?item ?editie ?volgendeITEM ?nextEDITIE ?volgendeVORIGEwhere {  ?item wdt:P155 ?volgendeITEM .   OPTIONAL{?item wdt:P393 ?editie} .   ?volgendeITEM wdt:P393 ?nextEDITIE.  OPTIONAL{?volgendeITEM wdt:P156 ?volgendeVORIGE}.  filter (!bound(?next))  }')
#oneChain('Q44382540',down) #
oneChain('Q70316184',down) #Slimste Mens Ter Wereld 2019
#oneChain('Q70317793') #Holland Next Top Model seizoen 12
print('Klaar')
Start
Sleeping for 7.8 seconds, 2019-10-10 09:16:39
Q62397961-Q61750467-11-True
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-5-89ca92986edb> in <module>
    160 #oneQuery('select ?item ?editie ?volgendeITEM ?nextEDITIE ?volgendeVORIGEwhere {  ?item wdt:P155 ?volgendeITEM .   OPTIONAL{?item wdt:P393 ?editie} .   ?volgendeITEM wdt:P393 ?nextEDITIE.  OPTIONAL{?volgendeITEM wdt:P156 ?volgendeVORIGE}.  filter (!bound(?next))  }')
    161 #oneChain('Q44382540',down) #
--> 162 oneChain('Q70316184',down) #Slimste Mens Ter Wereld 2019
    163 #oneChain('Q70317793') #Holland Next Top Model seizoen 12
    164 print('Klaar')

<ipython-input-5-89ca92986edb> in oneChain(start, direction)
    143   else:
    144     gen=DownChain
--> 145   for nxt in gen(prev):
    146     #xx=prev.labels['nl']
    147     #yy=nxt.labels['nl']

<ipython-input-5-89ca92986edb> in DownChain(wd)
    119      set_prev_next(next,prev)
    120      copyOne(prev,next,False)
--> 121      copyOne(next,prev,True)
    122      yield(next)
    123 

<ipython-input-5-89ca92986edb> in copyOne(src, dest, up)
     55       newtarget=str(editionnr)
     56       newclaim.setTarget(newtarget)
---> 57       genError(number=10,text=f'{src.title()}-{dest.title()}-{editionnr}-{up}')
     58       dest.addClaim(newclaim,summary=f'add {copythis} from {src.title()} in the P155/P156-chain')
     59 

<ipython-input-5-89ca92986edb> in genError(number, text)
     25 def genError(number=1,text=''):
     26   print(text)
---> 27   print(number/0)
     28 
     29 def copyOneClaim(src,dest,copythis):

ZeroDivisionError: division by zero