Completed
Push — master ( c08844...b9c6a9 )
by Sepand
26s
created

unfollow()   A

Complexity

Conditions 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 4
c 1
b 1
f 1
dl 0
loc 13
rs 9.2
1
import requests
2
import sys
3
import socket
4
import os
5
import datetime
6
from functools import reduce
7
import time
8
from random import randint
9
import sys
10
DEBUG=False
11
import gc
12
13
14
def zero_insert(input_string):
15
    '''
16
    This function get a string as input if input is one digit add a zero
17
    :param input_string: input digit az string
18
    :type input_string:str
19
    :return: modified output as str
20
    '''
21
    if len(input_string)==1:
22
        return "0"+input_string
23
    return input_string
24
25
def time_convert(input_string):
26
    '''
27
    This function convert input_string from uptime from sec to DD,HH,MM,SS Format
28
    :param input_string: input time string  in sec
29
    :type input_string:str
30
    :return: converted time as string
31
    '''
32
    input_sec=float(input_string)
33
    input_minute=input_sec//60
34
    input_sec=int(input_sec-input_minute*60)
35
    input_hour=input_minute//60
36
    input_minute=int(input_minute-input_hour*60)
37
    input_day=int(input_hour//24)
38
    input_hour=int(input_hour-input_day*24)
39
    return zero_insert(str(input_day))+" days, "+zero_insert(str(input_hour))+" hour, "+zero_insert(str(input_minute))+" minutes, "+zero_insert(str(input_sec))+" seconds"
40
41
def url_maker_following(Name,page_number):
42
    '''
43
    This function return github following page url
44
    :param Name: Username
45
    :param page_number: page nubmer of following page
46
    :type Name:str
47
    :type Page:int
48
    :return: github following url as string
49
    '''
50
    return "https://github.com/"+Name+"?page="+str(page_number)+"&tab=following"
51
52
def url_maker_repo(Name,page_number):
53
    '''
54
    This function return github repo page url
55
    :param Name: Username
56
    :param page_number: page nubmer of repos page
57
    :type Name:str
58
    :type Page:int
59
    :return: github repos url as string
60
    '''
61
    return "https://github.com/"+Name+"?page="+str(page_number)+"&tab=repositories"
62
def url_maker_follower(Name,page_number):
63
    '''
64
    This function return github follower page url
65
    :param Name: username
66
    :param page_number: page number of follower page
67
    :type Name:str
68
    :type page_number:int
69
    :return: github follower url as string
70
    '''
71
    return "https://github.com/" + Name + "?page=" + str(page_number) + "&tab=followers"
72
def url_maker_star(Name,page_number):
73
    '''
74
    This function return github stars page url
75
    :param Name: username
76
    :param page_number: page number of stars
77
    :type Name :str
78
    :type page_number:int
79
    :return: github star url as string
80
    '''
81 View Code Duplication
    return "https://github.com/"+Name+"?page="+str(page_number)+"&tab=stars"
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
82
def repo_extract(input_string,username):
83
    '''
84
    This function extract repo from raw_html
85
    :param input_string: raw input html
86
    :param user_name: user_name
87
    :type input_string:str
88
    :type user_name:str
89
    :return: repo_list as list
90
    '''
91
    try:
92
        user_list=[]
93
        index=0
94
        shift=len(username)+1
95
        while(index!=-1):
96
            index=input_string.find('src="/'+username,index+shift,len(input_string))
97
            length=input_string[index:].find('graphs/')
98
            star_repo=input_string[index+5:index+length]
99
            if star_repo.find("<svg")==-1 and len(star_repo)!=0:
100
                user_list.append(star_repo)
101
        return user_list
102
    except Exception as ex:
103
        pass
104 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
105
def star_extract(input_string):
106
    '''
107
    This function extract stared repo from raw_html
108
    :param input_string: raw input html
109
    :param follower_name: follower_name
110
    :type input_string:str
111
    :type follower_name:str
112
    :return: user_list as list
113
    '''
114
    user_list=[]
115
    index=0
116
    try:
117
        while(index!=-1):
118
            index=input_string.find('<a class="muted-link mr-3',index+33,len(input_string))
119
            length=input_string[index+33:].find('stargazers">\n')
120
            star_repo=input_string[index+34:index+33+length]
121
            if star_repo.find("<svg")==-1 and len(star_repo)!=0:
122
                user_list.append(star_repo)
123
        return user_list
124
    except Exception as ex:
125
        pass
126 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
127
def user_list_gen(input_string,follower_name):
128
    '''
129
    This function extract usernames from raw_html
130
    :param input_string: raw input html
131
    :param follower_name: follower_name
132
    :type input_string:str
133
    :type follower_name:str
134
    :return: user_list as list
135
    '''
136
    try:
137
        user_list = []
138
        index = 0
139
        while(index!=-1):
140
            index=input_string.find('alt="@',index+6,len(input_string))
141
            length=input_string[index+6:].find('"')
142
            user_name=input_string[index+6:index+6+length]
143
            if user_name!=follower_name:
144
                if user_name!=follower_name:
145
                    user_list.append(user_name)
146
        return user_list[:-1]
147
    except Exception as ex:
148
        pass
149
def get_html(url):
150
    '''
151
    This function extract raw_html file
152
    :param url: url
153
    :type url:str
154
    :return: html data
155
    '''
156
    time.sleep(create_random_sleep())
157
    if internet()==True:
158
        new_session=requests.session()
159
        new_session.cookies.clear()
160
        raw_html=new_session.get(url)
161
        new_session.close()
162
        raw_data=raw_html.text
163
        if "Not Found" in raw_data:
164
            print("Invalid Github User")
165
            sys.exit()
166
        return raw_data
167
    else:
168
        print("Error In Internet")
169
        pass
170
171
172
def end_check(input_string):
173
    '''
174
    This function check end page
175
    :param input_string: raw html
176
    :type input_string:str
177
    :return: True or False
178
    '''
179
    if input_string.find("reached the end")!=-1:
180
        return True
181
    else:
182 View Code Duplication
        return False
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
183
def follower_list_gen(follower_name,page_number=0,counter=0):
184
    '''
185
    This function generate follower_list
186
    :param follower_name: username
187
    :type follower_name:str
188
    :return: username follower list
189
    '''
190
    try:
191
        follower_list = []
192
        while (True):
193
            page_number += 1
194
            follower_url = url_maker_follower(follower_name, page_number)
195
            follower_html = get_html(follower_url)
196
            if end_check(follower_html) == True:
197
                break
198
            temp_list = user_list_gen(follower_html,follower_name)
199
            follower_list.extend(temp_list)
200
        return follower_list
201
    except Exception as ex:
202
        if counter>3:
203
            sys.exit()
204
        error_log("Error In Page "+str(page_number)+" Follower Page")
205
        follower_list_gen(follower_name,page_number,counter+1)
206
def repo_list(username,page_number=0,counter=0):
207
    '''
208
    This function return stared_repo list
209
    :param username: username
210
    :type username:str
211
    :return: stared repo as list
212
    '''
213
    try:
214
        repo_list_temp=[]
215
        while (True):
216
            page_number += 1
217
            repo_url = url_maker_repo(username, page_number)
218
            repo_html = get_html(repo_url)
219
            temp_list = repo_extract(repo_html,username)
220
            if len(temp_list)==0:
221
                break
222
            repo_list_temp.extend(temp_list)
223
        return repo_list_temp
224
    except Exception as ex:
225
        if counter>3:
226
            sys.exit()
227
        error_log("Error In Page " + str(page_number) + " Repos Page")
228
        repo_list(username,page_number,counter+1)
229
def star_list(username,page_number=0,counter=0):
230
    '''
231
    This function return stared_repo list
232
    :param username: username
233
    :type username:str
234
    :return: stared repo as list
235
    '''
236
    try:
237
        star_list_temp=[]
238
        while (True):
239
            page_number += 1
240
            star_url = url_maker_star(username, page_number)
241
            star_html = get_html(star_url)
242
            temp_list = star_extract(star_html)
243
            if len(temp_list)==0:
244
                break
245
            star_list_temp.extend(temp_list)
246
        return star_list_temp
247
    except Exception as ex:
248
        if counter>3:
249
            sys.exit()
250
        error_log("Error In Page " + str(page_number) + " Stars Page")
251
        star_list(username,page_number,counter+1)
252 View Code Duplication
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
def following_list_gen(follower_name,page_number=0,counter=0):
254
    '''
255
    This function generate following list
256
    :param follower_name: username
257
    :type follower_name:str
258
    :return: username following list
259
    '''
260
    try:
261
        following_list = []
262
        while (True):
263
            page_number+=1
264
            following_url = url_maker_following(follower_name, page_number)
265
            following_html = get_html(following_url)
266
            if end_check(following_html) == True:
267
                break
268
            temp_list = user_list_gen(following_html,follower_name)
269
            following_list.extend(temp_list)
270
        return following_list
271
    except Exception as ex:
272
        if counter>3:
273
            sys.exit()
274
        error_log("Error In Page " + str(page_number) + " Following Page")
275
        following_list_gen(follower_name,page_number,counter+1)
276
277
def error_log(msg):
278
    """
279
    Create the errorlog of the app
280
    :param msg: error message
281
    :type msg:str
282
    """
283
    if "log" not in os.listdir():
284
        os.mkdir("log")
285
    file = open(reduce(os.path.join, [os.getcwd(), "log", "error_log.txt"]), "a")
286
    file.write(str(datetime.datetime.now()) + " --> " + str(msg) + "\n")
287
    file.close()
288
289
def internet(host="8.8.8.8", port=53, timeout=3):
290
    """
291
    Check Internet Connections.
292
    :param  host: the host that check connection to
293
    :param  port: port that check connection with
294
    :param  timeout: times that check the connnection
295
    :type host:str
296
    :type port:int
297
    :type timeout:int
298
    :return bool: True if Connection is Stable
299
    >>> internet() # if there is stable internet connection
300
    True
301
    >>> internet() # if there is no stable internet connection
302
    False
303
    """
304
    try:
305
        socket.setdefaulttimeout(timeout)
306
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
307
        return True
308
    except Exception as ex:
309
        return False
310
311
def create_random_sleep(index=1,min_time=1,max_time=3):
312
    '''
313
    This function generate sleep time with random processes
314
    :param index: index to determine first page  and messages(index = 0 is for first page)
315
    :param min_time: minimum time of sleep
316
    :param max_time: maximum time of sleep
317
    :type index:int
318
    :type min_time:int
319
    :type max_time:int
320
    :return: time of sleep as integer (a number between max and min)
321
    '''
322
    if index==0:
323
        time_sleep = 5
324
        if DEBUG==True:
325
            print("Wait "+str(time_sleep)+" sec for first search . . .")
326
    else:
327
        time_sleep = randint(min_time, max_time)
328
        if DEBUG==True:
329
            print("Wait "+str(time_sleep)+" sec for next search . . .")
330
    if DEBUG==True:
331
        print_line(70,"*")
332
    return time_sleep
333
334
def print_line(number=30,char="-"):
335
    '''
336
    This function print line in screen
337
    :param number: number of items in each line
338
    :param char: each char of line
339
    :return: None
340
    '''
341
    line=""
342
    for i in range(number):
343
        line=line+char
344
    print(line)
345
346
347
def list_maker(username):
348
    '''
349
    This function create following and follower list
350
    :param username: username
351
    :type username:str
352
    :return: (list_1,list_2) as tuple
353
    '''
354
    try:
355
        print("Collecting Follower Information ...")
356
        print_line(70, "*")
357
        list_1 = follower_list_gen(username)
358
        file = open(username + "_follower.log", "w")
359
        print(str(len(list_1)) + " Followers --> " + username + "_follower.log")
360
        print_line(70, "*")
361
        file.write("\n".join(list_1))
362
        file.close()
363
        print('Collecting Following Informnation ...')
364
        print_line(70, "*")
365
        list_2 = following_list_gen(username)
366
        file = open(username + "_following.log", "w")
367
        print(str(len(list_2)) + " Following --> " + username + "_following.log")
368
        print_line(70, "*")
369
        file.write("\n".join(list_2))
370
        file.close()
371
        print('Collecting Stars Informnation ...')
372
        print_line(70, "*")
373
        stars=star_list(username)
374
        file = open(username + "_stars.log", "w")
375
        print(str(len(stars)) + " Stars --> " + username + "_stars.log")
376
        print_line(70, "*")
377
        file.write("\n".join(stars))
378
        file.close()
379
380
        print('Collecting Repos Informnation ...')
381
        print_line(70, "*")
382
        repos = repo_list(username)
383
        file = open(username + "_repos.log", "w")
384
        print(str(len(repos)) + " Repos --> " + username + "_repos.log")
385
        print_line(70, "*")
386
        file.write("\n".join(repos))
387
        file.close()
388
        return (list_1,list_2)
389
    except Exception as ex:
390
        error_log(str(ex))
391
392
def dif(list_1,list_2,username):
393
    '''
394
    This function generate dif files
395
    :param list_1:follower list
396
    :param list_2: following list
397
    :type list_1:list
398
    :type list_2:list
399
    :return: None
400
    '''
401
    try:
402
        file = open(username + "_NotFollower.log", "w")
403
        dif_list_1 = list(set(list_2) - set(list_1))
404
        print(str(len(dif_list_1)) + " Following - Not Follower --> " + username + "_NotFollower.log")
405
        print_line(70, "*")
406
        file.write("\n".join(dif_list_1))
407
        file.close()
408
        file = open(username + "_NotFollowing.log", "w")
409
        dif_list_2 = list(set(list_1) - set(list_2))
410
        print(str(len(dif_list_2)) + " Follower - Not Following --> " + username + "_NotFollowing.log")
411
        print_line(70, "*")
412
        file.write("\n".join(dif_list_2))
413
        file.close()
414
        return [dif_list_1,dif_list_2]
415
    except Exception as ex:
416
        print(str(ex))
417
def unfollow(username,password,id_list):
418
    for user in id_list:
419
        response=requests.delete("https://api.github.com/user/following/" + user, auth=(username, password))
420
        status_code=int(response.status_code)
421
        if status_code!=204:
422
            if status_code==401:
423
                print("[Error] Authentication Error")
424
                break
425
            else:
426
                print("[Error] in " + user + " unfollow!")
427
        else:
428
            print(user+" Unfollowed")
429
        time.sleep(3)
430
def follow(username,password,id_list):
431
    for user in id_list:
432
        response = requests.put("https://api.github.com/user/following/" + user, auth=(username, password))
433
        status_code = int(response.status_code)
434
        if status_code!=204:
435
            if status_code==401:
436
                print("[Error] Authentication Error")
437
                sys.exit()
438
            else:
439
                print("[Error] in "+user+" follow!")
440
        else:
441
            print(user+" Followed")
442
        time.sleep(3)
443
444 View Code Duplication
if __name__=="__main__":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
445
    try:
446
        password=""
447
        time_1=time.perf_counter()
448
        username=input("Please Enter Your Github Username : ")
449
        (list_1,list_2)=list_maker(username)
450
        dif_lists=dif(list_1,list_2,username)
451
        print(dif_lists)
452
        time_2=time.perf_counter()
453
        dif_time=str(time_2-time_1)
454
        print("Data Generated In "+time_convert(dif_time)+" sec")
455
        print("Log Files Are Ready --> " + os.getcwd())
456
        input_data=input("Unfollow Non-follower?Yes[y],No[n] ")
457
        if input_data.upper()=="Y":
458
            password=input("Please Enter Password : ")
459
            print("Processing ... ")
460
            unfollow(username,password,dif_lists[0])
461
        input_data = input("Follow Non-following?Yes[y],No[n] ")
462
        if input_data.upper()=="Y":
463
            if len(password)<1:
464
                password=input("Please Enter Password : ")
465
            print("Processing ... ")
466
            follow(username,password,dif_lists[1])
467
        gc.collect()
468
    except Exception as ex:
469
        error_log(str(ex))
470
471
472
473
474
475
476
477
478
479
480
481
482