Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persian text bugs were fixed #7

Merged
merged 4 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -12,3 +12,10 @@ Then run:
python src/chat_statistics/stats.py
```
to generate a word cloud of json data in `DATA_DIR`

## Adding Font:
Use Vazir font, which may be found in the following repository, to better display Persian words alongside English words:

https://github.com/rastikerdar/vazir-font/releases

add **`Vazir.ttf`** in **`src/data`** directory
52 changes: 42 additions & 10 deletions src/chat_statistics/stats.py
@@ -1,9 +1,11 @@
import json
import re
from collections import Counter, defaultdict
from pathlib import Path
from typing import Union

import arabic_reshaper
import demoji
from bidi.algorithm import get_display
from hazm import Normalizer, sent_tokenize, word_tokenize
from loguru import logger
Expand All @@ -14,6 +16,7 @@
class ChatStatistics:
"""Generates chat statistics from a telegram chat json file
"""

def __init__(self, chat_json: Union[str, Path]):
"""
:param chat_json: path to telegram export json file
Expand Down Expand Up @@ -89,6 +92,25 @@ def get_top_users(self, top_n: int = 10) -> dict:

return dict(Counter(users).most_common(top_n))

def remove_stopwords(self, text):
"""Removes stop-words from the text.

:param text: Text that may contain stop-words.
"""
tokens = word_tokenize(self.normalizer.normalize(text))
tokens = list(filter(lambda item: item not in self.stop_words, tokens))
return ' '.join(tokens)

def de_emojify(self, text):
"""Removes emojis and some special characters from the text.

:param text: Text that contains emoji
"""
regrex_pattern = re.compile(
pattern="[\u2069\u2066]+", flags=re.UNICODE)
text = regrex_pattern.sub('', text)
return demoji.replace(text, " ")

def generate_word_cloud(
self,
output_dir: Union[str, Path],
Expand All @@ -102,29 +124,39 @@ def generate_word_cloud(
"""
logger.info("Loading text content...")
text_content = ''
for msg in self.chat_data['messages']:
if type(msg['text']) is str:
tokens = word_tokenize(msg['text'])
tokens = list(filter(lambda item: item not in self.stop_words, tokens))
text_content += f" {' '.join(tokens)}"

# normalzie, reshape for final word cloud
text_content = self.normalizer.normalize(text_content)
text_content = arabic_reshaper.reshape(text_content)
messages = iter(self.chat_data['messages'])
for message in messages:
msg = message['text']
if isinstance(msg, list):
for sub_msg in msg:
if isinstance(sub_msg, str):
text_content += f" {self.remove_stopwords(sub_msg)}"
elif isinstance(sub_msg, dict) and sub_msg['type'] in {
'text_link', 'bold', 'italic',
'hashtag', 'mention', 'pre'
}:
text_ = self.remove_stopwords(sub_msg['text'])
text_content += f" {text_}"
else:
text_content += f" {self.remove_stopwords(msg)}"

# reshape for final word cloud
text_content = arabic_reshaper.reshape(self.de_emojify(text_content))
text_content = get_display(text_content)

logger.info("Generating word cloud...")
# generate word cloud
wordcloud = WordCloud(
width=1200, height=1200,
font_path=str(DATA_DIR / 'BHoma.ttf'),
font_path=str(DATA_DIR / 'Vazir.ttf'),
background_color=background_color,
max_font_size=250
).generate(text_content)

logger.info(f"Saving word cloud to {output_dir}")
wordcloud.to_file(str(Path(output_dir) / 'wordcloud.png'))


if __name__ == "__main__":
chat_stats = ChatStatistics(chat_json=DATA_DIR / 'online.json')
top_users = chat_stats.get_top_users(top_n=10)
Expand Down
186 changes: 184 additions & 2 deletions src/data/stopwords.txt
@@ -1,4 +1,23 @@

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
1
2
3
4
5
6
7
8
9
10
و
در
به
Expand Down Expand Up @@ -334,4 +353,167 @@
تو
میشه
اگه
اون
اون
?
??
؟
:
،
[
]
×
x
a
ی
=
!
(
)
.
بدین
کنین
الان
مثلا
می کنه
چی
هستن
کردین
؟؟
چیه
خوبی
»
«
>>
<<
>>>
>>>
ک
میده
احتمالا
سر
می کنم
دیگه
برا
اصلا
میکنم
میکنم
دیدم
بشه
نداره
کردید
کن
میکنه
کردن
ممکنه
باز
حالا
یعنی
بزنید
شدم
میخوام
دارید
بعدش
می تونید
یاد
اینو
می تونه
دارم
دارن
داره
میشن
میاد
کنی
اینه
کنن
نظرم
ببینید
میزنم
اوکی
برام
بدید
همون
می تونه
نمی تونم
پیدا
بده
بهش
نشد
میشم
خودم
گفتم
کنه
میگه
خوبه
لطف
خودش
بدم
داشتم
خب
می تونه
خواهش
دوست
نمی کنه
بقیه
باشید
شه
هستش
می تونه
بدیم
دوتا
نکردم
وجود
نمیشه
مگه
کلی
حتما
بهتره
نمیکنه
چقدر
بیاد
بخیر
دارین
ینی
ازتون
دست
مشکلی
نمی تونم
کلا
کم
واسه
بهم
میدم
کمی
دست
دادم
بهم
ینی
بابا
بازم
"
'
؟!
بریم
مند
تونید
+
چک
میگم
میشه
زدم
کردی
زدن
اونجا
عه
اینم
آخه
باشن
بودم
رفتم
خودت
سللا
پی
لپ
تاپ
...
دادین