ویکی‌پدیا:درخواست‌های ربات/بایگانی‌کنندهٔ منابع برخط/قدیمی

برای درخواست بایگانی به اینجا مراجعه نمائید.

پیش‌نیازها

ویرایش

قبل از اجرا باید بستهٔ mechanize را از اینجا نصب کنید.

نصب mechanize بر روی تول سرور

تول‌سرور به شما اجازه نصب هیچ نرم‌افزاری را نمی‌دهد و تنها روش نصب این کتابخانه به شرح زیر است.

  1. در ابتدا mechanize را از اینجا دانلود کنید.
  2. بعد از دانلود، زیپ بسته را باز کنید و پوشه mechanize (درون پوشه mechanize-0.2.5 قرار دارد) را به کمک winscp یا نرم‌افزارهای مشابه در پوشه pywikipedia خود در تول سرور کپی کنید.
  3. کد پایین (کد بایگانی‌کنندهٔ منابع برخط) را در پوشه pywikipedia خود در تول سرور قرار دهید.
نصب mechanize در لینوکس

برای سیستم‌های لینوکس به کمک easy_install mechanize قابل نصب است.

نصب mechanize در ویندوز

نصب این کتابخانه در ویندوز به چند روش می‌توان انجام داد، که یکی از آنها به شرح زیر است. مراحل زیر را انجام دهید

  1. در ابتدا mechanize را از اینجا دانلود کنید.
  2. بعد از دانلود، زیپ بسته را باز کنید و آن را در پوشه پایتون (مثلا C:\Python27) کپی کنید.
  3. در برنامهٔ cmd ویندوز، با نوشتن دستور زیر به آدرس پوشهٔ mechanize که الان در پوشه پایتون هست بروید (مثلا C:\Python27\mechanize-0.2.5)
  4. کد پایین (کد بایگانی‌کنندهٔ منابع برخط) را در پوشه pywikipedia قرار دهید.
cd C:\Python27\mechanize-0.2.5

و دستور setup.py install را بنویسید حال این کتابخانه بر روی پایتون شما نصب هست.

پس از اجرای کد از شما نام صفحه را می‌پرسد که باید به کمک این وب‌گاه عنوان را به صورت درصدی در آورده و در مقابل page: پیست کنید.

در این کد باید به جای js.tab@gmail.com ایمیل خودتان را وارد نمائید.(این ایمیل ترجیحاً ایمیل رسمیتان نباشد چون به ازاء هر ارجاع ثبت‌شده، از سوی وب‌گاه webcitation یک ایمیل تائید برای شما فرستاده می‌شود.)

  • نکته۱:وب‌گاه www.webcitation.org محدودیت آپلود دارد. اگر آی پی‌ای در یک مدت زمان مشخص (به نظرم یک روز) بیش از ۹۰ درخواست در وب‌گاه ثبت نماید یا با سرعت زیاد در وبگاه درخواست دهد آی‌پی‌اش قطع دسترسی می‌شود. برای جلوگیری از این مورد ربات به نحوی تنظیم شده‌است که تا ۹۰ درخواست را اجرا می‌کند و ارجاع‌های موجود در مقاله را به روز می‌کند و سپس کار را متوقف می‌کند تا در روز دیگر از نو ربات را برانید تا بقیهٔ ارجاع‌ها (در صورت موجود بودن) را در سایت www.webcitation.org ثبت نماید. این مشکل اجرای چند مرحله‌ای منحصر به مقالاتی است که بیش از ۹۰ ارجاع برای ثابت سازی، داشته باشند و باید ربات با آی‌پی‌های متفاوت یا در چند روز اجرا شود.
  • نکته۲: برای رفع مشکل سرعت بالای ربات و جلوگیری از قطع دسترسی بین هر درخواست ۵ ثانیه توقف داده می‌شود که دستور توقف درون کد تعبیه شده‌است.
  • نکته۳: در صورتی که در سایت www.webcitation.org قطع دسترسی شدید به کمک نرم‌افزارهای تغیردهده آی‌پی، آی‌پی ربات را تغیر دهید.
  • نکته۴: ربات پرونده مقاله به‌روز شده را در CitedPage.txt نیز ذخیره می‌کند.
#!/usr/bin/python
# -*- coding: utf-8 -*-
#############################################
# Copyright (C) 2011    Z     (User:ZxxZxxZ)
#                    Reza1615 (User:Reza1615)
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#############################################
 
__version__ = '$Id: WebCiteBot$'
 
