#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <process.h>
#include <windows.h>
#include "network.h"
#include "convert.h"
#include "auth.h"
#include "struct.h"
struct problemlist
{
char *title;
char *revid;
char *comment;
char *talktitle;
char *ftitle;
char *frev;
char *lang;
struct problemlist *next;
} ;
struct editargv
{
int count;
char *title;
char *newtext;
};
struct neditargv
{
int count;
char *title;
HTTP newtext;
};
CRITICAL_SECTION cs;
CRITICAL_SECTION tcs;
const char *nsprefix[]={"","Talk:","User:","User_talk:","Wikipedia:","Wikipedia_talk:","File:","File_talk:","Mediawiki:","Mediawiki_talk:","Template:","Template_talk:","Help:","Help_talk:","Category:","Category_talk:"};
int threadnumber=0;
struct problemlist *query();
struct problemlist *localquery();
int checkcomment(char *comment,char *lang,char *frev,char *ftitle);
int converttalk(char *title,char *talk);
void show(struct problemlist *head);
int proceed(struct problemlist* p,struct problemlist **new,int depth);
int proceedchild(char *title);
int findtemp(char *title);
int smartedit(struct neditargv *p);
int update(char *title);
int showerr=0;
int safemod=1;
int main()
{
struct problemlist *head;
if(login("Antigng-bot","")) return 1;
_beginthread(tokenmanage,0,0);
InitializeCriticalSection(&cs);
InitializeCriticalSection(&tcs);
head=localquery();
show(head);
while(head) proceed(head,&head,100);
DeleteCriticalSection(&cs);
DeleteCriticalSection(&tcs);
return 0;
}
struct problemlist *query()
{
HTTP h;
struct problemlist *pre,*head,*temp;
int flag=0;
int status=0;
char url[3000]={0};
char buffer[102400]={0};
char offset[200]={0};
char title[2000]={0};
char talktitle[2000]={0};
char revid[1000]={0};
char timestamp[1000]={0};
char comment[10000]={0};
char lang[10]={0};
char frev[100]={0};
char ftitle[2000]={0};
char *ctn[]={"arvcontinue"};
char *ctnres[1];
char *tta[]={"title"};
char *ttares[1];
char *rev[]={"revid","timestamp","comment"};
char *revres[3];
int bufferpos=0;
int next=0;
int vl=0;
struct hashlist *hsh;
ctnres[0]=offset;
ttares[0]=title;
revres[0]=revid;
revres[1]=timestamp;
revres[2]=comment;
head=0;
hsh=hashini();
do
{
h=hopen();
strcpy(url,"https://zh.wikipedia.org/w/api.php?action=query&format=xml&list=allrevisions&arvprop=ids|timestamp|comment&arvdir=older&arvlimit=5000");
if(next)
{
strcat(url,"&arvcontinue=");
strcat(url,offset);
}
if(get(url,1,h))
{
hclose(h);
return NULL;
}
if(skipresponseheader(h))
{
hclose(h);
return NULL;
}
next=0;
while(!heof(h))
{
vl=xmlparsetag(h,buffer);
if(!next&&!strcmp(buffer,"continue"))
{
vl=xmlparsearg(h,1,ctn,ctnres);
next=1;
printf("continue=%s\n",offset);
continue;
}
if(vl==0&&!strcmp(buffer,"page"))
{
vl=xmlparsearg(h,1,tta,ttares);
status=1;
continue;
}
if(!strcmp(buffer,"rev"))
{
vl=xmlparsearg(h,3,rev,revres);
status=0;
if(!hashquery(hsh,title)&&checkcomment(comment,lang,frev,ftitle))
{
status=0;
hashadd(hsh,title);
temp=(struct problemlist *)calloc(sizeof(struct problemlist),1);
temp->comment=(char *)calloc(strlen(comment)+5,1);
strcpy(temp->comment,comment);
temp->revid=(char *)calloc(strlen(revid)+5,1);
strcpy(temp->revid,revid);
temp->title=(char *)calloc(strlen(title)+5,1);
strcpy(temp->title,title);
temp->frev=(char *)calloc(strlen(frev)+5,1);
strcpy(temp->frev,frev);
temp->lang=(char *)calloc(strlen(lang)+5,1);
strcpy(temp->lang,lang);
temp->ftitle=(char *)calloc(strlen(ftitle)+5,1);
strcpy(temp->ftitle,ftitle);
converttalk(title,talktitle);
temp->talktitle=(char *)calloc(strlen(talktitle)+5,1);
strcpy(temp->talktitle,talktitle);
if(!head)
{
pre=head=temp;
}
else
{
pre->next=temp;
pre=temp;
}
temp->next=0;
}
}
}
hclose(h);
if(strcmp(timestamp,"2016-04-01T00:00:00Z")<0) break;
}while(next);
hashdestroy(hsh);
return head;
}
int converttalk(char *title,char *talk)
{
int i=0;
while(title[i]!=':'&&title[i]) i++;
if(title[i]==':')
{
strncpy(talk,title,i);
talk[i]=0;
strcat(talk,"_talk");
strcat(talk,&title[i]);
return 1;
}
else
{
strcpy(talk,"Talk:");
strcat(talk,title);
return 0;
}
}
struct problemlist *localquery()
{
struct problemlist *pre=0,*temp=0,*head=0;
FILE *f;
char buffer[20000];
char daemon[100];
char revid[1000]={0};
char comment[5000]={0};
char ns[100]={0};
int number=0;
char title[1000]={0};
char lang[10];
char ftitle[1000];
char frev[100];
int i=0,j=0;
struct hashlist *hsh;
f=fopen("quarry.txt","r+");
if(f==0) return NULL;
while(!feof(f))
{
fgets(buffer,19990,f);
for(i=0;buffer[i]&&buffer[i]!='\t';i++)
{
daemon[i]=buffer[i];
}
daemon[i]=0;
i+=1;
for(j=0;buffer[i+j]&&buffer[i+j]!='\t';j++)
{
revid[j]=buffer[i+j];
}
revid[j]=0;
i=i+j+1;
j=0;
for(j=0;buffer[i+j]&&buffer[i+j]!='\t';j++)
{
comment[j]=buffer[i+j];
}
comment[j]=0;
i=i+j+1;
j=0;
for(j=0;buffer[i+j]&&buffer[i+j]!='\t';j++)
{
title[j]=buffer[i+j];
}
title[j]=0;
i=i+j+1;
j=0;
for(j=0;buffer[i+j]&&buffer[i+j]!='\n';j++)
{
ns[j]=buffer[i+j];
}
ns[j]=0;
sscanf(ns,"%d",&number);
checkcomment(comment,lang,frev,ftitle);
if(number<20)
{
temp=(struct problemlist *)calloc(sizeof(struct problemlist),1);
temp->comment=(char *)calloc(strlen(comment)+5,1);
strcpy(temp->comment,comment);
temp->revid=(char *)calloc(strlen(revid)+5,1);
strcpy(temp->revid,revid);
if(number>0)
{
temp->title=(char *)calloc(strlen(title)+20,1);
strcpy(temp->title,nsprefix[number]);
strcat(temp->title,title);
}
else
{
temp->title=(char *)calloc(strlen(title)+5,1);
strcpy(temp->title,title);
}
temp->talktitle=(char *)calloc(strlen(title)+strlen(nsprefix[number+1])+5,1);
strcpy(temp->talktitle,nsprefix[number+1]);
strcat(temp->talktitle,title);
temp->frev=(char *)calloc(strlen(frev)+5,1);
strcpy(temp->frev,frev);
temp->lang=(char *)calloc(strlen(lang)+5,1);
strcpy(temp->lang,lang);
temp->ftitle=(char *)calloc(strlen(ftitle)+5,1);
strcpy(temp->ftitle,ftitle);
temp->next=pre;
head=pre=temp;
}
}
fclose(f);
hsh=hashini();
pre=temp=head;
while(temp)
{
if(!hashquery(hsh,temp->title))
{
hashadd(hsh,temp->title);
pre=temp;
temp=temp->next;
}
else
{
pre->next=temp->next;
free(temp);
temp=pre->next;
}
}
return head;
}
int checkcomment(char *comment,char *lang,char *frev,char *ftitle)
{
char *match1=G2U("通过翻译页面“[[:");
char *match2=G2U(":Special:Redirect/revision/");
unsigned int length1=strlen(match1);
unsigned int length2=strlen(match2);
unsigned int i=0,j=0;
lang[0]=frev[0]=ftitle[0]=0;
if(strlen(comment)<length1+length2+10)
{
free(match1);
return 0;
}
for(i=0;i<length1&&comment[i];i++)
{
if(comment[i]!=match1[i]) break;
}
if(i!=length1)
{
free(match1);
return 0;
}
j=0;
while(comment[i+j]!=':'&&comment[i+j])
{
lang[j]=comment[i+j];
j++;
}
lang[j]=0;
i=i+j;
j=0;
if(comment[i]!=':')
{
free(match1);
return 0;
}
for(j=0;j<length2&&comment[i];j++)
{
if(comment[i+j]!=match2[j]) break;
}
if(j!=length2)
{
free(match1);
return 0;
}
i=i+j;
j=0;
while(comment[i+j]!='|'&&comment[i+j])
{
frev[j]=comment[i+j];
j++;
}
frev[j]=0;
i=i+j;
j=0;
if(comment[i]!='|')
{
free(match1);
return 0;
}
i++;
while(comment[i+j]!=']'&&comment[i+j])
{
ftitle[j]=comment[i+j];
j++;
}
ftitle[j]=0;
i=i+j;
j=0;
if(comment[i]!=']')
{
free(match1);
return 0;
}
return 1;
}
void show(struct problemlist *head)
{
FILE *f;
f=fopen("b.txt","w+");
while(head)
{
fprintf(f,"[[%s]] %s %s %s %s %s %s\r\n",head->title,head->talktitle,head->revid,head->comment,head->lang,head->ftitle,head->frev);
fflush(f);
head=head->next;
}
fclose(f);
}
int proceed(struct problemlist* p,struct problemlist **newh,int depth)
{
struct problemlist *head;
int count=0;
if(!p) return -1;
head=p;
for(count=0;count< depth&&head;head=head->next,count++)
{
while(!hastoken)
{
Sleep(100);
}
proceedchild(head);
}
*newh=head;
return 0;
}
int proceedchild(struct problemlist *head)
{
char newtemp[10000];
char newtemp_e[15000];
char tt[2000];
char url[3000];
char statusl[500];
char ch=0,cht=0;
char buffer[10240];
int bufferpos=0;
int i=0;
int status=0;
struct neditargv p;
HTTP h,newtext;
i=sprintf(newtemp,"Translated page|1=%s|2=%s|version=%s|insertversion=%s",head->lang,head->ftitle,head->frev,head->revid);
URLEncode(newtemp,i,newtemp_e,14900);
h=hopen();
URLEncode(head->talktitle,strlen(head->talktitle),tt,1990);
//printf("%s\n",head->talktitle);
sprintf(url,"https://zh.wikipedia.org/w/index.php?action=raw&title=%s&redirect=no",tt);
//printf("%s\n",url);
if(get(url,1,h))
{
hclose(h);
return -1;
}
hgets(statusl,490,h);
if(strstr(statusl," 50")||strstr(statusl," 30"))
{
hclose(h);
return -2;
}
skipresponseheader(h);
newtext=hopen();
hputs("&text=",strlen("&text="),newtext);
smartURLEncode('{',newtext);
smartURLEncode('{',newtext);
hputs(newtemp_e,strlen(newtemp_e),newtext);
smartURLEncode('}',newtext);
smartURLEncode('}',newtext);
smartURLEncode('\n',newtext);
while(!heof(h))
{
cht=ch;
ch=hgetc(h);
switch(status)
{
case 0:
if(ch=='{')
{
status=1;
buffer[0]='{';
bufferpos=1;
buffer[bufferpos]=0;
}
else
{
smartURLEncode(ch,newtext);
}
break;
case 1:
if(ch!='{')
{
if(bufferpos!=2)
{
hclose(h);
hclose(newtext);
return -3;
}
status=2;
}
buffer[bufferpos]=ch;
bufferpos++;
buffer[bufferpos]=0;
break;
case 2:
buffer[bufferpos]=ch;
bufferpos++;
buffer[bufferpos]=0;
if(ch=='}')
{
for(i=0;i<bufferpos;i++)
{
smartURLEncode(buffer[i],newtext);
}
bufferpos=0;
status=0;
}
else if(ch=='|')
{
if(findtemp(buffer))
{
status=3;
bufferpos=0;
}
else
{
for(i=0;i<bufferpos;i++)
{
smartURLEncode(buffer[i],newtext);
}
bufferpos=0;
status=0;
}
}
break;
case 3:
if(ch!='}'&&cht=='}')
{
status=0;
if(ch!='\n') smartURLEncode(ch,newtext);
}
break;
}
}
hclose(h);
if(status==1||status==2)
{
hclose(newtext);
return -3;
}
p.newtext=newtext;
p.title=tt;
smartedit(&p);
hclose(newtext);
return 0;
}
int findtemp(char *title)
{
char prep[5000];
int i,j;
char *match1=G2U("已翻譯的頁面"),*MATCH1=G2U("已翻译页面");
char *match2=G2U("翻譯自"),*MATCH2=G2U("翻译自");
for(i=0,j=0;title[i]&&i<4900;i++)
{
if(title[i]!=' '&&title[i]!='{'&&title[i]!='|'&&title[i]!='_')
{
prep[j]=(title[i]>='A'&&title[i]<='Z')?(title[i]+'a'-'A'):title[i];
j++;
prep[j]=0;
}
}
if(title[i]) return 0;
if(!strcmp(prep,"translatedpage")||!strcmp(prep,match1)||!strcmp(prep,match2)||!strcmp(prep,MATCH1)||!strcmp(prep,MATCH2)) return 1;
return 0;
}
int smartedit(struct neditargv *p)
{
HTTP f;
const char *invalid1="notoken",*invalid2="badtoken";
const int length1=strlen(invalid1),length2=strlen(invalid2);
char line[1050],url[10240],aft[1000];
int resultlength=0,i=0,j=0,error=0,count=0,find;
strcpy(url,"https://zh.wikipedia.org/w/api.php?action=edit&title=");
strcat(url,p->title);
strcpy(aft,"&summary=add_translate_template([[User:Antigng-bot/1]])&minor=1&bot=1&format=xml&token=");
find=strlen(aft);
do
{
f=hopen();
error=0;count++;
while(!hastoken)
{
Sleep(100);
}
EnterCriticalSection(&cs);
aft[find]=0;
strcat(aft,token);
LeaveCriticalSection(&cs);
hrewind(p->newtext);
smartpost(url,p->newtext,aft,1,f);
resultlength=0;error=0;
while(!heof(f))
{
hgets(line,1000,f);
i=0;j=0;
while(line[j])
{
if(line[j]==invalid1[0])
{
for(i=0;i<length1;i++)
{
if(line[j+i]!=invalid1[i]) break;
}
if(i==length1) {error=1;break;}
}
if(line[j]==invalid2[0])
{
for(i=0;i<length2;i++)
{
if(line[j+i]!=invalid2[i]) break;
}
if(i==length2) {error=1;break;}
}
j++;
}
}
hclose(f);
if(error)
{
EnterCriticalSection(&cs);
i=0;
while(token[i])
{
if(aft[find+i]!=token[i]) break;
i++;
}
if(token[i]==0) hastoken=0;
LeaveCriticalSection(&cs);
}
}while(error&&count<3);
return 0;
}