Skip to content

Commit

Permalink
Fixes Telegram and Koodous
Browse files Browse the repository at this point in the history
  • Loading branch information
Te-k committed Jun 14, 2022
1 parent 079b5b3 commit 24206c8
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 39 deletions.
21 changes: 12 additions & 9 deletions harpoon/commands/koodousc.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#! /usr/bin/env python
import sys
import json
from datetime import datetime
from harpoon.commands.base import Command
from harpoon.lib.utils import bracket, unbracket
from harpoon.lib.koodous import Koodous, KoodousError, KoodousNotFound


Expand Down Expand Up @@ -34,26 +32,31 @@ def add_arguments(self, parser):
parser_d = subparsers.add_parser('analysis', help='Get a full analysis from Koodous')
parser_d.add_argument('HASH', help='Sha256')
parser_d.set_defaults(subcommand='analysis')
parser_e = subparsers.add_parser('account', help="Get information on the account")
parser_e.set_defaults(subcommand='account')
self.parser = parser

def run(self, conf, args, plugins):
kd = Koodous(token=conf['Koodous']['token'])
def run(self, args, plugins):
kd = Koodous(token=self._config_data['Koodous']['token'])
if 'subcommand' in args:
try:
if args.subcommand == "hash":
res = kd.sha256(args.HASH)
print(json.dumps(res, sort_keys=True, indent=4))
print(json.dumps(res, indent=4))
elif args.subcommand == "search":
res = kd.search(args.QUERY)
print(json.dumps(res, sort_keys=True, indent=4))
print(json.dumps(res, indent=4))
elif args.subcommand == "dl":
data = kd.download(args.HASH)
with open(args.HASH, "wb+") as f:
f.write(data)
print("File downlaoded as {}".format(args.HASH))
print("File downloaded as {}".format(args.HASH))
elif args.subcommand == "analysis":
res = kd.analysis(args.HASH)
print(json.dumps(res, sort_keys=True, indent=4))
print(json.dumps(res, indent=4))
elif args.subcommand == "account":
res = kd.account()
print(json.dumps(res, indent=4))
else:
self.parser.print_help()
except KoodousNotFound:
Expand All @@ -65,7 +68,7 @@ def intel(self, type, query, data):
if type == "hash":
if len(query) == 64:
try:
kd = Koodous(token=conf['Koodous']['token'])
kd = Koodous(token=self._config_data['Koodous']['token'])
res = kd.sha256(query)
except KoodousError:
pass
Expand Down
104 changes: 83 additions & 21 deletions harpoon/commands/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import csv
import sys
import time
from getpass import getpass
from telethon import TelegramClient
from telethon.errors import SessionPasswordNeededError
from telethon.tl.functions.channels import GetParticipantsRequest
Expand Down Expand Up @@ -44,34 +45,39 @@ def add_arguments(self, parser):
parser_a.set_defaults(subcommand='id')
parser_b = subparsers.add_parser('messages', help='Get messages from a public channel')
parser_b.add_argument('ID', help='Id to be requested')
parser_b.add_argument('--limit', '-l', default=25, type=int,
help="Limit number of messages to get")
parser_b.add_argument(
'--limit', '-l', default=25, type=int,
help="Limit number of messages to get")
parser_b.add_argument('--format', '-f', default='text', choices=['text', 'csv', 'json'], help="Output format")
parser_b.add_argument('--dump', '-D', help="Dump media in the given path")
parser_b.set_defaults(subcommand='messages')
parser_c = subparsers.add_parser('users', help='Get user list of a group')
parser_c.add_argument('ID', help='Id to be requested')
parser_c.add_argument('--limit', '-l', default=25, type=int,
help="Limit number of messages to get")
parser_c.add_argument('--format', '-f', default='text', choices=['text', 'csv', 'json'],
help="Output format")
parser_c.add_argument(
'--limit', '-l', default=25, type=int,
help="Limit number of messages to get")
parser_c.add_argument(
'--format', '-f', default='text', choices=['text', 'csv', 'json'],
help="Output format")
parser_c.set_defaults(subcommand='users')
self.parser = parser

