Projects STRLCPY Osintgram Commits ac77be0a
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • InstagramAPI.py
    Unable to diff as some line is too long.
  • ■ ■ ■ ■ ■ ■
    Osintgram.py
    1  -from InstagramAPI import InstagramAPI
    2  -from geopy.geocoders import Nominatim
    3  -import sys
    4  -import argparse
    5 1  import datetime
    6  -from collections import OrderedDict
    7 2  import json
    8  -from prettytable import PrettyTable
     3 +import sys
    9 4  import urllib
    10  -from requests.exceptions import HTTPError
    11  -import printcolors as pc
    12 5   
     6 +from geopy.geocoders import Nominatim
     7 +from prettytable import PrettyTable
     8 + 
     9 +import printcolors as pc
     10 +from InstagramAPI import InstagramAPI
    13 11   
    14 12   
    15 13  class Osintgram:
    skipped 13 lines
    29 27   self.api.login()
    30 28   self.setTarget(target)
    31 29   
    32  - 
    33 30   def setTarget(self, target):
    34 31   self.target = target
    35 32   user = self.getUser(target)
    36 33   self.target_id = user['id']
    37 34   self.is_private = user['is_private']
    38 35   self.__printTargetBanner__()
    39  - 
    40 36   
    41 37   def __getUsername__(self):
    42 38   u = open("config/username.conf", "r").read()
    skipped 10 lines
    53 49   photos = []
    54 50   a = None
    55 51   while True:
    56  - if (a == None):
     52 + if a is None:
    57 53   self.api.getUserFeed(id)
    58 54   a = self.api.LastJson['items']
    59 55   only_id = self.api.LastJson
    skipped 7 lines
    67 63   if not 'next_max_id' in only_id:
    68 64   break
    69 65   
    70  -
    71 66   locations = {}
    72 67   
    73 68   for i in photos:
    skipped 5 lines
    79 74   locations[str(lat) + ', ' + str(lng)] = j.get('taken_at')
    80 75   
    81 76   address = {}
    82  - for k,v in locations.items():
     77 + for k, v in locations.items():
    83 78   details = self.geolocator.reverse(k)
    84 79   unix_timestamp = datetime.datetime.fromtimestamp(v)
    85 80   address[details.address] = unix_timestamp.strftime('%Y-%m-%d %H:%M:%S')
    86  - 
    87 81   
    88 82   sort_addresses = sorted(address.items(), key=lambda p: p[1], reverse=True)
    89 83   
    skipped 8 lines
    98 92   pc.printout(" (private: " + str(self.is_private) + ")")
    99 93   print('\n')
    100 94   
    101  - def setWriteFile(self, bool):
    102  - if(bool):
     95 + def setWriteFile(self, flag):
     96 + if flag:
    103 97   pc.printout("Write to file: ")
    104 98   pc.printout("enabled", pc.GREEN)
    105 99   pc.printout("\n")
    skipped 2 lines
    108 102   pc.printout("disabled", pc.RED)
    109 103   pc.printout("\n")
    110 104   
    111  - self.writeFile = bool
     105 + self.writeFile = flag
    112 106   
    113  - 
    114  - def __getUserFollowigs__(self, id):
     107 + def __getUserFollowigs__(self, user_id):
    115 108   following = []
    116 109   next_max_id = True
    117 110   while next_max_id:
    118 111   # first iteration hack
    119 112   if next_max_id is True:
    120 113   next_max_id = ''
    121  - _ = self.api.getUserFollowings(id, maxid=next_max_id)
     114 + _ = self.api.getUserFollowings(user_id, maxid=next_max_id)
    122 115   following.extend(self.api.LastJson.get('users', []))
    123 116   next_max_id = self.api.LastJson.get('next_max_id', '')
    124 117   
    skipped 19 lines
    144 137   
    145 138   return followers
    146 139   
    147  -
    148 140   def getHashtags(self):
    149  - if(self.is_private):
     141 + if self.is_private:
    150 142   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    151 143   return
    152 144   
    skipped 5 lines
    158 150   hashtags = []
    159 151   counter = 1
    160 152   while True:
    161  - if (a == None):
     153 + if a is None:
    162 154   self.api.getUserFeed(self.target_id)
    163 155   a = self.api.LastJson['items']
    164 156   only_id = self.api.LastJson
    skipped 9 lines
    174 166   for i in a:
    175 167   c = i.get('caption', {}).get('text')
    176 168   text.append(c)
    177  - counter = counter +1
     169 + counter = counter + 1
    178 170   except AttributeError:
    179 171   pass
    180 172   
    skipped 15 lines
    196 188   
    197 189   sortE = sorted(hashtag_counter.items(), key=lambda value: value[1], reverse=True)
    198 190   
    199  - if(self.writeFile):
     191 + if self.writeFile:
    200 192   file_name = "output/" + self.target + "_hashtags.txt"
    201 193   file = open(file_name, "w")
    202  - for k,v in sortE:
    203  - file.write(str(v) + ". " + str(k.decode('utf-8'))+"\n")
     194 + for k, v in sortE:
     195 + file.write(str(v) + ". " + str(k.decode('utf-8')) + "\n")
    204 196   file.close()
    205 197   
    206  - 
    207  - for k,v in sortE:
    208  - print( str(v) + ". " + str(k.decode('utf-8')))
    209  -
    210  - 
     198 + for k, v in sortE:
     199 + print(str(v) + ". " + str(k.decode('utf-8')))
    211 200   
    212 201   def getTotalLikes(self):
    213  - if(self.is_private):
     202 + if self.is_private:
    214 203   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    215 204   return
    216 205   
    skipped 16 lines
    233 222   for i in a:
    234 223   c = int(i.get('like_count'))
    235 224   like_counter += c
    236  - counter = counter +1
     225 + counter = counter + 1
    237 226   except AttributeError:
    238 227   pass
    239 228   
    240 229   if not 'next_max_id' in only_id:
    241 230   break
    242 231   
    243  - if(self.writeFile):
     232 + if (self.writeFile):
    244 233   file_name = "output/" + self.target + "_likes.txt"
    245 234   file = open(file_name, "w")
    246 235   file.write(str(like_counter) + " likes in " + str(counter) + " posts\n")
    skipped 3 lines
    250 239   pc.printout(" likes in " + str(counter) + " posts\n")
    251 240   
    252 241   def getTotalComments(self):
    253  - if(self.is_private):
     242 + if self.is_private:
    254 243   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    255 244   return
    256 245   
    skipped 16 lines
    273 262   for i in a:
    274 263   c = int(i.get('comment_count'))
    275 264   comment_counter += c
    276  - counter = counter +1
     265 + counter = counter + 1
    277 266   except AttributeError:
    278 267   pass
    279 268   
    280 269   if not 'next_max_id' in only_id:
    281 270   break
    282 271   
    283  - if(self.writeFile):
     272 + if self.writeFile:
    284 273   file_name = "output/" + self.target + "_comments.txt"
    285 274   file = open(file_name, "w")
    286 275   file.write(str(comment_counter) + " comments in " + str(counter) + " posts\n")
    skipped 13 lines
    300 289   a = None
    301 290   counter = 1
    302 291   while True:
    303  - if (a == None):
     292 + if a is None:
    304 293   self.api.getUserFeed(self.target_id)
    305 294   a = self.api.LastJson['items']
    306 295   only_id = self.api.LastJson
    307  - 
    308  -
    309 296   else:
    310 297   self.api.getUserFeed(self.target_id, only_id['next_max_id'])
    311 298   only_id = self.api.LastJson
    skipped 12 lines
    324 311   else:
    325 312   index = ids.index(cc.get('user').get('pk'))
    326 313   post[index] += 1
    327  - counter = counter +1
     314 + counter = counter + 1
    328 315   except AttributeError as ae:
    329 316   pc.printout("\nERROR: an error occurred: ", pc.RED)
    330 317   print(ae)
    331 318   print("")
    332 319   pass
    333 320   
    334  - if not 'next_max_id' in only_id:
     321 + if 'next_max_id' not in only_id:
    335 322   break
    336 323   
    337 324   if len(ids) > 0:
    skipped 10 lines
    348 335   for i in range(len(ids)):
    349 336   t.add_row([post[i], full_name[i], username[i], str(ids[i])])
    350 337   
    351  - if(self.writeFile):
     338 + if self.writeFile:
    352 339   file_name = "output/" + self.target + "_tagged.txt"
    353 340   file = open(file_name, "w")
    354 341   file.write(str(t))
    skipped 3 lines
    358 345   else:
    359 346   pc.printout("Sorry! No results found :-(\n", pc.RED)
    360 347   
    361  - 
    362  - 
    363 348   def getAddrs(self):
    364  - if(self.is_private):
     349 + if self.is_private:
    365 350   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    366 351   return
    367 352   
    skipped 12 lines
    380 365   t.add_row([str(i), address, time])
    381 366   i = i + 1
    382 367   
    383  - if(self.writeFile):
    384  - file_name = "output/" + self.target + "_addrs.txt"
    385  - file = open(file_name, "w")
    386  - file.write(str(t))
    387  - file.close()
     368 + if self.writeFile:
     369 + file_name = "output/" + self.target + "_addrs.txt"
     370 + file = open(file_name, "w")
     371 + file.write(str(t))
     372 + file.close()
    388 373   
    389 374   print(t)
    390 375   
    391 376   def getFollowers(self):
    392  - if(self.is_private):
     377 + if self.is_private:
    393 378   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    394 379   return
    395 380   
    skipped 8 lines
    404 389   for i in followers:
    405 390   t.add_row([str(i['pk']), i['username'], i['full_name']])
    406 391   
    407  - if(self.writeFile):
    408  - file_name = "output/" + self.target + "_followers.txt"
    409  - file = open(file_name, "w")
    410  - file.write(str(t))
    411  - file.close()
     392 + if self.writeFile:
     393 + file_name = "output/" + self.target + "_followers.txt"
     394 + file = open(file_name, "w")
     395 + file.write(str(t))
     396 + file.close()
    412 397   
    413 398   print(t)
    414 399   
    415 400   def getFollowings(self):
    416  - if(self.is_private):
     401 + if self.is_private:
    417 402   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    418 403   return
    419 404   
    skipped 8 lines
    428 413   for i in followings:
    429 414   t.add_row([str(i['pk']), i['username'], i['full_name']])
    430 415   
    431  - if(self.writeFile):
    432  - file_name = "output/" + self.target + "_followings.txt"
    433  - file = open(file_name, "w")
    434  - file.write(str(t))
    435  - file.close()
     416 + if self.writeFile:
     417 + file_name = "output/" + self.target + "_followings.txt"
     418 + file = open(file_name, "w")
     419 + file.write(str(t))
     420 + file.close()
    436 421   
    437 422   print(t)
    438 423   
    439 424   def getUser(self, username):
    440 425   try:
    441  - content = urllib.request.urlopen("https://www.instagram.com/" + username + "/?__a=1" )
     426 + content = urllib.request.urlopen("https://www.instagram.com/" + username + "/?__a=1")
     427 + data = json.load(content)
     428 + if self.writeFile:
     429 + file_name = "output/" + self.target + "_user_id.txt"
     430 + file = open(file_name, "w")
     431 + file.write(str(data['graphql']['user']['id']))
     432 + file.close()
     433 + 
     434 + user = dict()
     435 + user['id'] = data['graphql']['user']['id']
     436 + user['is_private'] = data['graphql']['user']['is_private']
     437 + 
     438 + return user
     439 + 
    442 440   except urllib.error.HTTPError as err:
    443  - if(err.code == 404):
     441 + if err.code == 404:
    444 442   print("Oops... " + username + " non exist, please enter a valid username.")
    445 443   sys.exit(2)
    446 444   
    447  - data = json.load(content)
     445 + return None
    448 446   
    449  - if(self.writeFile):
    450  - file_name = "output/" + self.target + "_user_id.txt"
    451  - file = open(file_name, "w")
    452  - file.write(str(data['graphql']['user']['id']))
    453  - file.close()
     447 + def getUserInfo(self):
     448 + try:
     449 + content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1")
     450 + data = json.load(content)
     451 + data = data['graphql']['user']
    454 452   
    455  - user = dict()
    456  - user['id'] = data['graphql']['user']['id']
    457  - user['is_private'] = data['graphql']['user']['is_private']
     453 + pc.printout("[ID] ", pc.GREEN)
     454 + pc.printout(str(data['id']) + '\n')
     455 + pc.printout("[FULL NAME] ", pc.RED)
     456 + pc.printout(str(data['full_name']) + '\n')
     457 + pc.printout("[BIOGRAPHY] ", pc.CYAN)
     458 + pc.printout(str(data['biography']) + '\n')
     459 + pc.printout("[FOLLOWED] ", pc.GREEN)
     460 + pc.printout(str(data['edge_followed_by']['count']) + '\n')
     461 + pc.printout("[FOLLOW] ", pc.BLUE)
     462 + pc.printout(str(data['edge_follow']['count']) + '\n')
     463 + pc.printout("[BUSINESS ACCOUNT] ", pc.RED)
     464 + pc.printout(str(data['is_business_account']) + '\n')
     465 + if data['is_business_account']:
     466 + pc.printout("[BUSINESS CATEGORY] ")
     467 + pc.printout(str(data['business_category_name']) + '\n')
     468 + pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN)
     469 + pc.printout(str(data['is_verified']) + '\n')
    458 470   
    459  - return user
    460  - 
    461  - def getUserInfo(self):
    462  - try:
    463  - content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1" )
    464 471   except urllib.error.HTTPError as err:
    465  - if(err.code == 404):
     472 + if err.code == 404:
    466 473   print("Oops... " + str(self.target) + " non exist, please enter a valid username.")
    467 474   sys.exit(2)
    468 475   
    469  - data = json.load(content)
    470  - data = data['graphql']['user']
    471  - 
    472  - pc.printout("[ID] ", pc.GREEN)
    473  - pc.printout(str(data['id']) + '\n')
    474  - pc.printout("[FULL NAME] ", pc.RED)
    475  - pc.printout(str(data['full_name']) + '\n')
    476  - pc.printout("[BIOGRAPHY] ", pc.CYAN)
    477  - pc.printout(str(data['biography']) + '\n')
    478  - pc.printout("[FOLLOWED] ", pc.GREEN)
    479  - pc.printout(str(data['edge_followed_by']['count']) + '\n')
    480  - pc.printout("[FOLLOW] ", pc.BLUE)
    481  - pc.printout(str(data['edge_follow']['count']) + '\n')
    482  - pc.printout("[BUSINESS ACCOUNT] ", pc.RED)
    483  - pc.printout(str(data['is_business_account']) + '\n')
    484  - if data['is_business_account'] == True:
    485  - pc.printout("[BUSINESS CATEGORY] ")
    486  - pc.printout(str(data['business_category_name']) + '\n')
    487  - pc.printout("[VERIFIED ACCOUNT] ", pc.CYAN)
    488  - pc.printout(str(data['is_verified']) + '\n')
    489  - 
    490 476   def getPhotoDescription(self):
    491  - if(self.is_private):
     477 + if self.is_private:
    492 478   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    493 479   return
    494 480   
    skipped 15 lines
    510 496   t.add_row([str(count), node.get('accessibility_caption')])
    511 497   count += 1
    512 498   
    513  - if(self.writeFile):
     499 + if self.writeFile:
    514 500   file_name = "output/" + self.target + "_photodes.txt"
    515 501   file = open(file_name, "w")
    516 502   file.write(str(t))
    517 503   file.close()
    518 504   
    519  -
    520 505   print(t)
    521 506   else:
    522 507   pc.printout("Sorry! No results found :-(\n", pc.RED)
    523 508   
    524 509   def getUserPhoto(self):
    525  - if(self.is_private):
     510 + if self.is_private:
    526 511   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    527 512   return
    528 513   
    skipped 11 lines
    540 525   pc.printout("Wrong value entered\n", pc.RED)
    541 526   return
    542 527   
    543  -
    544 528   a = None
    545 529   counter = 0
    546 530   while True:
    547  - if (a == None):
     531 + if a is None:
    548 532   self.api.getUserFeed(self.target_id)
    549 533   a = self.api.LastJson['items']
    550 534   only_id = self.api.LastJson
    skipped 11 lines
    562 546   counter = counter + 1
    563 547   url = item["image_versions2"]["candidates"][0]["url"]
    564 548   photo_id = item["id"]
    565  - end = "output/" + self.target + "_" + photo_id + ".jpg"
     549 + end = "output/" + self.target + "_" + photo_id + ".jpg"
    566 550   urllib.request.urlretrieve(url, end)
    567 551   sys.stdout.write("\rDownloaded %i" % counter)
    568 552   sys.stdout.flush()
    skipped 5 lines
    574 558   counter = counter + 1
    575 559   url = i["image_versions2"]["candidates"][0]["url"]
    576 560   photo_id = i["id"]
    577  - end = "output/" + self.target + "_" + photo_id + ".jpg"
     561 + end = "output/" + self.target + "_" + photo_id + ".jpg"
    578 562   urllib.request.urlretrieve(url, end)
    579 563   sys.stdout.write("\rDownloaded %i" % counter)
    580 564   sys.stdout.flush()
    skipped 13 lines
    594 578   pc.printout("\nWoohoo! We downloaded " + str(counter) + " photos (saved in output/ folder) \n", pc.GREEN)
    595 579   
    596 580   def getCaptions(self):
    597  - if(self.is_private):
     581 + if self.is_private:
    598 582   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    599 583   return
    600 584   
    skipped 3 lines
    604 588   counter = 0
    605 589   captions = []
    606 590   while True:
    607  - if (a == None):
     591 + if a is None:
    608 592   self.api.getUserFeed(self.target_id)
    609 593   a = self.api.LastJson['items']
    610 594   only_id = self.api.LastJson
    skipped 6 lines
    617 601   try:
    618 602   for item in a:
    619 603   if "caption" in item:
    620  - if item["caption"] != None:
     604 + if item["caption"] is not None:
    621 605   text = item["caption"]["text"]
    622 606   captions.append(text)
    623 607   counter = counter + 1
    skipped 15 lines
    639 623   if counter > 0:
    640 624   pc.printout("\nWoohoo! We found " + str(counter) + " captions\n", pc.GREEN)
    641 625   
    642  -
    643  - 
    644  - if(self.writeFile):
     626 + if self.writeFile:
    645 627   file_name = "output/" + self.target + "_captions.txt"
    646 628   file = open(file_name, "w")
    647 629   for s in captions:
    skipped 9 lines
    657 639   return
    658 640   
    659 641   def getMediaType(self):
    660  - if(self.is_private):
     642 + if (self.is_private):
    661 643   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    662 644   return
    663 645   
    skipped 5 lines
    669 651   video_counter = 0
    670 652   
    671 653   while True:
    672  - if (a == None):
     654 + if a is None:
    673 655   self.api.getUserFeed(self.target_id)
    674 656   a = self.api.LastJson['items']
    675 657   only_id = self.api.LastJson
    skipped 29 lines
    705 687   
    706 688   if counter > 0:
    707 689   
    708  - if(self.writeFile):
     690 + if self.writeFile:
    709 691   file_name = "output/" + self.target + "_mediatype.txt"
    710 692   file = open(file_name, "w")
    711 693   file.write(str(photo_counter) + " photos and " + str(video_counter) \
    712  - + " video posted by target\n")
     694 + + " video posted by target\n")
    713 695   file.close()
    714  - 
    715 696   
    716 697   pc.printout("\nWoohoo! We found " + str(photo_counter) + " photos and " + str(video_counter) \
    717 698   + " video posted by target\n", pc.GREEN)
    skipped 5 lines
    723 704   
    724 705   def getUserPropic(self):
    725 706   try:
    726  - content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1" )
     707 + content = urllib.request.urlopen("https://www.instagram.com/" + str(self.target) + "/?__a=1")
    727 708   except urllib.error.HTTPError as err:
    728  - if(err.code == 404):
     709 + if err.code == 404:
    729 710   print("Oops... " + str(self.target) + " non exist, please enter a valid username.")
    730 711   sys.exit(2)
    731 712   
    skipped 8 lines
    740 721   URL = data["graphql"]["user"]["profile_pic_url"]
    741 722   
    742 723   if URL != "":
    743  - end = "output/" + self.target + "_propic.jpg"
     724 + end = "output/" + self.target + "_propic.jpg"
    744 725   urllib.request.urlretrieve(URL, end)
    745 726   pc.printout("Target propic saved in output folder\n", pc.GREEN)
    746 727   
    skipped 1 lines
    748 729   pc.printout("Sorry! No results found :-(\n", pc.RED)
    749 730   
    750 731   def getUserStories(self):
    751  - if(self.is_private):
     732 + if self.is_private:
    752 733   pc.printout("Impossible to execute command: user has private profile\n", pc.RED)
    753 734   return
    754 735   
    skipped 4 lines
    759 740   data = self.api.LastJson
    760 741   counter = 0
    761 742   
    762  - if data['reel'] != None: # no stories avaibile
     743 + if data['reel'] is not None: # no stories avaibile
    763 744   for i in data['reel']['items']:
    764 745   story_id = i["id"]
    765  - if i["media_type"] == 1: # it's a photo
     746 + if i["media_type"] == 1: # it's a photo
    766 747   url = i['image_versions2']['candidates'][0]['url']
    767  - end = "output/" + self.target + "_" + story_id + ".jpg"
     748 + end = "output/" + self.target + "_" + story_id + ".jpg"
    768 749   urllib.request.urlretrieve(url, end)
    769 750   counter += 1
    770 751   
    771  - elif i["media_type"] == 2: # it's a gif or video
     752 + elif i["media_type"] == 2: # it's a gif or video
    772 753   url = i['video_versions'][0]['url']
    773  - end = "output/" + self.target + "_" + story_id + ".mp4"
     754 + end = "output/" + self.target + "_" + story_id + ".mp4"
    774 755   urllib.request.urlretrieve(url, end)
    775 756   counter += 1
    776 757   
    skipped 4 lines
    781 762   
    782 763   def changeTarget(self):
    783 764   pc.printout("Insert new target username: ", pc.YELLOW)
    784  - l = input()
    785  - self.setTarget(l)
     765 + line = input()
     766 + self.setTarget(line)
    786 767   
    787 768   return
    788 769   
  • ■ ■ ■ ■ ■ ■
    main.py
    skipped 5 lines
    6 6  import printcolors as pc
    7 7  import sys
    8 8   
     9 + 
    9 10  def printlogo():
    10 11   pc.printout("________ .__ __ \n", pc.YELLOW)
    11 12   pc.printout("\_____ \ _____|__| _____/ |_ ________________ _____ \n", pc.YELLOW)
    skipped 9 lines
    21 22   
    22 23   
    23 24  def cmdlist():
    24  - #print("set <username>\t Set user to analize")
    25  - #print("clear\t\t Remove the user setted")
    26 25   pc.printout("FILE=y/n\t")
    27 26   print("Enable/disable output in a '<target username>_<command>.txt' file'")
    28 27   pc.printout("info\t\t")
    skipped 29 lines
    58 57  printlogo()
    59 58   
    60 59  parser = argparse.ArgumentParser()
    61  -parser.add_argument('id', type=str, # var = id
     60 +parser.add_argument('id', type=str, # var = id
    62 61   help='username')
    63 62  args = parser.parse_args()
    64 63   
    65 64  api = Osintgram(args.id)
    66 65   
    67  - 
    68 66  while True:
    69 67   pc.printout("Run a command: ", pc.YELLOW)
    70 68   cmd = input()
    71  - if(cmd == "quit" or cmd == "exit"):
     69 + if (cmd == "quit" or cmd == "exit"):
    72 70   pc.printout("Goodbye!\n", pc.RED)
    73 71   sys.exit(0)
    74  - elif cmd == "list" or cmd=="help":
     72 + elif cmd == "list" or cmd == "help":
    75 73   cmdlist()
    76 74   elif cmd == "addrs":
    77 75   api.getAddrs()
    skipped 36 lines
Please wait...
Page is in error, reload to recover