import wikipedia, sys
import pagegenerators,codecs
import re, os, codecs, catlib
import mechanize,time
import urllib
from datetime import timedelta,datetime
status=True
deadlink=[]
wikipedia.config.put_throttle = 0
wikipedia.put_throttle.setDelay()
class BasicBot:
 
    def archive(self, URL):
        status=True
        if URL.find('.wikipedia.')!=-1:
            deadlink.append(URL)
            status=False
            return False,status
        time.sleep(1)# sleep to have less errors
        wikipedia.output('Requesting %s on www.webcitation.org ....' %URL)
        #if status:
        try:
            br = mechanize.Browser()
            br.open('http://www.webcitation.org/archive')
            br.select_form(nr=0)
            try:
                br['url'] = URL    
                br['email'] = 'js.tab@gmail.com'
                br.submit()
            except:
                URL=URL.replace('http://','').replace('https://','').replace('HTTP://','').replace('HTTPS://','').replace('http:','').replace('https:','').strip()
                URL=urllib.quote(URL.encode('utf8'))
                br['url'] = URL
                br['email'] = 'js.tab@gmail.com'
                br.submit()
        except:
            wikipedia.output('\03{lightred}ERROR: may be the citation URL is a dead link!\03{default}')
            deadlink.append(URL)
            status=False
            return False,status
        try:
          archiveURL = re.search(", url='(.*?)'",
                                 br.find_link(url_regex = re.compile('http.*?webcitation.org/')).__repr__()
                                ).group(1)
        except:  
              wikipedia.output('\03{lightred}ERROR: may be your IP is blocked for today!\03{default}')
              status=False
              return False,status
        if archiveURL.find(u'%')!=-1 or archiveURL.find(u'=')!=-1 or archiveURL.find(u'+')!=-1:
              deadlink.append(URL)
              status=False
              return False,status
        return archiveURL,status
 
    def run(self, page):
        status=True
        oldText = self.load(page)
        todaytime=persianmonth()
        entodaytime = datetime.now().strftime("%d %B %Y")
        text = oldText
        j=0
        items=[u'|',u'}}']
        for i in [u'نشانی',u'پیوند']:        
            text=text.replace(i+u' بایگانی ='+items[j],u'').replace(i+u' بایگانی = '+items[j],u'').replace(i+u' بایگانی =  '+items[j],u'').replace(i+u' بایگانی =   '+items[j],u'')
            j+=1
        counter=0
        # for Persian citations
        citations = re.findall(ur'\{\{\s*یادکرد(?:\{\{.*?\}\}|.)*?\}\}', text, re.S)
 
        if not citations:
             wikipedia.output(u"\03{lightpurple}page %s dosen't have any Persian citation! \03{default}" % page.title())
        else:
            #-----------------------Farsi Citation Counter------------------------------------------
            citecount=0
            for citation in citations:
              if not 'webcitation.org/' in citation:
                  try:
                      re.search(ur'\|\s*پیوند بایگانی\s*=\s*.+\s*(?=\||\}\})', citation).group(0)
                  except AttributeError:
                      try:
                        URLtest = re.search(ur'\|\s*(?:پیوند|url|نشانی)\s*=\s*(.*?)\s*(?=\||\}\})', citation).group(1)
                        if URLtest.strip():
                            citecount+=1
                      except AttributeError:
                        continue
            wikipedia.output(u"\03{lightpurple}Found %s Persian citations in page %s \03{default}" % (str(citecount), page.title()))
            #----------------------------------------------------------------------------
        for citation in citations:
          if not 'webcitation.org/' in citation:
            try:
               testlink=re.search(ur'\|\s*(پیوند بایگانی|نشانی بایگانی)\s*=\s*.+\s*(?=\||\}\})', citation).group(0)
            except AttributeError:
              try:
                URL = re.search(ur'\|\s*(?:پیوند|url|نشانی)\s*=\s*(.*?)\s*(?=\||\}\})', citation).group(1)
                if not URL.strip():
                    continue
              except AttributeError:
                continue
              counter+=1
              if counter>99:    
                    wikipedia.output(u"\03{lightpurple}your requests are more than 90 pages and you exceed your limitation! try another day \03{default}")
                    break
              URL,status=self.archive(URL)
              oldcitation=citation
              citation=citation.replace(u'| ',u'|').replace(u' =',u'=').replace(u'= ',u'=').replace(u'| ',u'|').replace(u' =',u'=').replace(u'= ',u'=')
              if URL!=False:
                  citation=citation.replace(u'| ',u'|').replace(u' |',u'|').replace(u'= ',u'=').replace(u' =',u'=')
                  citation=citation.replace(u'| ',u'|').replace(u' |',u'|').replace(u'= ',u'=').replace(u' =',u'=')
                  citation=citation.replace(u'|پیوند بایگانی=',u'').replace(u'|نشانی بایگانی=',u'').replace(u'|تاریخ بایگانی=',u'')
                  if citation.find(u'|زبان=en')!=-1 or citation.find(u'|زبان=آلمانی')!=-1 or citation.find(u'|زبان=ژاپنی')!=-1 or citation.find(u'|زبان=روسی')!=-1 or citation.find(u'|زبان=انگلیسی')!=-1 or citation.find(u'|زبان=فرانسوی')!=-1 or citation.find(u'|کد زبان=en')!=-1 or citation.find(u'|زبان=fr')!=-1 or citation.find(u'|زبان=de')!=-1 or citation.find(u'|زبان=it')!=-1 or citation.find(u'|زبان=es')!=-1 or citation.find(u'|زبان=ja')!=-1 or citation.find(u'|زبان=zn')!=-1 or citation.find(u'|کد زبان=fr')!=-1 or citation.find(u'|کد زبان=de')!=-1 or citation.find(u'|کد زبان=it')!=-1 or citation.find(u'|کد زبان=es')!=-1 or citation.find(u'|کد زبان=ja')!=-1 or citation.find(u'|کد زبان=zn')!=-1:
                      citation_with_archive = citation[:-2] + u'| پیوند بایگانی = %s | تاریخ بایگانی = %s}}' %(URL ,entodaytime)
                  else:  
                      citation_with_archive = citation[:-2] + u'| پیوند بایگانی = %s | تاریخ بایگانی = %s}}' %(URL ,todaytime)
                  wikipedia.output(citation_with_archive)
                  wikipedia.output(u'\03{lightpurple}Citation number: '+str(counter)+u"\03{default}")  
                  text = text.replace(oldcitation, citation_with_archive)
              else:
                   continue
          else:
              wikipedia.output(u'\03{lightpurple}Citation is OK!\03{default}')
 
        # for English citations
        citations = []
        citations = re.findall(ur'\{\{\s*(?:[Cc]ite|[Cc]itation)(?:\{\{.*?\}\}|.)*?\}\}', text, re.S)
        if not citations:
             wikipedia.output(u"\03{lightpurple}page %s dosen't have any English citation! \03{default}" % page.title())
        else:
            #-----------------------English Citation Counter------------------------------------------
            citecount=0
            for citation in citations:
              if not 'webcitation.org/' in citation:
                  try:
                      re.search(ur'\|\s*archiveurl\s*=\s*.+\s*(?=\||\}\})', citation).group(0)
                  except AttributeError:
                      try:
                        URLtest = re.search(ur'\|\s*url\s*=\s*(.*?)\s*(?=\||\}\})', citation).group(1)
                        if URLtest.strip():
                            citecount+=1
                      except AttributeError:
                        continue
            wikipedia.output(u"\03{lightpurple}Found %s English citations in page %s \03{default}" % (str(citecount), page.title()))
            #-------------------------------------------------------------------------------------------
        for citation in citations:
            if not 'webcitation.org/' in citation:
                try:
                  testlink=re.search(ur'\|\s*archiveurl\s*=\s*.+\s*(?=\||\}\})', citation).group(0)
                except AttributeError:
                  try:
                    URL = re.search(ur'\|\s*url\s*=\s*(.*?)\s*(?=\||\}\})', citation).group(1)
                    if not URL.strip():
                        continue
                  except AttributeError:
                    continue
                  counter+=1
                  if counter>90:
                        wikipedia.output(u"\03{lightpurple}your requests are more than 90 pages and you exceed your limitation! try another day \03{default}")
                        break
                  URL,status=self.archive(URL)
 
                  if URL!=False:
                      citation=citation.replace(u'| ',u'|').replace(u' |',u'|').replace(u'= ',u'=').replace(u' =',u'=')
                      citation=citation.replace(u'| ',u'|').replace(u' |',u'|').replace(u'= ',u'=').replace(u' =',u'=')
                      citation=citation.replace(u'|archiveurl=',u'').replace(u'|archivedate= ',u'')
                      citation_with_archive = citation[:-2] + u'| archiveurl = %s | archivedate = %s}}' %(URL ,entodaytime)
                      wikipedia.output(citation_with_archive)
                      wikipedia.output(u'\03{lightpurple}Citation number: '+str(counter)+u"\03{default}")
                      text = text.replace(citation, citation_with_archive)
                  else:
                      continue
            else:
                  wikipedia.output(u'\03{lightpurple}Citation is OK!\03{default}')
        if text != oldText:
          self.save(text, page)
        return status
 
 
    def load(self, page):
        try:
            text = page.get()
            wikipedia.output(u"Openning page %s ..."
                             % page.title())
        except wikipedia.NoPage:
            wikipedia.output(u"ERROR: Page %s does not exist."
                             % page.title(asLink=True))
        except wikipedia.IsRedirectPage:
            wikipedia.output(u"ERROR: Page %s is a redirect."
                             % page.title(asLink=True))
        else:
            return text
        return None
 
    def save(self, text, page, comment=u'ربات: ساخت و افزودن [[وپ:پایدار|پیوند پایدار]] برای منابع برخط ([[وپ:درخواست ربات/بایگانی‌کنندهٔ منابع برخط|کد]])'):
      with codecs.open( u'CitedPage.txt',mode = 'w',encoding = 'utf8' ) as f:
                    f.write( text )
      try:
        page.put(text, comment=comment, minorEdit=True, botflag=True)
        wikipedia.output(u'Page %s Updated!' % page.title())
      except wikipedia.EditConflict:
        wikipedia.output(u'ERROR: Skipping %s because of edit conflict' % page.title())
      except wikipedia.LockedPage:
        wikipedia.output(u"ERROR: Page %s is locked; skipping." % page.title(asLink=True))
      except wikipedia.SpamfilterError, error:
        wikipedia.output(u'ERROR: Cannot change %s because of spam blacklist entry %s' % (page.title(), error.url))
