Completed
Push — master ( 555fae...eac1bf )
by Sepand
30s
created

list_maker()   A

Complexity

Conditions 2

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 3 Features 1
Metric Value
cc 2
c 3
b 3
f 1
dl 0
loc 52
rs 9.4929

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
def org_list_gen(name):
127
    url=url_maker_follower(name,1)
128
    raw_data=get_html(url)
129
    org_index = raw_data.find("col-9 float-left pl-2")
130
    org_data = raw_data[:org_index]
131
    index=0
132
    org_list=[]
133
    while (index != -1):
134
        index = org_data.find('alt="@', index + 6, len(org_data))
135
        length = org_data[index + 6:].find('"')
136
        org_name = org_data[index + 6:index + 6 + length]
137
        if org_name != name:
138
            org_list.append(org_name)
139
    return org_list[:-1]
140
def user_list_gen(input_string,follower_name):
141
    '''
142
    This function extract usernames from raw_html
143
    :param input_string: raw input html
144
    :param follower_name: follower_name
145
    :type input_string:str
146
    :type follower_name:str
147
    :return: user_list as list
148
    '''
149
    try:
150
        user_list = []
151
        index = 0
152
        org_index=input_string.find("col-9 float-left pl-2")
153
        repo_data=input_string[org_index:]
154
        while(index!=-1):
155
            index=repo_data.find('alt="@',index+6,len(input_string))
156
            length=repo_data[index+6:].find('"')
157
            user_name=repo_data[index+6:index+6+length]
158
            if user_name!=follower_name:
159
                user_list.append(user_name)
160
        return user_list[:-1]
161
    except Exception as ex:
162
        pass
163
def get_html(url):
164
    '''
165
    This function extract raw_html file
166
    :param url: url
167
    :type url:str
168
    :return: html data
169
    '''
170
    time.sleep(create_random_sleep())
171
    if internet()==True:
172
        new_session=requests.session()
173
        new_session.cookies.clear()
174
        raw_html=new_session.get(url)
175
        new_session.close()
176
        raw_data=raw_html.text
177
        if "Not Found" in raw_data:
178
            print("Invalid Github User")
179
            sys.exit()
180
        return raw_data
181
    else:
182 View Code Duplication
        print("Error In Internet")
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
183
        pass
184
185
186
def end_check(input_string):
187
    '''
188
    This function check end page
189
    :param input_string: raw html
190
    :type input_string:str
191
    :return: True or False
192
    '''
193
    if input_string.find("reached the end")!=-1:
194
        return True
195
    else:
196
        return False
197
def follower_list_gen(follower_name,page_number=0,counter=0):
198
    '''
199
    This function generate follower_list
200
    :param follower_name: username
201
    :type follower_name:str
202
    :return: username follower list
203
    '''
204
    try:
205
        follower_list = []
206
        while (True):
207
            page_number += 1
208
            follower_url = url_maker_follower(follower_name, page_number)
209
            follower_html = get_html(follower_url)
210
            if end_check(follower_html) == True:
211
                break
212
            temp_list = user_list_gen(follower_html,follower_name)
213
            follower_list.extend(temp_list)
214
        return follower_list
215
    except Exception as ex:
216
        if counter>3:
217
            sys.exit()
218
        error_log("Error In Page "+str(page_number)+" Follower Page")
219
        follower_list_gen(follower_name,page_number,counter+1)
220
def repo_list(username,page_number=0,counter=0):
221
    '''
222
    This function return stared_repo list
223
    :param username: username
224
    :type username:str
225
    :return: stared repo as list
226
    '''
227
    try:
228
        repo_list_temp=[]
229
        while (True):
230
            page_number += 1
231
            repo_url = url_maker_repo(username, page_number)
232
            repo_html = get_html(repo_url)
233
            temp_list = repo_extract(repo_html,username)
234
            if len(temp_list)==0:
235
                break
236
            repo_list_temp.extend(temp_list)
237
        return repo_list_temp
238
    except Exception as ex:
239
        if counter>3:
240
            sys.exit()
241
        error_log("Error In Page " + str(page_number) + " Repos Page")
242
        repo_list(username,page_number,counter+1)
243
def star_list(username,page_number=0,counter=0):
244
    '''
245
    This function return stared_repo list
246
    :param username: username
247
    :type username:str
248
    :return: stared repo as list
249
    '''
250
    try:
