HalChat 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
halchat-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 halwarsing.net
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
halchat-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.1
2
+ Name: HalChat
3
+ Version: 0.0.1
4
+ Summary: HalChat api library
5
+ Author-email: Halwarsing <system@halwarsing.net>
6
+ Project-URL: Homepage, https://halchat.halwarsing.net/
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ # HalChat API module
15
+
16
+ API for HalChat in python
@@ -0,0 +1,3 @@
1
+ # HalChat API module
2
+
3
+ API for HalChat in python
@@ -0,0 +1,17 @@
1
+ [project]
2
+ name = "HalChat"
3
+ version = "0.0.1"
4
+ authors = [
5
+ { name="Halwarsing", email="system@halwarsing.net" },
6
+ ]
7
+ description = "HalChat api library"
8
+ readme = "README.md"
9
+ requires-python = ">=3.8"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "License :: OSI Approved :: MIT License",
13
+ "Operating System :: OS Independent",
14
+ ]
15
+
16
+ [project.urls]
17
+ Homepage = "https://halchat.halwarsing.net/"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.1
2
+ Name: HalChat
3
+ Version: 0.0.1
4
+ Summary: HalChat api library
5
+ Author-email: Halwarsing <system@halwarsing.net>
6
+ Project-URL: Homepage, https://halchat.halwarsing.net/
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ # HalChat API module
15
+
16
+ API for HalChat in python
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/HalChatAPI.py
5
+ src/HalEncryption.py
6
+ src/HalHash.py
7
+ src/__init__.py
8
+ src/HalChat.egg-info/PKG-INFO
9
+ src/HalChat.egg-info/SOURCES.txt
10
+ src/HalChat.egg-info/dependency_links.txt
11
+ src/HalChat.egg-info/top_level.txt
@@ -0,0 +1,4 @@
1
+ HalChatAPI
2
+ HalEncryption
3
+ HalHash
4
+ __init__
@@ -0,0 +1,157 @@
1
+ import requests
2
+ import time
3
+ import json
4
+ import os
5
+ from HalEncryption import HalEncryption
6
+ from Cryptodome.Cipher import PKCS1_OAEP
7
+ from Cryptodome.PublicKey import RSA
8
+ from Cryptodome.Hash import SHA256
9
+ import base64
10
+
11
+ class HalChatAPI:
12
+ def __init__(self,code,sleepTime=1,save_file_passwords='HalChatPasswords.json',auto_join_chats=True):
13
+ self.code=code
14
+ self.url='https://halchat.halwarsing.net/api'
15
+ self.events={'onNewMessage':[],'onNewChat':[],'onReceivePassword':[],'onStart':[],'onClickButton':[]}
16
+ self.isRun=False
17
+ self.sleepTime=sleepTime
18
+ self.chats={}
19
+ self.chatsPasswords={}
20
+ self.bot=requests.post('https://halwarsing.net/api/api?req=getInfoUser',data={'code':self.code}).json()
21
+ self.botId=self.bot['id']
22
+ self.he=HalEncryption()
23
+ self.requested_passwords={}
24
+ self.save_file_passwords=save_file_passwords
25
+ self.auto_join_chats=auto_join_chats
26
+ self.loadPasswords()
27
+
28
+ def apiReq(self,req:str,getData:str='',postData:dict={}):
29
+ postData['code']=self.code
30
+ out=requests.post(self.url+'?req='+req+getData,data=postData)
31
+ if out.status_code:
32
+ try:
33
+ return out.json()
34
+ except json.decoder.JSONDecodeError:
35
+ print('Error: ',req,getData,postData,out.text)
36
+ return None
37
+ return None
38
+
39
+ def event_add(self,name:str,func):
40
+ if not (name in self.events):
41
+ return False
42
+ self.events[name]+=[func]
43
+ return True
44
+
45
+ def event(self,name:str):
46
+ def event_inside(func):
47
+ return self.event_add(name,func)
48
+ return event_inside
49
+
50
+ def run_event(self,name:str,args:list):
51
+ if name in self.events:
52
+ for ev in self.events[name]:
53
+ ev(*args)
54
+ return True
55
+ return False
56
+
57
+ def run(self):
58
+ for v in self.apiReq('getListChats')['chats']:
59
+ self.chats[str(v['uid'])]=[v['maxLastMessage'],v['maxAction']]
60
+ self.isRun=True
61
+ self.run_event('onStart',[])
62
+ while self.isRun:
63
+ data=self.apiReq('getEvents',postData={'chats':json.dumps(self.chats)})
64
+ if not data is None and data['errorCode']==0:
65
+ for msg in data['newMessages']:
66
+ self.chats[str(msg['fromChat'])][0]=msg['uid']
67
+ if str(msg['fromChat']) in self.chatsPasswords:
68
+ msg['message']=self.he.decodeByHash(bytes.fromhex(msg['message']),self.chatsPasswords[str(msg['fromChat'])]+msg['encryptId'],10).decode("utf-8")
69
+ self.run_event("onNewMessage",[msg,str(msg['fromChat']) in self.chatsPasswords])
70
+ for chat in data['newChats']:
71
+ if self.auto_join_chats:
72
+ self.joinChatByInviteId(chat['inviteId'])
73
+ self.chats[str(chat['chatId'])]=chat['maxLastMessage']
74
+ self.run_event("onNewChat",[chat['chatId'],chat['inviteId']])
75
+ for v in data['events']:
76
+ self.chats[str(v['fromChat'])][1]=v['uid']
77
+ if v['type']==2:
78
+ if str(v['fromChat']) in self.requested_passwords:
79
+ passw=self.requested_passwords[v['fromChat']].decrypt(base64.b64decode(v['data'])).decode('utf-8')
80
+ self.addChatPassword(v['fromChat'],passw)
81
+ self.savePasswords()
82
+ v['data']=passw
83
+ del self.requested_passwords[v['fromChat']]
84
+ self.run_event('onReceivePassword',[v['fromChat'],v['data']])
85
+ elif v['type']==6:
86
+ self.run_event('onClickButton',[v['fromChat'],v['fromId'],v['fromMsg'],v['data']])
87
+
88
+ time.sleep(self.sleepTime)
89
+
90
+ def close(self):
91
+ self.isRun=False
92
+
93
+ def addChatPassword(self,chatId:int,password:str):
94
+ self.chatsPasswords[str(chatId)]=password
95
+
96
+ def requestPassword(self,chatId:int):
97
+ key=RSA.generate(2048)
98
+ out=self.apiReq("requestPassword",getData='&chatId='+str(chatId),postData={'publicKey':base64.b64encode(key.publickey().exportKey()).decode('utf-8')})
99
+ if out['errorCode']==0:
100
+ self.requested_passwords[str(chatId)]=PKCS1_OAEP.new(key,hashAlgo=SHA256)
101
+
102
+ def savePasswords(self):
103
+ f=open(self.save_file_passwords,'w')
104
+ f.write(json.dumps(self.chatsPasswords))
105
+ f.close()
106
+
107
+ def loadPasswords(self):
108
+ if os.path.isfile(self.save_file_passwords):
109
+ f=open(self.save_file_passwords,'r')
110
+ self.chatsPasswords=json.loads(f.read())
111
+ f.close()
112
+
113
+ def sendMessage(self,chatId:int,message:str,encryptId:str=None,
114
+ attachments:list=[],answerMsg:int=-1,commentMsg:int=-1,
115
+ soundMsg:str=-1,buttons:list=None,plugins=None):
116
+ if str(chatId) in self.chatsPasswords:
117
+ if encryptId is None:
118
+ encryptId=self.he.hh.Str2Hash(str(time.time_ns())+":"+str(chatId)+":"+str(self.chats[str(chatId)]),16,16)
119
+ message=self.he.encodeByHash(message.encode('utf-8'),self.chatsPasswords[str(chatId)]+encryptId,10).hex()
120
+ elif encryptId is None:
121
+ encryptId=""
122
+ postData={
123
+ 'message':message,
124
+ 'attachments':json.dumps(attachments),
125
+ 'encryptId':encryptId
126
+ }
127
+ if not (buttons is None):
128
+ postData['buttons']=json.dumps(buttons)
129
+ if not (plugins is None):
130
+ postData['plugins']=json.dumps(plugins)
131
+ return self.apiReq(
132
+ "sendMessage",
133
+ getData="&soundMsg="+str(soundMsg)+"&chatId="+str(chatId)+("" if answerMsg==-1 else "&answerMsg="+str(answerMsg))+("" if commentMsg==-1 else "&commentMsg="+str(commentMsg)),
134
+ postData=postData
135
+ )
136
+
137
+ def joinChatByInviteId(self,inviteId:int):
138
+ return self.apiReq('joinChatByInviteId',getData='&inviteId='+str(inviteId))
139
+
140
+ def deleteMessage(self,chatId:int,msgId:int):
141
+ return self.apiReq('deleteMessage',getData='&chatId='+str(chatId)+'&msgId='+str(msgId))
142
+
143
+ def editMessage(self,chatId:int,msgId:int,message:str,encryptId:str=None,attachments:list=[]):
144
+ if str(chatId) in self.chatsPasswords:
145
+ if encryptId is None:
146
+ encryptId=self.he.hh.Str2Hash(str(time.time_ns())+":"+str(chatId)+":"+str(self.chats[str(chatId)]),16,16)
147
+ message=self.he.encodeByHash(message.encode('utf-8'),self.chatsPasswords[str(chatId)]+encryptId,10).hex()
148
+ elif encryptId is None:
149
+ encryptId=""
150
+ return self.apiReq('editMessage',getData="&chatId="+str(chatId)+"&msgId="+str(msgId),
151
+ postData={'message':message,'attachments':json.dumps(attachments),'encryptId':encryptId})
152
+
153
+ def setMenu(self,chatId:int,menu:list):
154
+ return self.apiReq('setMenu',getData="&chatId="+str(chatId),postData={'menu':json.dumps(menu)})
155
+
156
+ def execHDB(self,chatId:int,query:str):
157
+ return self.apiReq('execHDB','&chatId='+chatId,{'query':json.dumps({'exec':exec})})
@@ -0,0 +1,42 @@
1
+ from HalHash import HalHash
2
+
3
+ class HalEncryption:
4
+ def __init__(self):
5
+ self.version="0.0.3"
6
+ self.hh=HalHash()
7
+
8
+ def shift_forward(self,a:int,b:int):
9
+ o=a+b
10
+ return o-256 if (o>255) else o
11
+
12
+ def shift_back(self,a:int,b:int):
13
+ o=a-b
14
+ return 256+o if o<0 else o
15
+
16
+ def encode(self,data:bytes,password:str,hashlength:int=256,hashcount:int=64,secretData:str="") -> bytes:
17
+ return self.encodeByHash(data,self.hh.Str2Hash(password,hashlength,hashcount),hashcount,secretData)
18
+
19
+ def encodeByHash(self,data:bytes,passw:str,hashcount:int=64,secretData:str="")->bytes:
20
+ out=[]
21
+ a=0
22
+ b=len(passw)-1
23
+ newPassw=self.hh.Str2Hash(passw+passw+secretData,len(passw),hashcount)
24
+ for i in range(len(data)):
25
+ out+=[self.shift_forward(int(data[i]),int(newPassw[a:a+2],16))]
26
+ a+=1
27
+ if a>=b:newPassw=self.hh.Str2Hash(passw+newPassw,len(passw),hashcount);a=0
28
+ return bytes(out)
29
+
30
+ def decode(self,data:bytes,password:str,hashlength:int=256,hashcount:int=64,secretData:str="")->bytes:
31
+ return self.decodeByHash(self.hh.Str2Hash(password,hashlength,hashcount),hashcount,secretData)
32
+
33
+ def decodeByHash(self,data:bytes,passw:str,hashcount:int=64,secretData:str="")->bytes:
34
+ out=[]
35
+ a=0
36
+ b=len(passw)-1
37
+ newPassw=self.hh.Str2Hash(passw+passw+secretData,len(passw),hashcount)
38
+ for i in range(len(data)):
39
+ out+=[self.shift_back(int(data[i]),int(newPassw[a:a+2],16))]
40
+ a+=1
41
+ if a>=b:newPassw=self.hh.Str2Hash(passw+newPassw,len(passw),hashcount);a=0
42
+ return bytes(out)
@@ -0,0 +1,63 @@
1
+ class HalHash:
2
+ def __init__(self):self.version="0.0.2"
3
+ def array_toHex(arr)->str:
4
+ return "".join([hex(i)[2:] for i in arr])
5
+ def getHalfInt(i,h)->int:
6
+ temp=str(i)
7
+ temp=temp[:len(temp)//2] if h==0 else temp[len(temp)//2:]
8
+ return 0 if temp=="" else int(temp)
9
+ def Str2Hash(self,text:str,length:int,count:int,maxIterration:int=100000):
10
+ return self.Bin2Hash(text.encode("utf8"),length,count,maxIterration)
11
+ def Bin2Hash(self,binary:bytes,length:int,count:int,maxIterration:int=100000):
12
+ #if (len(binary)==1):binary+=b'\0'
13
+ count=length if length<count else count
14
+ count=len(binary) if len(binary)<count else count
15
+ sizeD=len(binary)//count
16
+ g=length*count
17
+ d=[int.from_bytes(binary[i*sizeD:i*sizeD+sizeD],byteorder="big",signed=False)*g for i in range(count)]
18
+
19
+ if len(binary)%count:
20
+ d[count-1]=int.from_bytes(binary[count*sizeD-sizeD:],byteorder="big",signed=False)*g
21
+
22
+ for i in range(int((length-count)/2)):
23
+ d.append(i+2)
24
+ for b in range(count):
25
+ d[len(d)-1]=d[b]*d[len(d)-1]+g*(i+1)
26
+ count=len(d)
27
+ temp=d.copy()
28
+ g=HalHash.getHalfInt(g,0)+HalHash.getHalfInt(g,1)
29
+ for i in range(count):
30
+ for b in range(count):
31
+ # d[b]=d[b]+temp[i]+g
32
+ d[b]=d[b]+temp[i]*temp[i]+temp[i]*g
33
+ lc=count-1
34
+ mc=0
35
+ h=""
36
+ while True:
37
+ h=HalHash.array_toHex(d)
38
+ if (len(h)<length):
39
+ for i in range(count):
40
+ if (i==lc):
41
+ #d[i]=HalHash.getHalfInt(d[i],0)*HalHash.getHalfInt(d[i],1)+g
42
+ d[i]=d[i]*2+g
43
+ else:
44
+ temp=HalHash.getHalfInt(d[i],0)+HalHash.getHalfInt(d[i],1)
45
+ d[i]=int(str(temp)+str(HalHash.getHalfInt(d[i+1],0)+HalHash.getHalfInt(d[i+1],1)))
46
+ d[i+1]=int(str(HalHash.getHalfInt(d[i+1],0)+HalHash.getHalfInt(d[i+1],1))+str(temp))
47
+ elif (len(h)>length):
48
+ if mc>maxIterration:
49
+ h=h[0:length]
50
+ break
51
+ for i in range(count):
52
+ if (i==lc):
53
+ d[i]=HalHash.getHalfInt(d[i],0)+HalHash.getHalfInt(d[i],1)+g
54
+ else:
55
+ temp=HalHash.getHalfInt(d[i],1)
56
+ d[i]=HalHash.getHalfInt(d[i],0)+HalHash.getHalfInt(d[i+1],1)
57
+ d[i+1]=HalHash.getHalfInt(d[i+1],0)+temp
58
+ else:
59
+ break
60
+ mc+=1
61
+ return h
62
+
63
+ hh=HalHash()
File without changes