def persianmonth():
    b = datetime.now().strftime("%d %B %Y")
    b=b.replace(u"January",u"ژانویه")
    b=b.replace(u"February",u"فوریه")
    b=b.replace(u"March",u"مارس")
    b=b.replace(u"April",u"آوریل")
    b=b.replace(u"May",u"مه")
    b=b.replace(u"June",u"ژوئن")
    b=b.replace(u"July",u"ژوئیه")
    b=b.replace(u"August",u"اوت")
    b=b.replace(u"September",u"سپتامبر")
    b=b.replace(u"October",u"اکتبر")
    b=b.replace(u"November",u"نوامبر")
    b=b.replace(u"December",u"دسامبر")
    b=b.replace(u'0',u'۰').replace(u'1',u'۱').replace(u'2',u'۲').replace(u'3',u'۳').replace(u'4',u'۴').replace(u'5',u'۵').replace(u'6',u'۶').replace(u'7',u'۷').replace(u'8',u'۸').replace(u'9',u'۹')
    return b 
def page_talk(page,status):
    if status:
        up_text=u"== بایگانی منابع برخط ==\n'''ربات:'''بایگانی همه منابع برخط انجام شد {{شد}} ~~~~"
    else:
        if deadlink:
            up_text=u"== خطا در منابع ==\n'''ربات:'''منابع زیر در روند بایگانی دچار خطا شدند ممکن است (۱- پیوند مرده باشد۲- پیوند به خود ویکی‌پدیا باشد۳-در زمان بایگانی ربات با خطای سایت مواجه شده باشد) {{نشد}}"
            up_text+='\n# '.join(deadlink)
            up_text+=u'~~~~'
    talk_page=wikipedia.Page(wikipedia.getSite('fa'), u'بحث:'+page.title())    
    talk_text=talk_page.get()
    if talk_text.find(u'بایگانی همه منابع برخط انجام شد')==-1 and status:#don't repeating a comment!
        talk_page.put(talk_text+u'\n'+up_text,u'ربات:بایگانی منابع برخط انجام شد!')
    if status==False and deadlink:
        talk_page.put(talk_text+u'\n'+up_text,u'ربات:خطا در روند بایگانی منابع برخط!')    
def main():
    bot = BasicBot()
    page=wikipedia.Page(wikipedia.getSite('fa'), wikipedia.input('Page: '))
    if page.namespace()==0:
        status=bot.run(page)
        wikipedia.output(u'Commenting on Talk page....')    
        page_talk(page,status)    
 
if __name__ == "__main__":
    try:
        main()
    finally:
        wikipedia.stopme()