251
        star_list_temp=[]
252 View Code Duplication
        while (True):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
            page_number += 1
254
            star_url = url_maker_star(username, page_number)
255
            star_html = get_html(star_url)
256
            temp_list = star_extract(star_html)
257
            if len(temp_list)==0:
258
                break
259
            star_list_temp.extend(temp_list)
260
        return star_list_temp
261
    except Exception as ex:
262
        if counter>3:
263
            sys.exit()
264
        error_log("Error In Page " + str(page_number) + " Stars Page")
265
        star_list(username,page_number,counter+1)
266
267
def following_list_gen(follower_name,page_number=0,counter=0):
268
    '''
269
    This function generate following list
270
    :param follower_name: username
271
    :type follower_name:str
272
    :return: username following list
273
    '''
274
    try:
275
        following_list = []
276
        while (True):
277
            page_number+=1
278
            following_url = url_maker_following(follower_name, page_number)
279
            following_html = get_html(following_url)
280
            if end_check(following_html) == True:
281
                break
282
            temp_list = user_list_gen(following_html,follower_name)
283
            following_list.extend(temp_list)
284
        return following_list
285
    except Exception as ex:
286
        if counter>3:
287
            sys.exit()
288
        error_log("Error In Page " + str(page_number) + " Following Page")
289
        following_list_gen(follower_name,page_number,counter+1)
290
291
def error_log(msg):
292
    """
293
    Create the errorlog of the app
294
    :param msg: error message
295
    :type msg:str
296
    """
297
    if "log" not in os.listdir():
298
        os.mkdir("log")
299
    file = open(reduce(os.path.join, [os.getcwd(), "log", "error_log.txt"]), "a")
300
    file.write(str(datetime.datetime.now()) + " --> " + str(msg) + "\n")
301
    file.close()
302
303
def internet(host="8.8.8.8", port=53, timeout=3):
304
    """
305
    Check Internet Connections.
306
    :param  host: the host that check connection to
307
    :param  port: port that check connection with
308
    :param  timeout: times that check the connnection
309
    :type host:str
310
    :type port:int
311
    :type timeout:int
312
    :return bool: True if Connection is Stable
313
    >>> internet() # if there is stable internet connection
314
    True
315
    >>> internet() # if there is no stable internet connection
316
    False
317
    """
318
    try:
319
        socket.setdefaulttimeout(timeout)
320
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
321
        return True
322
    except Exception as ex:
323
        return False
324
325
def create_random_sleep(index=1,min_time=1,max_time=3):
326
    '''
327
    This function generate sleep time with random processes
328
    :param index: index to determine first page  and messages(index = 0 is for first page)
329
    :param min_time: minimum time of sleep
330
    :param max_time: maximum time of sleep
331
    :type index:int
332
    :type min_time:int
333
    :type max_time:int
334
    :return: time of sleep as integer (a number between max and min)
335
    '''
336
    if index==0:
337
        time_sleep = 5
338
        if DEBUG==True:
339
            print("Wait "+str(time_sleep)+" sec for first search . . .")
340
    else:
341
        time_sleep = randint(min_time, max_time)
342
        if DEBUG==True:
343
            print("Wait "+str(time_sleep)+" sec for next search . . .")
344
    if DEBUG==True:
345
        print_line(70,"*")
346
    return time_sleep
347
348
def print_line(number=30,char="-"):
349
    '''
350
    This function print line in screen
351
    :param number: number of items in each line
352
    :param char: each char of line
353
    :return: None
354
    '''
355
    line=""
356
    for i in range(number):
357
        line=line+char
358
    print(line)
359
360
361
def list_maker(username):
362
    '''
363
    This function create following and follower list
364
    :param username: username
365
    :type username:str
366
    :return: (list_1,list_2) as tuple
367
    '''
368
    try:
369
        print("Collecting Follower Information ...")
370
        print_line(70, "*")
371
        list_1 = follower_list_gen(username)
372
        file = open(username + "_follower.log", "w")
373
        print(str(len(list_1)) + " Followers --> " + username + "_follower.log")
374
        print_line(70, "*")
375
        file.write("\n".join(list_1))
376
        file.close()
377
        print('Collecting Following Informnation ...')
378
        print_line(70, "*")
379
        list_2 = following_list_gen(username)
380
        file = open(username + "_following.log", "w")
381
        print(str(len(list_2)) + " Following --> " + username + "_following.log")
