From 1ec60fd83fb43ae16bb9f155fe51a73f46d2a5ef Mon Sep 17 00:00:00 2001 From: emile Date: Thu, 3 Oct 2024 16:22:59 +0300 Subject: [PATCH] new --- osinaweb/db.sqlite3 | Bin 1990656 -> 1990656 bytes .../osichat/__pycache__/admin.cpython-310.pyc | Bin 622 -> 652 bytes .../__pycache__/consumers.cpython-310.pyc | Bin 19308 -> 20610 bytes .../__pycache__/models.cpython-310.pyc | Bin 11652 -> 12466 bytes .../__pycache__/routing.cpython-310.pyc | Bin 569 -> 569 bytes osinaweb/osichat/admin.py | 1 + .../api/__pycache__/views.cpython-310.pyc | Bin 4603 -> 4612 bytes osinaweb/osichat/api/views.py | 2 +- osinaweb/osichat/consumers.py | 61 +++++++++++++++++- .../osichat/migrations/0033_chatconnection.py | 27 ++++++++ .../0033_chatconnection.cpython-310.pyc | Bin 0 -> 1125 bytes osinaweb/osichat/models.py | 31 ++++++++- .../__pycache__/models.cpython-310.pyc | Bin 16933 -> 16933 bytes osinaweb/osinacore/models.py | 8 ++- 14 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 osinaweb/osichat/migrations/0033_chatconnection.py create mode 100644 osinaweb/osichat/migrations/__pycache__/0033_chatconnection.cpython-310.pyc diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index d6d1ef972e253dae94ad2caa5982fce0ace97773..51dfbe3c76da1643b37072a32815fb81f3942d4d 100644 GIT binary patch delta 1049 zcmZ{iZ%7ky7{~8-ySx3n+d0>qw_9Tb62g|Zo&RR0nMFlOnlB9O+)PK!WNMAV{*b6J z|GiKb{-{?H(NQ+vKJp7?w;>+-{<@LU01TR zE7>_Ln%x9}KBXWKK~ND9mVFE1e*j(Zp$~ zj1ldWn2Xvjhnp@mMmK1SL_$r`a9c!4JS?ocqZy(fC$ulj8Xf(do~2cIGItG=4n~7W z1r4RjV5$tHN`GShb@3N)8o}BmdP*`QFtR|4fI7Uhp$HZMH#}*L$BfiD7W_n_}Ve)g!+$0y|9PCTBgDrrt7Pi#iEzpE0S8V^&N7Jl7i9G)*(y`7K()!P^!)mc}gQWADrq zK0GO8;$LHyY`ipP5wQ(h#CTGt#d#Bg2{%NL4!?iP9YVS4%3f!XrnqI|I1YH6M|3B9 wuQRrQpNuDsHr(Es&3gXcW5D|#_m2cY=mCOIS3OROytn8YsWzyFYUdCBH?CS{u>b%7 delta 560 zcmZoTP}y*xa)Pv=CIbWGGYDp2W?*2koTy{WsJSsATZd6%@);ci#*WQ@b*?cn#!SAV zZ@?VGwstbRf%oPR13R|K3JtQG*P4aTWbR-+vzh&ZAoFIyhAm8!H(X`eeBr9eE1=>v z)7cL&?gR?IVQpV?j1h>LfS4JGS%4TM#s8$Kr8^n zfbBU)As3(x8z3`08_QEr=lY^x=*nczdNAqoD|IOpfUCR}~xs>-0 zYaj>$RhqJH4_1})Wt^^1D#0@Szp9+jbYC?&+39ap9V>Gd}n)KQVxvk!d?efZPv$0Kc8aq5uE@ diff --git a/osinaweb/osichat/__pycache__/admin.cpython-310.pyc b/osinaweb/osichat/__pycache__/admin.cpython-310.pyc index 2d3ede8d10231174b32baab54cf0c99acb6364dd..6bd5fecb67615f900f386fda6b7ad83f69bb49b1 100644 GIT binary patch delta 86 zcmaFI(!PbIwRC oan8@nOHD4x%+H%_%D9kC6sWIAbn+d>B1XB%{!FqgJd6U207se^{Qv*} delta 59 zcmeBSeaFI=&&$ij00jF?kEeZSoX97`xMHIA@`?8p7zHQ(cb*)?xPVOrC|x8n`3GYW Nqs-)NCRru{MgS7k5a|E_ diff --git a/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc b/osinaweb/osichat/__pycache__/consumers.cpython-310.pyc index 5888301d418a234c4fd567b16f9b15f76997d469..b80325276d76b561a5294ac5bf92f2a81904ac95 100644 GIT binary patch delta 6692 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 F?SGlz>DB-M diff --git a/osinaweb/osichat/__pycache__/models.cpython-310.pyc b/osinaweb/osichat/__pycache__/models.cpython-310.pyc index 1eb2f9e3b4768579fedfd25832b58d493002a45e..dea9d81b076646a4a51ba6859cf9156fe2528501 100644 GIT binary patch delta 4422 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 M-1M}Ed{yrM1Hm1q8~^|S delta 3608 zcmaJ@YiyfW8TOZp^CiB-b-gr6lh||YBww6MDIJa4(st{bCEe1lZCYry;<*04q)vTF zjvdgtLZ+>wVk$-1+g-#Zy8=r=D_b3*R&f|nn8t{jMhPat+}KJdHS+LbJ8S7u{jZPo zvVOHs<4yV?H8PB=PeE*9PG*9Q;Smx_f?Z6nsc?#4;xYgd$=*7Po)#n z@p+Xlql5z$z0#4&B&IENCuz*JS363VT|KuQ!+IwGrDJr{4OhrH4drL(J=gV^tlp4L z6s&w9p3Y5|kHz}+seC+_O{cQfxs@C47R@yQZFM4@R;TG7o)IS&P&2gKI~19OShg2N zdJDNiA{{s9Rico}W#{M_?@;Vc47>|)08jp3Y)H+<6Q-%Gd|n-=|9VIJPonR$ zfX@L6fYLr9iFe_GQ#9My&r!3~_(uOu41`%z@3UXn&g&)?KXBNT6g%h<-;cZEn2`XS z0VDzNhO!t8U7dzJO%t1LAK{jqJqOhcU=}b3P=GvO5>VnQK6A63*DZ2+PZFga*-Sped2Ye4ed=QWVOjAdoHF}Ok!)=rLG}L<; zCfw}6sgzpt?w9CvU@9QNTrwMy;_EAa417&%g9VqJ%7^JlNF}km6;hZUZHhz?{i>6p z=u9e$!$$mK)Y;oUY7g8WZVvqanbqUm^Co@JG`Ud8`6HNzz11PWW`?4E;@Ew|DJyNN zuRo_buXk6mwgUSK)V#2=N_=iH!8U%ZjV2#&Qs6UYt8pz4J7sW@>&Qux@a6>Cgh zuc+q>YO0XRSVoQ7L#^%6FgnXlwia0lcJ%x#rkH=GM0;MlO7FDCwmpr(aGSlymmxjI zU{u+TlL}ZeQ#Wnv2vn^)Xt?9ri3N;vDm(lzu?ElzK)|Yt49m3};!b@9T~7ciMBCpT zbTAl=R0;+0^XD;7f?|}e1Y4cr=x6EGVB~&r@;A}{96&t%5hrtp6of?{@(2Fr0}Q&u ztp(W2P3&cOSa%1i)FKy(cG?$;dmiQ?Y!2I>^u5r2&k!`#YX_%)hdLsX@awr%>16+L z(5~Bmv*$9V)~l!Z$F>wgTFRT6hqRtX>I#~uZERv$K1`fGx0U$<172qM&_S8-NTvKK zdX8kR@f?GlFgUiINkX8MUBW_4h6O*G9IO+&y~MpA@HgMUfZXtNR`{wF>*@K%Ccg8g zM_%DBqpIi{&6=qxPDqRE)UvIsKAteuHI~N}th&0LK?z)7>9FBZWuB+^I=7zr4n}OC zjYvSUCz7~1)Il`sOskMcrSoNhFP0M4-{lbv+B)kR&0p(d<_h}c;-(gwj0Wk*fKHkI zI$DV|FYp@znR}S4W*H&Y*jJJrfM`lpT7o1T#j1$O2^TUgK9l47(X7bnRUQ>!PXE$b z&>cRmF>Xykn{+Jto0-zc!gX$KFbZpI4wVc8UK4fqtK5v0EEMZz*97-nxm?;xWF-cQ z&e{1h=~S{Jsn>XcRwku>fPJ*r__1|y6H0{bFZCqU7ifP=GySgXWbAovaxiZw0HxSo zuL5d`#=3(oFJO9wtdFid-rb>T-=>#)dR@p6brtX}`cqG&EeNsfwm}nB$q1;YsKp3x z-;gp$BYqL)vIPX5JPu&hvii0}8DqeM%j4$t6sA`Uqh({Q!>l(L2I*bnW3HzS(K(7~ zF9IYk5S{8r0K|oQ1|W%sm2aJBFnWkRk@vEIM57zMu3Bg%V2ArV$QK*ZuG47j;Xagy ziTVs*0`bB_vsO_nf1n}*iaKBR@)kTy|BRi|hUidVYuC@XhhG&^TqIcpWPJTpDs9PC zb(Egy8?01YltdsH*;ycdlG9>c^>cvKs>B}0W7$K;jrPob)aNZL8%GhTKr`e}Z}Ef&!P73p zKEA*LTtY-|L}}+>r}L+v^b49CyrhNbZ-e1;J*+6!j^#`%ZQnD!7;zpTF$@w?6Qv9( z6ayuU;V7|zEMI{T2iTrW&YVwMdzq6X-$x7Enzs!31O7h$QGbYk8~jfG#Qd%%=l=i& Cy48{Z diff --git a/osinaweb/osichat/__pycache__/routing.cpython-310.pyc b/osinaweb/osichat/__pycache__/routing.cpython-310.pyc index 3b115dfd1f6a5a050c43cdaa394244e773649176..b14819691ce0990fde5edf3e12c8aadfb0cd2416 100644 GIT binary patch delta 20 acmdnVvXg~7pO=@50SK}u{@ci{#{>W~t_1%8 delta 20 acmdnVvXg~7pO=@50SK1Oez=iaj|l)Y_5~*Z diff --git a/osinaweb/osichat/admin.py b/osinaweb/osichat/admin.py index c5adceef..d8ffa8ea 100644 --- a/osinaweb/osichat/admin.py +++ b/osinaweb/osichat/admin.py @@ -3,6 +3,7 @@ from .models import * # Register your models here. admin.site.register(Visitor) admin.site.register(VisitorLog) +admin.site.register(ChatConnection) admin.site.register(ChatRoom) admin.site.register(ChatRoomGuest) admin.site.register(ChatMember) diff --git a/osinaweb/osichat/api/__pycache__/views.cpython-310.pyc b/osinaweb/osichat/api/__pycache__/views.cpython-310.pyc index e19c7c4f9bc7e53854daa32760bf33de15b052de..72b333d95aedcea6d0b4ba1dc8da4a391e9cbebf 100644 GIT binary patch delta 88 zcmeyZ+@ivp&&$ij00gcR|D`?L$h(-EF>dlkZWU#zTIL$&EY>VGFv$)kIe;W*7FP*3 hh}XG&&$ij00gCtztXO4D9od5s; diff --git a/osinaweb/osichat/api/views.py b/osinaweb/osichat/api/views.py index 66125306..b040b999 100644 --- a/osinaweb/osichat/api/views.py +++ b/osinaweb/osichat/api/views.py @@ -109,7 +109,7 @@ def get_staffs(request): "first_name": staff.user.first_name, "last_name": staff.user.last_name, "image": staff.image.url, - "last_seen": staff.get_last_seen + "last_seen": get_chat_last_seen(staff.user) } staffs_data.append(staff_data) diff --git a/osinaweb/osichat/consumers.py b/osinaweb/osichat/consumers.py index 3c709c6d..4ebeede2 100644 --- a/osinaweb/osichat/consumers.py +++ b/osinaweb/osichat/consumers.py @@ -8,6 +8,7 @@ from django.forms.models import model_to_dict from django.core.serializers.json import DjangoJSONEncoder from django.db.models import Case, When, F, Max, DateTimeField from django.db import transaction +import threading @@ -55,21 +56,39 @@ class OsitcomVisitor(WebsocketConsumer): - - class Osichat(WebsocketConsumer): def connect(self): self.user = self.scope["user"] + existing_connection = ChatConnection.objects.filter(user=self.user).last() + if existing_connection: + self.connection = existing_connection + self.connection.online = True + self.connection.disconnected = False + self.connection.save() + else: + self.connection = ChatConnection.objects.create(user=self.user, online=True) async_to_sync(self.channel_layer.group_add)( 'osichat', self.channel_name ) self.accept() def disconnect(self, close_code): + self.last_seen = datetime.now() + self.connection.disconnected = True + self.connection.save() + timer_thread = threading.Timer(3, self.check_disconnect_status) + timer_thread.start() async_to_sync(self.channel_layer.group_discard)( 'osichat', self.channel_name ) + def check_disconnect_status(self): + connection = ChatConnection.objects.filter(user=self.user).last() + if connection.disconnected: + self.connection.last_seen = self.last_seen + self.connection.online = False + self.connection.save() + def receive(self, text_data): data = json.loads(text_data) event_type = data.get('event_type') @@ -471,6 +490,16 @@ class OsitcomChatRoom(WebsocketConsumer): self.group, event ) + if event_type == 'recording': + event = { + 'type': 'recording_handler', + 'user_id': text_data_json.get('user_id'), + 'recording_status': text_data_json.get('recording_status') + } + async_to_sync(self.channel_layer.group_send)( + self.group, event + ) + if event_type == 'send_message': if text_data_json.get('user_id'): member = get_object_or_404(User, id=text_data_json.get('user_id')) @@ -764,6 +793,34 @@ class OsitcomChatRoom(WebsocketConsumer): })) + def recording_handler(self, event): + if event.get('recording_status') == 'recording': + if event.get('user_id'): + member = get_object_or_404(User, id=event.get('user_id')) + else: + member = None + + context = { + 'member': member, + 'chat_room': self.chat_room, + 'domain': self.domain + } + if self.client_type == 'mobile_admin': + member_data = None + if member: + member_data = model_to_dict(member) + member_data['image'] = member.staffprofile.image.url if member.staffprofile and member.staffprofile.image else None + self.send(text_data=json.dumps({ + 'event_type': 'recording', + 'member_data': member_data, + }, cls=DjangoJSONEncoder)) + + else: + self.send(text_data=json.dumps({ + 'event_type': 'stopped_recording', + })) + + def send_message_handler(self, event): chat_message = get_object_or_404(ChatMessage, id=event['chat_message_id']) context = { diff --git a/osinaweb/osichat/migrations/0033_chatconnection.py b/osinaweb/osichat/migrations/0033_chatconnection.py new file mode 100644 index 00000000..2da68df5 --- /dev/null +++ b/osinaweb/osichat/migrations/0033_chatconnection.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.5 on 2024-10-03 12:27 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('osichat', '0032_remove_chatnotification_users_chatnotification_user'), + ] + + operations = [ + migrations.CreateModel( + name='ChatConnection', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField(null=True)), + ('online', models.BooleanField(default=True)), + ('last_seen', models.DateTimeField(blank=True, null=True)), + ('disconnected', models.BooleanField(default=False)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/osinaweb/osichat/migrations/__pycache__/0033_chatconnection.cpython-310.pyc b/osinaweb/osichat/migrations/__pycache__/0033_chatconnection.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de4b7e707ba69de866edd012f79635850a1b6fa8 GIT binary patch literal 1125 zcmZuwO^?$^5Oud5$4Q(_U=b1=5T})*T}?)CK`Vq9lHo&Q7>Sv=_|od6E1@&(?yTEk zl)b_=H+}#dIq--2%89>##6Y#30S;@aTlK2SepRo^rrT`?_FL?DO?a*`3^ZK`M#>QH4X*$l@n~h(zOUAQ})Zns36aDZ=Am5P!kN|a}&*|NYK|oPisREwGpL=Iu%N{u}E|`6r;T=+So>S5Otxq*jcm| z{lyi}C;C2b9*Zj*Iw#pxaTR;}!?g}C8^Nxc#>(j{Ub=gGdw1`!0&?>jnD=N?%9)&2 z9kZ2%!v4S8^+uRIGFrpbtK+B?CyyO{HXcMS<*U-LX#uXGI_NcBznd zS{H(BkuMrET1GRR7L?#H1SM=67~fulCX-IG1q1cN4rvhcFNelE3SMpV+HP8 z;I7$ozFhJN#sw@v3((VbL49av|McW3J3T&l$qtXk2hXvX%M1zDbw-s2hkkDgzo#yJ zByEMM6PZH|(?`ZA;CdT8(r{w%s$nb^T+fZ8V&amjGcS8{w0}I>A0N23 zS;BTvKL*8L$W>im&xfaeibKey0#Hh>VK@eRR+{DT7zdHxe$JO399daTO+Lic(0r)j zyfSLi+IbEWZ}>GC{`xJ3xI%ZUCD{%E%i3M8iw2gE;IX$Vqa9KbT|_Y@*JzLQNFUEl zLcc~A$@eOEkho6Gwu>K{)%v!!9xx)ZipCsgZ_yfWH!o4rsboY*6cN}68%YqtRzwFA|OHXS#pm+Q_XVO?xxce>7K$Ru3?h5MBl6p9;gQWpD zCb!H*E=ph7YX+sp*H2oqzD2G|um3VvbjhE9o8qqc!ly1wsK1le=4JI9Ed2kVymOgSm$}t+T8xRUc8=%F9o_yO+t%9r*lb&+eK0@59WBtSZla8CL>7`kT?ATKqk=$~ zMzZQf`hcK_+3+Haml0SRQ5Tv91tndG+D(#l72QNh{e2&J?wx7RkIfr49qUI5zg4%^3ZKyX8q3fEB8lKgD0ZE?L9|BF>APP-$B z#N?guTWK!2Pj>qGp;JP(|tmhy4*(n|SJ6Tc)1?s7IjX|om`Y=FQYXR4&tMW3g^2f?%V3Z8sXXI$b*NwZB@=sub z*8Bxz>1H6H8nU66p9VBwl8W2LFhz%hDLm)lU=f(7w$LZMr;6|+EOIgY7Wl%M>N4Ov zkJPBZE6&v(0e;eI0NvbRg_LFAHV(!A1CdLY8~^|S diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 16337aab..cafdfbfd 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -13,6 +13,7 @@ from channels.layers import get_channel_layer from datetime import timedelta + # Create your models here. @@ -60,6 +61,7 @@ class CustomerProfile(models.Model): new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001' self.customer_id = current_year + new_id # Add 'p' prefix super(CustomerProfile, self).save(*args, **kwargs) + @property def get_last_seen(self): connection = Connection.objects.filter(user=self.user).last() @@ -78,7 +80,6 @@ class CustomerProfile(models.Model): return f"last seen yesterday at {last_seen_time.strftime('%I:%M %p')}" else: return f"last seen on {last_seen_time.strftime('%b %d at %I:%M %p')}" - @@ -149,6 +150,7 @@ class StaffProfile(models.Model): new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001' self.staff_id = 'O' + current_year + new_id # Add 'p' prefix super(StaffProfile, self).save(*args, **kwargs) + @property def get_last_seen(self): connection = Connection.objects.filter(user=self.user).last() @@ -167,10 +169,14 @@ class StaffProfile(models.Model): return f"last seen yesterday at {last_seen_time.strftime('%I:%M %p')}" else: return f"last seen on {last_seen_time.strftime('%b %d at %I:%M %p')}" + @property def active(self): return self.staffposition_set.filter(end_date__isnull=True).exists() + + + class StaffPosition(models.Model):