def run(self, conf, args, plugins):
def run(self, args, plugins):
session_file = os.path.join(os.path.expanduser("~"), ".config/harpoon/telegram")
client = TelegramClient(session_file, int(conf['Telegram']['id']), conf['Telegram']['hash'])
client = TelegramClient(
session_file,
int(self._config_data['Telegram']['id']),
self._config_data['Telegram']['hash'])
# FIXME : do not connect if it's help
client.connect()
if not client.is_user_authorized():
client.send_code_request(conf['Telegram']['phone'])
client.send_code_request(self._config_data['Telegram']['phone'])
code_ok = False
while not code_ok:
code = input("Enter Telegram code:")
try:
code_ok = client.sign_in(conf['Telegram']['phone'], code)
code_ok = client.sign_in(self._config_data['Telegram']['phone'], code)
except SessionPasswordNeededError:
# FIXME: getpass is not imported, that would not work
password = getpass('Two step verification enabled. Please enter your password: ')
code_ok = client.sign_in(password=password)
if hasattr(args, 'subcommand'):
Expand All @@ -87,7 +93,7 @@ def run(self, conf, args, plugins):
users = {}
if args.dump:
if not os.path.exists(args.dump):
os.makedirs(args.dump)
os.makedirs(args.dump)
if args.format == "text":
if len(messages) == 0:
print("No messages in this channel")
Expand Down Expand Up @@ -155,7 +161,7 @@ def run(self, conf, args, plugins):
if args.dump:
for msg in messages:
if msg.media is None:
if not os.path.exists(os.path.join(args.dump, str(msg.id)+ '.jpg')):
if not os.path.exists(os.path.join(args.dump, str(msg.id) + '.jpg')):
client.download_media(msg.media, os.path.join(args.dump, str(msg.id)))
time.sleep(7)
elif args.format == "csv":
Expand All @@ -167,26 +173,75 @@ def run(self, conf, args, plugins):
if m.from_id not in users:
users[m.from_id] = client.get_entity(m.from_id)
if isinstance(m, telethon.tl.types.MessageService):
w.writerow([m.date.isoformat(), m.id, users[m.from_id].username, m.from_id, m.__class__.__name__, m.action.__class__.__name__])
w.writerow([
m.date.isoformat(),
m.id,
users[m.from_id].username,
m.from_id,
m.__class__.__name__,
m.action.__class__.__name__
])
else:
w.writerow([m.date.isoformat(), m.id, users[m.from_id].username, m.from_id, m.__class__.__name__, m.message])
w.writerow([
m.date.isoformat(),
m.id,
users[m.from_id].username,
m.from_id,
m.__class__.__name__,
m.message
])
else:
w = csv.writer(sys.stdout, delimiter=';')
w.writerow(["Date", "id", "Type", "Information", "Media", "Views"])
for m in messages:
if isinstance(m, telethon.tl.types.MessageService):
if isinstance(m.action, telethon.tl.types.MessageActionChatEditPhoto):
w.writerow([m.date.isoformat(), m.id, m.__class__.__name__, "Channel Photo Changed", "No", ""])
w.writerow([
m.date.isoformat(),
m.id,
m.__class__.__name__,
"Channel Photo Changed",
"No",
""
])
elif isinstance(m.action, telethon.tl.types.MessageActionChannelCreate):
w.writerow([m.date.isoformat(), m.id, m.__class__.__name__, "Channel Created", "No", ""])
w.writerow([
m.date.isoformat(),
m.id,
m.__class__.__name__,
"Channel Created",
"No",
""
])
else:
w.writerow([m.date.isoformat(), m.id, m.__class__.__name__, m.action.__class__.__name__, "No", ""])
w.writerow([
m.date.isoformat(),
m.id,
m.__class__.__name__,
m.action.__class__.__name__,
"No",
""
])
else:
if m.media is None:
# message
w.writerow([m.date.isoformat(), m.id, m.__class__.__name__, m.message, "No", m.views])
w.writerow([
m.date.isoformat(),
m.id,
m.__class__.__name__,
m.message,
"No",
m.views
])
else:
w.writerow([m.date.isoformat(), m.id, m.__class__.__name__, m.message, "Yes", m.views])
w.writerow([
m.date.isoformat(),
m.id,
m.__class__.__name__,
m.message,
"Yes",
m.views
])
if args.dump:
if not os.path.exists(os.path.join(args.dump, str(m.id) + '.jpg')):
client.download_media(m.media, os.path.join(args.dump, str(m.id)))
Expand All @@ -203,7 +258,14 @@ def run(self, conf, args, plugins):
all_participants = []

while True:
participants = client.invoke(GetParticipantsRequest(entity, ChannelParticipantsSearch(''), offset, limit, hash=0))
participants = client.invoke(
GetParticipantsRequest(
entity,
ChannelParticipantsSearch(''),
offset,
limit,
hash=0
))
if not participants.users:
break
all_participants.extend(participants.users)
Expand Down
30 changes: 21 additions & 9 deletions harpoon/lib/koodous.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import requests


class KoodousError(Exception):
def __init__(self, message):
Exception.__init__(self, message)
self.message = message


class KoodousNotFound(KoodousError):
pass


class Koodous(object):
def __init__(self, token=None):
self.token = token
self.base_url = "https://api.koodous.com/apks"
self.base_url = "https://developer.koodous.com"

def _query(self, url, params={}):
headers = {
"Authorization":"Token " + self.token,
"Authorization": "Token " + self.token,
'User-Agent': 'Harpoon (https://github.com/Te-k/harpoon)'
}
r = requests.get(self.base_url + url, params=params, headers=headers)
Expand All @@ -27,17 +29,27 @@ def _query(self, url, params={}):
return r.json()

def sha256(self, hash):
return self._query("/" + hash)
return self._query("/apks/" + hash)

def search(self, query):
return self._query("", {'search': query})
return self._query("/apks/", {'search': query})

def download(self, hash):
res = self._query("/" + hash + "/download")
r = requests.get(res["download_url"])
if r.status_code != 200:
raise KoodousError("Bad HTTP code {}".format(r.status_code))
headers = {
"Authorization": "Token " + self.token,
'User-Agent': 'Harpoon (https://github.com/Te-k/harpoon)'
}
r = requests.get(
self.base_url + "/apks/" + hash + "/download/",
headers=headers)
if r.status_code == 404:
raise KoodousNotFound()
elif r.status_code != 200:
raise KoodousError("Invalid HTTP code {}".format(r.status_code))
return r.content

def analysis(self, hash):
return self._query("/" + hash + "/analysis")
return self._query("/apks/" + hash + "/analysis")

def account(self):
return self._query("/account/")

0 comments on commit 24206c8

Please sign in to comment.