382
        print_line(70, "*")
383
        file.write("\n".join(list_2))
384
        file.close()
385
        print('Collecting Stars Informnation ...')
386
        print_line(70, "*")
387
        stars=star_list(username)
388
        file = open(username + "_stars.log", "w")
389
        print(str(len(stars)) + " Stars --> " + username + "_stars.log")
390
        print_line(70, "*")
391
        file.write("\n".join(stars))
392
        file.close()
393
        print('Collecting Repos Informnation ...')
394
        print_line(70, "*")
395
        repos = repo_list(username)
396
        file = open(username + "_repos.log", "w")
397
        print(str(len(repos)) + " Repos --> " + username + "_repos.log")
398
        print_line(70, "*")
399
        file.write("\n".join(repos))
400
        file.close()
401
402
        print('Collecting Organizations Informnation ...')
403
        print_line(70, "*")
404
        orgs = org_list_gen(username)
405
        file = open(username + "_orgs.log", "w")
406
        print(str(len(orgs)) + " Organizations --> " + username + "_orgs.log")
407
        print_line(70, "*")
408
        file.write("\n".join(orgs))
409
        file.close()
410
        return (list_1,list_2)
411
    except Exception as ex:
412
        error_log(str(ex))
413
414
def dif(list_1,list_2,username):
415
    '''
416
    This function generate dif files
417
    :param list_1:follower list
418
    :param list_2: following list
419
    :type list_1:list
420
    :type list_2:list
421
    :return: None
422
    '''
423
    try:
424
        file = open(username + "_NotFollower.log", "w")
425
        dif_list_1 = list(set(list_2) - set(list_1))
426
        print(str(len(dif_list_1)) + " Following - Not Follower --> " + username + "_NotFollower.log")
427
        print_line(70, "*")
428
        file.write("\n".join(dif_list_1))
429
        file.close()
430
        file = open(username + "_NotFollowing.log", "w")
431
        dif_list_2 = list(set(list_1) - set(list_2))
432
        print(str(len(dif_list_2)) + " Follower - Not Following --> " + username + "_NotFollowing.log")
433
        print_line(70, "*")
434
        file.write("\n".join(dif_list_2))
435
        file.close()
436
        return [dif_list_1,dif_list_2]
437
    except Exception as ex:
438
        print(str(ex))
439
def unfollow(username,password,id_list):
440
    for user in id_list:
441
        response=requests.delete("https://api.github.com/user/following/" + user, auth=(username, password))
442
        status_code=int(response.status_code)
443
        if status_code!=204:
444
            if status_code==401:
445
                print("[Error] Authentication Error")
446
                break
447
            else:
448
                print("[Error] in " + user + " unfollow!")
449
        else:
450
            print(user+" Unfollowed")
451
        time.sleep(3)
452
def follow(username,password,id_list):
453
    for user in id_list:
454
        response = requests.put("https://api.github.com/user/following/" + user, auth=(username, password))
455
        status_code = int(response.status_code)
456
        if status_code!=204:
457
            if status_code==401:
458
                print("[Error] Authentication Error")
459
                sys.exit()
460
            else:
461
                print("[Error] in "+user+" follow!")
462
        else:
463
            print(user+" Followed")
464
        time.sleep(3)
465
466
def run():
467
    password = ""
468
    time_1 = time.perf_counter()
469
    username = input("Please Enter Your Github Username : ")
470
    (list_1, list_2) = list_maker(username)
471
    dif_lists = dif(list_1, list_2, username)
472
    time_2 = time.perf_counter()
473
    dif_time = str(time_2 - time_1)
474
    print("Data Generated In " + time_convert(dif_time) + " sec")
475
    print("Log Files Are Ready --> " + os.getcwd())
476
    input_data = input("Unfollow Non-follower?Yes[y],No[n] ")
477
    if input_data.upper() == "Y":
478
        password = input("Please Enter Password : ")
479
        print("Processing ... ")
480
        unfollow(username, password, dif_lists[0])
481
    input_data = input("Follow Non-following?Yes[y],No[n] ")
482
    if input_data.upper() == "Y":
483
        if len(password) < 1:
484
            password = input("Please Enter Password : ")
485
        print("Processing ... ")
486
        follow(username, password, dif_lists[0])
487
    gc.collect()
488
489
490
491
492
493
494
495
496
497
498
499
500