diff --git a/hknweb/candidate/admin/__init__.py b/hknweb/candidate/admin/__init__.py index de788281..2b170137 100644 --- a/hknweb/candidate/admin/__init__.py +++ b/hknweb/candidate/admin/__init__.py @@ -1,4 +1,5 @@ from hknweb.candidate.admin.announcement import AnnouncementAdmin from hknweb.candidate.admin.bitbyteactivity import BitByteActivityAdmin +from hknweb.candidate.admin.bit_byte_group import BitByteGroupAdmin from hknweb.candidate.admin.officer_challenge import OffChallengeAdmin from hknweb.candidate.admin.logistics import LogisticsAdmin diff --git a/hknweb/candidate/admin/bit_byte_group.py b/hknweb/candidate/admin/bit_byte_group.py new file mode 100644 index 00000000..3925dd11 --- /dev/null +++ b/hknweb/candidate/admin/bit_byte_group.py @@ -0,0 +1,101 @@ +from django.contrib import admin, messages +from django.shortcuts import render, redirect +from django.urls import path +from django.db import transaction +from django.contrib.auth.models import User + +import io +import csv +from hknweb.coursesemester.models import Semester +from hknweb.candidate.models import BitByteGroup +from hknweb.forms import CsvImportForm + + +@admin.register(BitByteGroup) +class BitByteGroupAdmin(admin.ModelAdmin): + change_list_template = "admin/candidate/bitbyte_group_change_list.html" + + fields = ["semester", "bytes", "bits"] + list_display = ( + "semester", + "bytes_usernames", + "bits_usernames", + ) + list_filter = ["semester"] + search_fields = [ + "bytes__username", + "bytes__first_name", + "bytes__last_name", + "bits__username", + "bits__first_name", + "bits__last_name", + ] + autocomplete_fields = ["bytes", "bits"] + + def bytes_usernames(self, obj): + return ", ".join([user.username for user in obj.bytes.all()]) + + def bits_usernames(self, obj): + return ", ".join([user.username for user in obj.bits.all()]) + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path("import-csv/", self.import_csv, name="import_csv"), + ] + return custom_urls + urls + + # Refactor and move this outside of admin panel if this becomes front facing feature(i.e. you + # want evp creating bitbyte groups) + def import_csv(self, request): + # Helper function. + def _get_user_or_error(username): + user = User.objects.filter(username__iexact=username).first() + if not user: + raise ValueError( + f"Error on trying to add '{username}'." + f" Check if the username is correct." + ) + return user + + if request.method == "POST": + form = CsvImportForm(request.POST, request.FILES) + if form.is_valid(): + csv_file = request.FILES["csv_file"] + data_set = csv_file.read().decode("UTF-8") + io_string = io.StringIO(data_set) + next(io_string) # Skip header + + try: + # If an error happens we just don't do anything + with transaction.atomic(): + count = 0 + for row in csv.reader(io_string, delimiter=";"): + if not row or len(row) != 4: + continue + + byte_usernames, bit_usernames, year, sem = [ + s.strip() for s in row + ] + + semester_obj = Semester.objects.get(year=year, semester=sem) + group = BitByteGroup.objects.create(semester=semester_obj) + for byte in byte_usernames.split(","): + byte_user = _get_user_or_error(byte) + group.bytes.add(byte_user) + + for bit in bit_usernames.split(","): + bit_user = _get_user_or_error(bit) + group.bits.add(bit_user) + + count += 1 + self.message_user( + request, f"Successfully imported {count} relationships." + ) + return redirect("..") + except Exception as e: + self.message_user(request, f"Error: {e}", level=messages.ERROR) + + form = CsvImportForm() + payload = {"form": form} + return render(request, "admin/candidate/bitbyte_group_csv_upload.html", payload) diff --git a/hknweb/candidate/migrations/0016_bitbytegroup.py b/hknweb/candidate/migrations/0016_bitbytegroup.py new file mode 100644 index 00000000..dccb213a --- /dev/null +++ b/hknweb/candidate/migrations/0016_bitbytegroup.py @@ -0,0 +1,58 @@ +# Generated by Django 4.2.17 on 2026-01-11 18:31 + +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), + ("coursesemester", "0002_auto_20210202_0225"), + ("candidate", "0015_logistics_mandatory_events"), + ] + + operations = [ + migrations.CreateModel( + name="BitByteGroup", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "bits", + models.ManyToManyField( + related_name="bitbyte_groups_as_bit", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "bytes", + models.ManyToManyField( + related_name="bitbyte_groups_as_byte", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "semester", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="bit_byte_groups", + to="coursesemester.semester", + ), + ), + ], + options={ + "verbose_name": "Bit Byte Group", + "verbose_name_plural": "Bit Byte Groups", + }, + ), + ] diff --git a/hknweb/candidate/models/__init__.py b/hknweb/candidate/models/__init__.py index c5289e9e..436c090a 100644 --- a/hknweb/candidate/models/__init__.py +++ b/hknweb/candidate/models/__init__.py @@ -1,4 +1,5 @@ from hknweb.candidate.models.bit_byte_activity import BitByteActivity +from hknweb.candidate.models.bit_byte_group import BitByteGroup from hknweb.candidate.models.officer_challenge import OffChallenge from hknweb.candidate.models.announcement import Announcement from hknweb.candidate.models.logistics import Logistics, EventReq, MiscReq, FormReq diff --git a/hknweb/candidate/models/bit_byte_group.py b/hknweb/candidate/models/bit_byte_group.py new file mode 100644 index 00000000..7ebd4e6f --- /dev/null +++ b/hknweb/candidate/models/bit_byte_group.py @@ -0,0 +1,32 @@ +from django.db import models + +from hknweb.coursesemester.models import Semester + + +class BitByteGroup(models.Model): + """ + Model for bit byte group. + Each bit byte group has a semester associated with it, if it is unknown the field is none. + """ + + class Meta: + verbose_name = "Bit Byte Group" + verbose_name_plural = "Bit Byte Groups" + + semester = models.ForeignKey( + Semester, + on_delete=models.CASCADE, + null=True, + blank=True, + related_name="bit_byte_groups", + ) + + bytes = models.ManyToManyField("auth.User", related_name="bitbyte_groups_as_byte") + bits = models.ManyToManyField("auth.User", related_name="bitbyte_groups_as_bit") + + def __str__(self): + return ( + f"Bit byte group {self.semester}; " + + f"Bytes: {', '.join([c.username for c in self.bytes.all()])}; " + + f"Bits: {', '.join([c.username for c in self.bits.all()])}" + ) diff --git a/hknweb/forms.py b/hknweb/forms.py index a50a8df6..70e4c514 100644 --- a/hknweb/forms.py +++ b/hknweb/forms.py @@ -267,3 +267,7 @@ def generate_password() -> str: # Save information for adding messages self.invalid_emails = invalid_emails + + +class CsvImportForm(forms.Form): + csv_file = forms.FileField(label="Select .csv file") diff --git a/hknweb/static/bit_byte_tree_data.csv b/hknweb/static/bit_byte_tree_data.csv deleted file mode 100644 index 9876aba6..00000000 --- a/hknweb/static/bit_byte_tree_data.csv +++ /dev/null @@ -1,1024 +0,0 @@ -byte,bit -mhwangc,austinapatel -mhwangc,henrymuller -mhwangc,bri25yu -mowen,austinapatel -mowen,henrymuller -mowen,bri25yu -adithyaj,williamaditama -adithyaj,nfigueira -adithyaj,katherineshu -sfarhat,jeffjohn3 -marancpalaniappan,jeffjohn3 -vishnu.iyer,ramihijab -srig,ramihijab -emilyw,conhuang -seanlin,conhuang -alex.eecs,kpzhu -catherine.who,kpzhu -anthony.ding,rithvik.chuppala -chevin_ken,rithvik.chuppala -ericwang,matthew_nevling -ericwang,dineshp -ericwang,bobotran -rdurrani,matthew_nevling -rdurrani,dineshp -rdurrani,bobotran -galen,benliao1 -galen,ruhangma -jack.wang,benliao1 -jack.wang,ruhangma -jameszhu,sarah -jameszhu,ashzhang -jameszhu,parthgupta -chungmin99,sarah -chungmin99,ashzhang -chungmin99,parthgupta -sean.obrien,zhang.andrew -sarah.sun,alberttang -sarah.sun,vidishgupta -lakabuli,alberttang -lakabuli,vidishgupta -anavmittal,nicholas.j.liu -kevinwang,nicholas.j.liu -william.hsu,yiliu77 -william.hsu,haolinz -leonxu,yiliu77 -leonxu,haolinz -naomi.sagan,kaitlynlee -naomi.sagan,amy.hung -alex.eecs,ethanguo -alex.eecs,mraheja -haolinz,ethanguo -haolinz,mraheja -anthony.ding,gilbertfeng -chevin_ken,gilbertfeng -kaitlynlee,drakelin -kaitlynlee,rohintangirala -nfigueira,drakelin -nfigueira,rohintangirala -srig,tarunamarnath -vidishgupta,tarunamarnath -alberttang,andrewzhang2001 -katherineshu,andrewzhang2001 -austinapatel,aganesh10 -austinapatel,jeffdeng -bri25yu,aganesh10 -bri25yu,jeffdeng -guor.lei,austinkao -kpzhu,anvitha -naomi.sagan,anvitha -stevenchen,linandrew -nicholas.j.liu,linandrew -amy.hung,christykoh -amy.hung,toddyu -sarah,christykoh -sarah,toddyu -william.hsu,nisha.p -william.hsu,evynmachi -william.hsu,rk2357 -graceluo,nisha.p -graceluo,evynmachi -graceluo,rk2357 -anavmittal,aatifjiwani -anavmittal,jameszp -jerrysong,aatifjiwani -jerrysong,jameszp -jack.wang,awang -galen,awang -ericwang,fredwang -rdurrani,fredwang -henrymuller,ochan2 -henrymuller,tthvar -dineshp,ochan2 -dineshp,tthvar -drakelin,nnlum -drakelin,bryanngo -drakelin,ananthrao -andrewzhang2001,nnlum -andrewzhang2001,bryanngo -andrewzhang2001,ananthrao -jack.wang,davidwlin -jack.wang,ryanhuntley23 -galen,davidwlin -galen,ryanhuntley23 -katherineshu,jasontao -katherineshu,dahliasaba -katherineshu,narang -katherineshu,kam.salahi2 -alberttang,jasontao -alberttang,dahliasaba -alberttang,narang -alberttang,kam.salahi2 -rohintangirala,adbhawal -rohintangirala,alvin.xu5745 -rohintangirala,raeriksson -tarunamarnath,adbhawal -tarunamarnath,alvin.xu5745 -tarunamarnath,raeriksson -jeffdeng,yutengli -jeffdeng,justquan -aganesh10,yutengli -aganesh10,justquan -vidishgupta,sbrahmbhatt1 -vidishgupta,ashwin.rammohan -vidishgupta,simonguozirui -vidishgupta,kylui -ramihijab,sbrahmbhatt1 -ramihijab,ashwin.rammohan -ramihijab,simonguozirui -ramihijab,kylui -amy.hung,sammaher1 -amy.hung,arbaaz.muslim -michael_perry,sammaher1 -michael_perry,arbaaz.muslim -conhuang,naasirfarooqi -jeffjohn3,naasirfarooqi -alex.eecs,shawnak -chungmin99,shawnak -tthvar,suryarajan -parthgupta,suryarajan -toddyu,schel337 -mraheja,schel337 -jeffrey.y.liu,reinaw1012 -hermish,reinaw1012 -naomi.sagan,bwang0536 -bri25yu,bwang0536 -anvitha,srisainachuri -anvitha,ath -anvitha,aliciawang -anvitha,jermxt -danny,srisainachuri -danny,ath -danny,aliciawang -danny,jermxt -jerrysong,vshakib -jerrysong,vincentwang -jerrysong,dhasteer -jerrysong,anitaliu -jerrysong,wesley.cheng -nnlum,vshakib -nnlum,vincentwang -nnlum,dhasteer -nnlum,anitaliu -nnlum,wesley.cheng -ath,vshakib -ath,vincentwang -ath,dhasteer -ath,anitaliu -ath,wesley.cheng -kylui,ashwinrastogi -kylui,allengu01 -kylui,inferee -jack.wang,ashwinrastogi -jack.wang,allengu01 -jack.wang,inferee -sbrahmbhatt1,zoltantakahiro -sbrahmbhatt1,safi -sbrahmbhatt1,ram.m.kripa -aliciawang,catherinehwu -aliciawang,sugu -aliciawang,vinnyz -reinaw1012,catherinehwu -reinaw1012,sugu -reinaw1012,vinnyz -graceluo,crystal.chang -jeffdeng,raghavg13 -jeffdeng,anson.tiong -aganesh10,raghavg13 -aganesh10,anson.tiong -danny,fliu -danny,kyuen -danny,bbqiu -danny,shivana -sammaher1,fliu -sammaher1,kyuen -sammaher1,bbqiu -sammaher1,shivana -parthgupta,siddharthganesan -srisainachuri,siddharthganesan -bri25yu,alanzhu39 -bri25yu,alew2161 -bri25yu,sberkun -bri25yu,amaltsev -alvin.xu5745,alanzhu39 -alvin.xu5745,alew2161 -alvin.xu5745,sberkun -alvin.xu5745,amaltsev -galen,keatonelvins -galen,anishk -galen,awang -galen,rsmcconnell -jasontao,keatonelvins -jasontao,anishk -jasontao,awang -jasontao,rsmcconnell -naomi.sagan,pranshubansal -naomi.sagan,lelzeiny -naomi.sagan,sallypeng00 -michael_perry,pranshubansal -michael_perry,lelzeiny -michael_perry,sallypeng00 -vidishgupta,saltyminty -vidishgupta,josephjin -lakabuli,licolz -lakabuli,valleyjoe -lakabuli,gauravrghosal -alex.eecs,licolz -alex.eecs,valleyjoe -alex.eecs,gauravrghosal -tarunamarnath,eustyn_trinh -tarunamarnath,abhiganesh -tarunamarnath,anixsarkar -raeriksson,eustyn_trinh -raeriksson,abhiganesh -raeriksson,anixsarkar -anvitha,jmindel -anvitha,akhanwale -anvitha,erijung -anvitha,shivamsinghal -ryanhuntley23,jmindel -ryanhuntley23,akhanwale -ryanhuntley23,erijung -ryanhuntley23,shivamsinghal -andrewzhang2001,willchp -andrewzhang2001,aeron -andrewzhang2001,ajayvellayapan -drakelin,willchp -drakelin,aeron -drakelin,ajayvellayapan -anixsarkar,aliciamatsumoto -anixsarkar,haileyswpa -anixsarkar,richeldhaliwal -licolz,aliciamatsumoto -licolz,haileyswpa -licolz,richeldhaliwal -aganesh10,mrunali -aganesh10,suannho -aganesh10,vinaykanigicherla -aganesh10,maanav -jeffdeng,mrunali -jeffdeng,suannho -jeffdeng,vinaykanigicherla -jeffdeng,maanav -valleyjoe,yt_z10 -valleyjoe,fgeng -valleyjoe,gmitnick -lelzeiny,yt_z10 -lelzeiny,fgeng -lelzeiny,gmitnick -raghavg13,tinnaliu -raghavg13,leecolette -raghavg13,kelly_liu -anson.tiong,tinnaliu -anson.tiong,leecolette -anson.tiong,kelly_liu -drakelin,hanlinsun -drakelin,jyxzhang -andrewzhang2001,hanlinsun -andrewzhang2001,jyxzhang -sbrahmbhatt1,omaryu -sbrahmbhatt1,raymondmo -sbrahmbhatt1,shamus -sbrahmbhatt1,addikala -sbrahmbhatt1,lo-maxwell -rithvik.chuppala,joshua6261 -rithvik.chuppala,kathangandhi -rithvik.chuppala,lyin19 -rithvik.chuppala,jakebringetto -sugu,joshua6261 -sugu,kathangandhi -sugu,lyin19 -sugu,jakebringetto -ashwinrastogi,yousefh -ashwinrastogi,monishwaran -ashwinrastogi,smoolji -ashwinrastogi,aarush.aitha -kylui,yousefh -kylui,monishwaran -kylui,smoolji -kylui,aarush.aitha -ajayvellayapan,rt0110 -ajayvellayapan,mitchellzhen -ajayvellayapan,christopherchou -sammaher1,rt0110 -sammaher1,mitchellzhen -sammaher1,christopherchou -anvitha,sonali25 -anvitha,zengstellas -anvitha,timothyg24 -erijung,sonali25 -erijung,zengstellas -erijung,timothyg24 -ochan2,amoghgupta -ochan2,michael.wu1 -ochan2,dan.cooper -suryarajan,amoghgupta -suryarajan,michael.wu1 -suryarajan,dan.cooper -tarunamarnath,seenum -tarunamarnath,ayushgupta -tarunamarnath,kdharmarajan -tarunamarnath,saamahme -akhanwale,seenum -akhanwale,ayushgupta -akhanwale,kdharmarajan -akhanwale,saamahme -toddyu,mirandatao -toddyu,zwu -dhasteer,mirandatao -dhasteer,zwu -galen,fu.aaron -galen,abrashid -galen,sanchez -galen,kevinxpshi -galen,bryanli0 -bryanngo,fu.aaron -bryanngo,abrashid -bryanngo,sanchez -bryanngo,kevinxpshi -bryanngo,bryanli0 -bri25yu,jessiejuheehong -bri25yu,veenau -bri25yu,rohaga -amaltsev,jessiejuheehong -amaltsev,veenau -amaltsev,rohaga -vincentwang,kishoresrinivas -vincentwang,jonguo6 -vincentwang,eygao -willchp,kishoresrinivas -willchp,jonguo6 -willchp,eygao -jeffdeng,edwinlim -jeffdeng,arnzchen -jeffdeng,alson -aganesh10,edwinlim -aganesh10,arnzchen -aganesh10,alson -andrewzhang2001,alexfung -andrewzhang2001,vikasu -andrewzhang2001,kanavmittal -drakelin,alexfung -drakelin,vikasu -drakelin,kanavmittal -richeldhaliwal,milesturin -richeldhaliwal,careff -lelzeiny,milesturin -lelzeiny,careff -michael.wu1,tonyxin -kevinxpshi,tonyxin -vidishgupta,aqyzhang -vidishgupta,rachelxin -vidishgupta,mihai.tudor -katherineshu,aqyzhang -katherineshu,rachelxin -katherineshu,mihai.tudor -naasirfarooqi,shaylandias -naasirfarooqi,aryangoyal -toddyu,shaylandias -toddyu,aryangoyal -parthgupta,ymmohnot -parthgupta,oliveryu -parthgupta,eric.li2 -srisainachuri,ymmohnot -srisainachuri,oliveryu -srisainachuri,eric.li2 -simonguozirui,ashwatc -simonguozirui,fogel -rohintangirala,ashwatc -rohintangirala,fogel -aliciamatsumoto,vivianwuc25 -aliciamatsumoto,jessica.young -aliciamatsumoto,mishawu -anvitha,vivianwuc25 -anvitha,jessica.young -anvitha,mishawu -shamus,billybao -shamus,shzhao -shamus,alexanderdi -omaryu,billybao -omaryu,shzhao -omaryu,alexanderdi -saltyminty,jmni -saltyminty,r.hu -aeron,jmni -aeron,r.hu -anson.tiong,noppaponnc -anson.tiong,ncograin -raghavg13,noppaponnc -raghavg13,ncograin -haileyswpa,jennifertoy -haileyswpa,alyssau -haileyswpa,gtx -zwu,jennifertoy -zwu,alyssau -zwu,gtx -anixsarkar,nmahini -anixsarkar,rqchao -anixsarkar,xzrderek -saamahme,nmahini -saamahme,rqchao -saamahme,xzrderek -veenau,iborkovic -veenau,snayyar -veenau,erankohen -ashwinrastogi,iborkovic -ashwinrastogi,snayyar -ashwinrastogi,erankohen -tarunamarnath,junhak -tarunamarnath,siakmun -tarunamarnath,kaushalkarpuram -vincentwang,junhak -vincentwang,siakmun -vincentwang,kaushalkarpuram -amaltsev,rahularya -amaltsev,estseng -amaltsev,daniel.endraws -bri25yu,rahularya -bri25yu,estseng -bri25yu,daniel.endraws -sanchez,mehar_samra -sanchez,mahit -dhasteer,mehar_samra -dhasteer,mahit -sammaher1,migueltenant -bryanngo,colbychang -bryanngo,adamgoldstein -bryanngo,kwkw -raymondmo,colbychang -raymondmo,adamgoldstein -raymondmo,kwkw -ochan2,kennethwang -ochan2,jyou12 -ochan2,kathan -josephjin,kennethwang -josephjin,jyou12 -josephjin,kathan -shivana,reyanlee -kathangandhi,reyanlee -zwu,himakolavennu -zwu,rdang -zwu,adrianwei -andrewzhang2001,himakolavennu -andrewzhang2001,rdang -andrewzhang2001,adrianwei -aliciamatsumoto,nandiniagarwal -aliciamatsumoto,lydiaignatova -aliciamatsumoto,daniel_chang -aliciamatsumoto,bill.cy.zheng -anvitha,nandiniagarwal -anvitha,lydiaignatova -anvitha,daniel_chang -anvitha,bill.cy.zheng -saamahme,kdurani -saamahme,rishi.madala -saamahme,harivall -anixsarkar,kdurani -anixsarkar,rishi.madala -anixsarkar,harivall -tarunamarnath,kdurani -tarunamarnath,rishi.madala -tarunamarnath,harivall -alexfung,pranavsukumar -alexfung,hsw1018 -alexfung,bhatsavit -dhasteer,pranavsukumar -dhasteer,hsw1018 -dhasteer,bhatsavit -zoltantakahiro,rmei -zoltantakahiro,ndurvasula -zoltantakahiro,olafbrah -zoltantakahiro,jonahmt -amaltsev,rmei -amaltsev,ndurvasula -amaltsev,olafbrah -amaltsev,jonahmt -mihai.tudor,brentfriedman725 -junhak,brentfriedman725 -ath,kge -ath,nmacasaet1003 -ath,jinwei -akhanwale,kge -akhanwale,nmacasaet1003 -akhanwale,jinwei -jeffdeng,aeroanish -jeffdeng,aaronguo -jeffdeng,pgasawa -aganesh10,aeroanish -aganesh10,aaronguo -aganesh10,pgasawa -reyanlee,selene.huang -reyanlee,jenniferyin -reyanlee,jasonding -reyanlee,williamding -mishawu,selene.huang -mishawu,jenniferyin -mishawu,jasonding -mishawu,williamding -saltyminty,jfwang983 -saltyminty,gurvirkooner -aeron,jfwang983 -aeron,gurvirkooner -toddyu,luis.cermeno -toddyu,seungwoo415 -toddyu,nzxyin -naasirfarooqi,luis.cermeno -naasirfarooqi,seungwoo415 -naasirfarooqi,nzxyin -arengarajan,wgiorza -arengarajan,rcottone -bryanngo,wgiorza -bryanngo,rcottone -gilbertfeng,kevinsyee -gilbertfeng,baoer -josephjin,kevinsyee -josephjin,baoer -jmni,dvaish -jmni,edwardneo -kanavmittal,tanishk.v -kanavmittal,parth.behani -kanavmittal,thienle1942 -alexanderdi,tanishk.v -alexanderdi,parth.behani -alexanderdi,thienle1942 -willchp,lucassosa -willchp,raiyanrizwan -erankohen,lucassosa -erankohen,raiyanrizwan -veenau,adymchenko -veenau,jessica.jx.lin -veenau,msaaraswat -iborkovic,adymchenko -iborkovic,jessica.jx.lin -iborkovic,msaaraswat -vivianwuc25,jolenehuey -vivianwuc25,heather.ding -vivianwuc25,rishi.nath -vivianwuc25,quangnguyenln -richeldhaliwal,jolenehuey -richeldhaliwal,heather.ding -richeldhaliwal,rishi.nath -richeldhaliwal,quangnguyenln -amoghgupta,kamal.nahas -amoghgupta,hgn -amoghgupta,varunbharadwaj -amoghgupta,arda.akman -jakebringetto,kamal.nahas -jakebringetto,hgn -jakebringetto,varunbharadwaj -jakebringetto,arda.akman -sanchez,owent -sanchez,rhalameddine -sanchez,jaehayi -sanchez,franzkieviet -anson.tiong,owent -anson.tiong,rhalameddine -anson.tiong,jaehayi -anson.tiong,franzkieviet -lelzeiny,ayushi.batwara -lelzeiny,suhanisinghal04 -sonali25,ayushi.batwara -sonali25,suhanisinghal04 -addikala,tekotan -addikala,aayush.gupta -vincentwang,tekotan -vincentwang,aayush.gupta -arengarajan,leejeewoo -arengarajan,krishchat -r.hu,leejeewoo -r.hu,krishchat -aliciamatsumoto,tamih -aliciamatsumoto,garrettmoore -aliciamatsumoto,dbibikar -anvitha,tamih -anvitha,garrettmoore -anvitha,dbibikar -veenau,prabhask -veenau,divyaramesh -veenau,dmurugan2026 -richeldhaliwal,prabhask -richeldhaliwal,divyaramesh -richeldhaliwal,dmurugan2026 -alexfung,iamwangyuanxiu -alexfung,zhang.andrew -kathangandhi,iamwangyuanxiu -kathangandhi,zhang.andrew -hsw1018,iamwangyuanxiu -hsw1018,zhang.andrew -haileyswpa,jiayang.wang -haileyswpa,ni -zwu,jiayang.wang -zwu,ni -mihai.tudor,runjeetnarula -mihai.tudor,dselimot -mihai.tudor,saarnav -junhak,runjeetnarula -junhak,dselimot -junhak,saarnav -ath,timothydknguyen -ath,jasmine.zhang -ath,sanjay.chintapally -akhanwale,timothydknguyen -akhanwale,jasmine.zhang -akhanwale,sanjay.chintapally -jeffdeng,prestonfu -jeffdeng,dstalcup -aganesh10,prestonfu -aganesh10,dstalcup -reyanlee,grace.tang -reyanlee,justin0404 -reyanlee,aryanshs -alyssau,grace.tang -alyssau,justin0404 -alyssau,aryanshs -suhanisinghal04,shethhriday29 -suhanisinghal04,jkorr -suhanisinghal04,ria.jain -himakolavennu,shethhriday29 -himakolavennu,jkorr -himakolavennu,ria.jain -toddyu,annadawes -toddyu,parham-sharaf -toddyu,ansa -toddyu,kojiro -dhasteer,annadawes -dhasteer,parham-sharaf -dhasteer,ansa -dhasteer,kojiro -jinwei,michael.wiradharma -jinwei,yajatyadav -jinwei,patmendoza6745 -jinwei,phillipe10042003 -nmacasaet1003,michael.wiradharma -nmacasaet1003,yajatyadav -nmacasaet1003,patmendoza6745 -nmacasaet1003,phillipe10042003 -franzkieviet,alexchen1 -franzkieviet,ckeokot -franzkieviet,michelle.taeeun -jenniferyin,alexchen1 -jenniferyin,ckeokot -jenniferyin,michelle.taeeun -shivana,swetha.rajkumar -shivana,daniel_chang -sonali25,swetha.rajkumar -sonali25,daniel_chang -shzhao,wid4soe -shzhao,changjaewon0315 -shzhao,echang09 -jyxzhang,wid4soe -jyxzhang,changjaewon0315 -jyxzhang,echang09 -tarunamarnath,anjopag -tarunamarnath,ncarpenedo -tarunamarnath,jirieskaileh -saamahme,anjopag -saamahme,ncarpenedo -saamahme,jirieskaileh -olafbrah,ouwilliam -olafbrah,jaimyndrake -jfwang983,ouwilliam -jfwang983,jaimyndrake -erankohen,jboondicharern -erankohen,shai.dickman -erankohen,jerliang7 -sanchez,jboondicharern -sanchez,shai.dickman -sanchez,jerliang7 -lydiaignatova,yash_totale -lydiaignatova,anyaraju -lydiaignatova,sfarooqi -naasirfarooqi,yash_totale -naasirfarooqi,anyaraju -naasirfarooqi,sfarooqi -vincentwang,brandoncjw_25 -vincentwang,aldenlau -vincentwang,mannymnz -varunbharadwaj,brandoncjw_25 -varunbharadwaj,aldenlau -varunbharadwaj,mannymnz -rohaga,aakarshv -rohaga,lce -rohaga,chandna -amaltsev,aakarshv -amaltsev,lce -amaltsev,chandna -williamding,erikkizior -williamding,venkata.alapati -williamding,dhruvagarwal -adrianwei,erikkizior -adrianwei,venkata.alapati -adrianwei,dhruvagarwal -tekotan,kkodnad -tekotan,raghavpu -tekotan,aarushdas -raiyanrizwan,kkodnad -raiyanrizwan,raghavpu -raiyanrizwan,aarushdas -bryanngo,nithid -bryanngo,madharmawan -bryanngo,sselvan -erijung,nithid -erijung,madharmawan -erijung,sselvan -saltyminty,jonahbedouch -saltyminty,nikhiljha -aeron,jonahbedouch -aeron,nikhiljha -quangnguyenln,schilamkur -quangnguyenln,aaronhao -quangnguyenln,william.tang -jonahmt,schilamkur -jonahmt,aaronhao -jonahmt,william.tang -haileyswpa,veronicacheung -haileyswpa,malia.kowal -haileyswpa,ashmita.kumar -haileyswpa,amukh946 -haileyswpa,shreya.bhandari -zwu,veronicacheung -zwu,malia.kowal -zwu,ashmita.kumar -zwu,amukh946 -zwu,shreya.bhandari -anixsarkar,anshul.verma -anixsarkar,aabraham -anixsarkar,yash.aggarwal -anixsarkar,marco.w.monfiglio -tarunamarnath,anshul.verma -tarunamarnath,aabraham -tarunamarnath,yash.aggarwal -tarunamarnath,marco.w.monfiglio -bill.cy.zheng,dillonsemin -bill.cy.zheng,zheng.michael -nzxyin,dillonsemin -nzxyin,zheng.michael -aaronguo,andrewji -aaronguo,ralph_cow -prestonfu,andrewji -prestonfu,ralph_cow -jenniferyin,allison23liu -jenniferyin,rachel.xiao -jenniferyin,eren.saglam -jenniferyin,shinggao -franzkieviet,allison23liu -franzkieviet,rachel.xiao -franzkieviet,eren.saglam -franzkieviet,shinggao -ashwatc,wolfedholm -ashwatc,adityatomar -ashwatc,alenachao -ashwatc,y.rao -ath,wolfedholm -ath,adityatomar -ath,alenachao -ath,y.rao -akhanwale,pbales1 -akhanwale,camillexdang -akhanwale,haoze_tang -akhanwale,apollo.loh -vivianwuc25,pbales1 -vivianwuc25,camillexdang -vivianwuc25,haoze_tang -vivianwuc25,apollo.loh -himakolavennu,mtsao -himakolavennu,artem.shumay -himakolavennu,cjmc7e -annadawes,mtsao -annadawes,artem.shumay -annadawes,cjmc7e -quangnguyenln,maxmwang -quangnguyenln,adalal542 -quangnguyenln,mike.martinez -quangnguyenln,michaeleugeneng -jonahmt,maxmwang -jonahmt,adalal542 -jonahmt,mike.martinez -jonahmt,michaeleugeneng -shzhao,trazzaque -shzhao,syeon-um -shzhao,sasmit -jyxzhang,trazzaque -jyxzhang,syeon-um -jyxzhang,sasmit -jonahbedouch,lucapoulos -jonahbedouch,aderouen -jonahbedouch,jwt4517 -saltyminty,isabellehsu -aeron,isabellehsu -reyanlee,mdhekial -reyanlee,anokhi -reyanlee,marvinlin -michelle.taeeun,mdhekial -michelle.taeeun,anokhi -michelle.taeeun,marvinlin -nithid,brandonwong14 -nithid,matthewgerardi -nithid,benjaminkarish04 -ckeokot,brandonwong14 -ckeokot,matthewgerardi -ckeokot,benjaminkarish04 -jerliang7,darren.ho -jerliang7,dannylam -jerliang7,achaurasia -venkata.alapati,darren.ho -venkata.alapati,dannylam -venkata.alapati,achaurasia -mannymnz,owen2608 -mannymnz,advayratan -yash_totale,owen2608 -yash_totale,advayratan -william.tang,andychen2121 -william.tang,jamesoncrate -william.tang,henryqi -william.tang,lyndonyang2005 -aaronhao,andychen2121 -aaronhao,jamesoncrate -aaronhao,henryqi -aaronhao,lyndonyang2005 -bryanngo,kranganathan -bryanngo,jjasmine -anvitha,kranganathan -anvitha,jjasmine -varunbharadwaj,andrew_song -varunbharadwaj,sshashi -varunbharadwaj,ericho -varunbharadwaj,n10dollar -tekotan,andrew_song -tekotan,sshashi -tekotan,ericho -tekotan,n10dollar -jakebringetto,silas.taylor -jakebringetto,alanb -jonahbedouch,gururajesh -lydiaignatova,isakt -akhanwale,isakt -zwu,kmeng -zwu,hiyashah -haileyswpa,kmeng -haileyswpa,hiyashah -reyanlee,bsong27 -reyanlee,jfchen29 -reyanlee,jwhur38 -vivianwuc25,bsong27 -vivianwuc25,jfchen29 -vivianwuc25,jwhur38 -hgn,joshualu -hgn,sajnanidev -kwkw,joshualu -kwkw,sajnanidev -franzkieviet,sriyakalyan -franzkieviet,devajgupta -jenniferyin,sriyakalyan -jenniferyin,devajgupta -nmacasaet1003,dsinger -nmacasaet1003,jamesonliu -nmacasaet1003,danielchen1009 -jinwei,dsinger -jinwei,jamesonliu -jinwei,danielchen1009 -shzhao,jphung -bryanli0,jphung -anixsarkar,saarthgao -anixsarkar,zoghby.marc -tarunamarnath,saarthgao -tarunamarnath,zoghby.marc -jkorr,sjprasad -jkorr,kabirshah -jkorr,abaner -aabraham,sjprasad -aabraham,kabirshah -aabraham,abaner -saltyminty,lauethan -saltyminty,tbagri -aeron,lauethan -aeron,tbagri -nithid,jaewon.lee -nithid,liamcnewsam -anokhi,x7 -anokhi,pranav.perumandla -amukh946,x7 -amukh946,pranav.perumandla -michelle.taeeun,marieanne.xu -michelle.taeeun,christyhuang -michelle.taeeun,asujithan -mdhekial,marieanne.xu -mdhekial,christyhuang -mdhekial,asujithan -tekotan,jason_lee -tekotan,raiyanausaf14 -varunbharadwaj,zachary.mcmullan -varunbharadwaj,yixuanqiao -michael.wu1,zachary.mcmullan -michael.wu1,yixuanqiao -jonahmt,robertrzhang -jonahmt,jiajunyu -william.tang,robertrzhang -william.tang,jiajunyu -jyxzhang,jorditedja -timothydknguyen,jorditedja -lucapoulos,luca.manolache -lucapoulos,cameronjordan -jerliang7,luca.manolache -jerliang7,cameronjordan -echang09,colangdon -echang09,kellytou -bryanngo,colangdon -bryanngo,kellytou -prestonfu,kenzhengjk -prestonfu,gyang276 -prestonfu,yifan.wang65535 -swetha.rajkumar,kenzhengjk -swetha.rajkumar,gyang276 -swetha.rajkumar,yifan.wang65535 -marco.w.monfiglio,apawar -marco.w.monfiglio,nicorakela -marco.w.monfiglio,ehharrison -jonahbedouch,kylehuo -gyang276,rylee4761 -gyang276,jiajunyu -x7,rylee4761 -x7,jiajunyu -sriyakalyan,yiyinqi -sriyakalyan,smuppalla06 -jfchen29,yiyinqi -jfchen29,smuppalla06 -tekotan,vivekputta -tekotan,jeremymills -tekotan,divij_muthu -ericho,vivekputta -ericho,jeremymills -ericho,divij_muthu -hgn,jermainelei -hgn,p.pandey -hgn,kinjal_govil -hgn,ishirgarg -varunbharadwaj,jermainelei -varunbharadwaj,p.pandey -varunbharadwaj,kinjal_govil -varunbharadwaj,ishirgarg -timothydknguyen,asingh28 -timothydknguyen,jessicafan -kwkw,asingh28 -kwkw,jessicafan -kmeng,nidhya -kmeng,yf328 -sajnanidev,nidhya -sajnanidev,yf328 -wolfedholm,huijae.an -wolfedholm,sriram.srivatsan -wolfedholm,hershraj -wolfedholm,maxphillips -sjprasad,huijae.an -sjprasad,sriram.srivatsan -sjprasad,hershraj -sjprasad,maxphillips -patmendoza6745,ksalahi -patmendoza6745,sgoudarzi -patmendoza6745,kuljit -kennethllontop,ksalahi -kennethllontop,sgoudarzi -kennethllontop,kuljit -jkorr,codywang -jkorr,jeremykang -aabraham,codywang -aabraham,jeremykang -vivianwuc25,robertian23 -vivianwuc25,jwang7041 -vivianwuc25,rsha256 -vivianwuc25,25woochulk -jessica.jx.lin,robertian23 -jessica.jx.lin,jwang7041 -jessica.jx.lin,rsha256 -jessica.jx.lin,25woochulk -marieanne.xu,aditijain -marieanne.xu,skylarq -colangdon,aditijain -colangdon,skylarq -jonahmt,vihaanm -jonahmt,pro -jonahmt,ashbardh -anixsarkar,vihaanm -anixsarkar,pro -anixsarkar,ashbardh -jaewon.lee,amy.yao -jaewon.lee,raymondzhu -jaewon.lee,eric_khodorenko -shinggao,amy.yao -shinggao,raymondzhu -shinggao,eric_khodorenko -christyhuang,jeffreygong -christyhuang,aditimundra -christyhuang,dylana2z05 -michelle.taeeun,jeffreygong -michelle.taeeun,aditimundra -michelle.taeeun,dylana2z05 -zachary.mcmullan,pravinrajah -zachary.mcmullan,aaronz -zachary.mcmullan,anishs -isakt,pravinrajah -isakt,aaronz -isakt,anishs -hsw1018,ryantrinh05 -hsw1018,starbuck diff --git a/hknweb/templates/admin/candidate/bitbyte_group_change_list.html b/hknweb/templates/admin/candidate/bitbyte_group_change_list.html new file mode 100644 index 00000000..0896e0a7 --- /dev/null +++ b/hknweb/templates/admin/candidate/bitbyte_group_change_list.html @@ -0,0 +1,12 @@ +{% extends "admin/change_list.html" %} +{% load i18n admin_urls %} + +{% block object-tools-items %} + {# This button only shows up on the BitByteGroup list page #} +
  • + + {% trans "Import BitByte CSV" %} + +
  • + {{ block.super }} +{% endblock %} \ No newline at end of file diff --git a/hknweb/templates/admin/candidate/bitbyte_group_csv_upload.html b/hknweb/templates/admin/candidate/bitbyte_group_csv_upload.html new file mode 100644 index 00000000..d1811684 --- /dev/null +++ b/hknweb/templates/admin/candidate/bitbyte_group_csv_upload.html @@ -0,0 +1,11 @@ +{% extends "admin/base_site.html" %} + +{% block content %} + +
    + {% csrf_token %} + {{ form.as_p }} + +
    + +{% endblock %} diff --git a/hknweb/views/bitbyte_tree.py b/hknweb/views/bitbyte_tree.py index ac8c8811..0ab9f5b1 100644 --- a/hknweb/views/bitbyte_tree.py +++ b/hknweb/views/bitbyte_tree.py @@ -1,42 +1,45 @@ from django.shortcuts import render -from hknweb.utils import allow_public_access +from hknweb.candidate.models import BitByteGroup +from hknweb.utils import allow_public_access, login_and_committee +from django.conf import settings from django.http import JsonResponse from django.contrib.auth.models import User -# TODO: dont read from the file when actual model and backend for bitbyte groups exists. +@login_and_committee(settings.COMPSERV_GROUP) +def update_bitbyte_tree(request): + return + + @allow_public_access def bitbyte_tree_data(request): - byte_bits = {} - data = {"nodes": [], "links": []} - all_bytes = [] - with open("hknweb/static/bit_byte_tree_data.csv", "r") as f: - lines = f.readlines()[1::] - for line in lines: - line = line.strip() - if line.split(",")[0] not in all_bytes: - all_bytes.append(line.split(",")[0]) - if line.split(",")[1] not in all_bytes: - all_bytes.append(line.split(",")[1]) - - if not byte_bits.get(line.split(",")[0], False): - byte_bits[line.split(",")[0]] = [] - byte_bits[line.split(",")[0]].append(line.split(",")[1]) - - for byte in all_bytes: - user = User.objects.get(username__iexact=byte) - data["nodes"].append( - { - "id": byte, - "name": user.first_name + " " + user.last_name, - "candidate_semester": user.date_joined.year, - } - ) - - for byte in byte_bits: - for bit in byte_bits[byte]: - data["links"].append({"source": byte, "target": bit}) + groups = BitByteGroup.objects.prefetch_related("bits", "bytes").all() + + username_to_node = {} + links = [] + + for group in groups: + group_bytes = group.bytes.all() + group_bits = group.bits.all() + + def add_to_nodes(user_list): + for user in user_list: + if user.username not in username_to_node: + username_to_node[user.username] = { + "id": user.username, + "name": f"{user.first_name} {user.last_name}", + "candidate_semester": user.date_joined.year, + } + + add_to_nodes(group_bytes) + add_to_nodes(group_bits) + + for byte in group_bytes: + for bit in group_bits: + links.append({"source": byte.username, "target": bit.username}) + + data = {"nodes": list(username_to_node.values()), "links": links} return JsonResponse(data)