File size: 88,573 Bytes
e7f7004 ce26fdd e7f7004 bd0122a e7f7004 ce26fdd e7f7004 ce26fdd e7f7004 0ff5b4f e7f7004 ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f e7f7004 ce26fdd 0ff5b4f ce26fdd e7f7004 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd e7f7004 ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f e7f7004 0ff5b4f e7f7004 ce26fdd 0ff5b4f bd0122a 48ec3d4 bd0122a 48ec3d4 bd0122a 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f e7f7004 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd e7f7004 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f ce26fdd 0ff5b4f e7f7004 0ff5b4f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 |
import os
import gradio as gr
import pandas as pd
import numpy as np
import random
import datetime
import uuid
import json
import io # For BytesIO
from huggingface_hub import HfApi, create_repo, HfFileSystem
from datasets import Dataset # Still useful for potential future aggregation
import soundfile as sf
import shutil
import traceback # For detailed error logging
# --- Configuration ---
SAMPLE_PROMPTS = [
# --- Greetings and Introductions ---
"नमस्ते, मेरो नाम __ हो। म नेपाली बोल्छु।",
"शुभ प्रभात! तपाईंलाई कस्तो छ?",
"शुभ रात्री, राम्रोसँग सुत्नुहोस्।",
"मेरो परिवारमा चार जना छन्: बुबा, आमा, दाइ र म।",
"तपाईं कहाँबाट हुनुहुन्छ? म काठमाडौंबाट हुँ।",
"म बिरामी छु, कृपया मलाई सहयोग गर्नुहोस्।",
"तपाईंसँग भेटेर खुसी लाग्यो।",
"मेरो घर पोखरामा छ।",
"के म तपाईंको नाम जान्न सक्छु?",
"उहाँ मेरो मिल्ने साथी हुनुहुन्छ।",
# --- Weather and Nature ---
"आज मौसम धेरै राम्रो र घमाइलो छ।",
"आज बिहानदेखि भारी वर्षा भइरहेको छ।",
"उफ! यो हावाले कति चिसो बनाएको!",
"हिजो राति तराईमा बाक्लो हुस्सु लागेको थियो।",
"सुन्दर मौसममा हरियो डाँडाकाँडा घुम्न जान मन लाग्छ।",
"आकाशमा इन्द्रेणी देखिएको छ।",
"भोलिको मौसम पूर्वानुमान कस्तो छ?",
"रुखहरूमा नयाँ पालुवा पलाएको छ।",
"पहाडबाट झरना बगिरहेको हेर्न कति रमाइलो!",
"समुद्र किनारमा हिँड्न मलाई मन पर्छ।", # (Though Nepal is landlocked, for general ASR)
# --- Places and Travel ---
"नेपाल हिमाल, पहाड र तराईले बनेको एक सुन्दर देश हो।",
"काठमाडौं नेपालको ऐतिहासिक र सांस्कृतिक राजधानी हो।",
"पोखरा फेवातालको मनमोहक किनारमा अवस्थित छ।",
"चितवन राष्ट्रिय निकुञ्जमा दुर्लभ एक सिंगे गैंडा र पाटे बाघ हेर्न पाइन्छ।",
"लुम्बिनी भगवान गौतम बुद्धको पवित्र जन्मस्थल हो।",
"सगरमाथा आरोहण गर्न कति खर्च लाग्छ होला?",
"म अर्को महिना मुक्तिनाथ दर्शन गर्न जाँदैछु।",
"नेपालमा धेरै आकर्षक पर्यटकीय गन्तव्यहरू छन्।",
"यहाँबाट सबैभन्दा नजिकको होटल कुन हो?",
"बसको टिकट कहाँ किन्न पाइन्छ?",
# --- Daily Activities ---
"म आज बिहान छिट्टै उठेँ र स्कूल जाँदैछु।",
"म प्रायः साँझपख पार्कमा दौडिन वा व्यायाम गर्न जान्छु।",
"तपाईंले बिहानको खाजा खानु भयो? मैले त खाइसकेँ।",
"मेरो आज धेरै काम बाँकी छ, रातिसम्ममा सक्नुपर्छ।",
"म आज अफिसमा मिटिङहरूले गर्दा धेरै व्यस्त थिएँ।",
"म अहिले खाना बनाउँदै छु।",
"के तपाईं आज मसँग बजार जानुहुन्छ?",
"मैले गृहकार्य सकेर साथीहरूसँग खेल्न जान्छु।",
"राति सुत्नुअघि म किताब पढ्छु।",
"आजकल म चाँडै सुत्ने र चाँडै उठ्ने प्रयास गर्दैछु।",
# --- Food and Culture ---
"मलाई नेपाली परम्परागत खाना, विशेष गरी दाल, भात, तरकारी धेरै मन पर्छ।",
"मःमः, सेल रोटी र ढिँडो मेरो सबैभन्दा मनपर्ने नेपाली परिकार हुन्।",
"तपाईंले आज दिउँसोको खानामा दाल भात खाउनु भयो?",
"नेपालमा तिहारको बेला समूहमा देउसी-भैलो खेल्ने पुरानो चलन छ।",
"दशैं नेपालीहरूको सबैभन्दा ठूलो र महत्वपूर्ण चाड हो।",
"यो गुन्द्रुकको अचार साह्रै मीठो रहेछ।",
"के तपाईंलाई नेवारी खाजा मन पर्छ?",
"विभिन्न जातजातिका आ-आफ्नै सांस्कृतिक विशेषताहरू छन्।",
"नेपाली लोक संगीत सुन्दा मन आनन्दित हुन्छ।",
"हाम्रो संस्कृतिमा अतिथि देवो भवः भन्ने मान्यता छ।",
# --- History and Religion ---
"भगवान गौतम बुद्ध नेपालको लुम्बिनीमा जन्मिएका थिए।",
"विश्वको सर्वोच्च शिखर सगरमाथा नेपालमा पर्दछ।",
"पोखराको तालबाराही मन्दिर तालको बीचमा रहेको छ।", # Modified slightly for accuracy
"नेपालमा लिच्छविकालीन, मल्लकालीन मठ मन्दिरहरु र वास्तुकला प्रसिद्ध छन्।",
"काठमाडौंमा रहेको पशुपतिनाथ मन्दिर बागमती नदीको किनारमा अवस्थित छ।",
"पृथ्वीनारायण शाहले आधुनिक नेपालको एकीकरण गरेका थिए।",
"स्वयम्भूनाथ स्तूपामा धेरै बाँदरहरू छन्।",
"जानकी मन्दिर सीताको जन्मस्थल जनकपुरमा रहेको छ।",
"नेपालमा हिन्दु र बौद्ध धर्मावलम्बीहरूको बाहुल्यता छ।",
"मनकामना मन्दिर दर्शन गर्न केबलकार चढेर जानुपर्छ।",
# --- Emotions ---
"यो सफलता पाएर म आज निकै खुशी छु।",
"परीक्षामा असफल हुँदा ऊ धेरै दुखी देखिन्छ।",
"किन यस्तो व्यवहार गरेको? तिमी रिसाएको जस्तो देखिन्छौ।",
"यो अनौठो समाचारले मलाई साँच्चै अचम्मित बनाएको छ।",
"आज म सामान्य र शान्त महसुस गर्दैछु, कुनै विशेष कुरा छैन।",
"मलाई अलिकति डर लागिरहेको छ।",
"उनी आफ्नो प्रस्तुतिलाई लिएर उत्साहित छिन्।",
"मैले गरेको गल्तीमा मलाई पछुतो छ।",
"यो कस्तो अचम्मको कुरा हो!",
"मलाई एकदमै दिक्क लाग्यो।",
# --- Hobbies and Interests ---
"म फुर्सदको समयमा विभिन्न प्रकारका पुस्तक पढ्न मन पराउँछु।",
"मैले आजकल गितार बजाउन र गीत गाउन सिक्दैछु।",
"के तपाईंलाई क्रिकेट हेर्न वा फुटबल खेल्न रुचाउनु हुन्छ?",
"मलाई प्रकृति र मानिसहरूको चित्रकला गर्न औधी मन पर्छ।",
"हामी अर्को हप्ता पदयात्रामा जान उत्साहित छौं।",
"बागवानी गर्नु मेरो सोख हो।",
"मलाई विभिन्न देशका मुद्राहरू संकलन गर्न मनपर्छ।",
"के तपाईंलाई खाना पकाउन आउँछ?",
"मलाई नयाँ ठाउँहरू घुम्न र नयाँ संस्कृतिहरू सिक्न मन पर्छ।",
"फोटोग्राफी मेरो रुचिको विषय हो।",
# --- Education and Work ---
"म त्रिभुवन विश्वविद्यालयमा बीए द्वितीय वर्षमा मानविकी संकायमा अध्ययन गर्दैछु।",
"उहाँ एक अनुभवी र सफल वकील हुनुहुन्छ।",
"मैले भर्खरै एउटा नयाँ सामाजिक उद्यम परियोजना सुरु गरेको छु।",
"अन्ततः, मैले लोकसेवाको परीक्षा प्रथम श्रेणीमा उत्तीर्ण गरेँ।",
"आजकल तपाईंको व्यवसाय र कामकाज कस्तो चल्दैछ?",
"म एक सफ्टवेयर इन्जिनियरको रूपमा काम गर्छु।",
"शिक्षण एउटा सम्मानित पेशा हो।",
"के तपाईंले आफ्नो स्नातकोत्तर पूरा गर्नुभयो?",
"म जागिरको खोजीमा छु।",
"कार्यशालामा धेरै उपयोगी जानकारी पाइयो।",
# --- Technology and Media ---
"म अहिले नयाँ मोडलको स्मार्टफोन प्रयोग गर्दैछु।",
"म हरेक दिन जुम मार्फत अनलाइन कक्षा लिन्छु।",
"आजकलका युवाहरू सोशल मिडियामा धेरै समय बिताउँछन्।",
"मैले भर्खरै एउटा उपयोगी मोबाइल एप्लिकेसन विकास गरेको छु।",
"आफ्ना विचारहरू व्यक्त गर्न ब्लग लेख्न मलाई रमाइलो लाग्छ।",
"इन्टरनेटले संसारलाई एउटा सानो गाउँ बनाएको छ।",
"के तपाईंले त्यो भाइरल भिडियो हेर्नुभयो?",
"कृत्रिम बौद्धिकता (AI) भविष्यको प्रविधि हो।",
"म अनलाइन समाचार पोर्टलहरू नियमित रूपमा पढ्छु।",
"डिजिटल भुक्तानीले कारोबारलाई सजिलो बनाएको छ।",
# --- Health and Fitness ---
"म आफ्नो शारीरिक र मानसिक स्वास्थ्यका लागि दैनिक योग अभ्यास गर्छु।",
"लामो र स्वस्थ जीवनका लागि सन्तुलित खानपान आवश्यक छ।",
"हामी सबै रोगमुक्त र सुखी जीवन चाहन्छौं।",
"यदि तपाईंलाई अस्वस्थ महसुस भइरहेको छ भने तुरुन्त डाक्टरको सल्लाह लिनुहोस्।",
"नियमित व्यायामले हाम्रो शरीरलाई बलियो र स्फूर्त बनाउँछ।",
"पर्याप्त निद्रा स्वास्थ्यका लागि महत्त्वपूर्ण छ।",
"तनाव व्यवस्थापन गर्न ध्यान गर्नु राम्रो हुन्छ।",
"धुम्रपान स्वास्थ्यका लागि हानिकारक छ।",
"म हरेक बिहान जगिङ गर्न जान्छु।",
"फलफूल र हरियो सागसब्जी प्रशस्त खानुपर्छ।",
# --- Shopping and Services ---
"म अहिले तरकारी किन्न बजार जान्छु, तपाईंलाई केही चाहिन्छ कि?",
"माफ गर्नुहोस्, यो निलो सर्टको कति पर्छ होला?",
"यो सुन्दर पश्मिना सल कतातिर बनेको होला? यो निकै राम्रो छ।",
"मलाई यो सामानको पेमेन्ट मेरो मोबाइल वालेटबाट गर्न मन छ, के यो सम्भव छ?",
"तपाईंको पसल ठ्याक्कै कहाँनिर छ, मलाई ठेगाना दिनुहुन्छ कि?",
"के यहाँ अनलाइन अर्डर गर्ने सुविधा छ?",
"मलाई यो जुत्ताको साइज अलि मिलेन, साट्न मिल्छ?",
"बैंक कति बजे खुल्छ?",
"मलाई बिजुलीको बिल तिर्नु छ।",
"यो औषधि पसलमा सबै किसिमका औषधि पाइन्छ।",
# --- Family and Relationships ---
"मेरो जेठो दाई गाउँको सरकारी विद्यालयमा पढाउनुहुन्छ।",
"हामी सबै परिवारका सदस्यहरू एक आपसमा धेरै माया र सम्मान गर्छौं।",
"चित्रमा देखिनुहुने व्यक्तिहरू मेरा आदरणीय पुर्खाहरु हुन्।",
"हाम्रो संयुक्त परिवार निकै ठूलो र रमाइलो छ।",
"मेरा बाल्यकालका केही मिल्ने साथीहरु आज मलाई भेट्न आउँदैछन्।",
"आमाबुबाको आज्ञा पालन गर्नु हाम्रो कर्तव्य हो।",
"छिमेकीहरूसँग राम्रो सम्बन्ध राख्नुपर्छ।",
"के तपाईं विवाहित हुनुहुन्छ?",
"मेरा भाइबहिनीहरू धेरै चकचके छन्।",
"सम्बन्धमा विश्वास सबैभन्दा महत्त्वपूर्ण कुरा हो।",
# --- Greetings and Introductions (with Code-Switching) ---
"नमस्ते, मेरो नाम __ हो। म नेपाली बोल्छु and I also speak English.",
"हाई! तपाईंलाई कस्तो छ? Are you feeling okay today?",
"शुभ रात्री, good night, राम्रोसँग सुत्नुहोस्।",
"मेरो family मा चार जना छन्: बुबा, आमा, दाइ र म।",
"तपाईं कहाँबाट हुनुहुन्छ? I am from Kathmandu.",
"म अलि sick छु, please मलाई सहयोग गर्नुहोस्।",
"तपाईंसँग भेटेर खुसी लाग्यो, it was nice meeting you.",
"मेरो घर पोखरामा छ, it's a beautiful city.",
"के म तपाईंको name जान्न सक्छु? What should I call you?",
"उहाँ मेरो best friend हुनुहुन्छ, हामी सँगै हुर्कियौं।",
# --- Weather and Nature (with Code-Switching) ---
"आज मौसम धेरै राम्रो छ, it's very sunny and pleasant.",
"Oh no! आज बिहानदेखि heavy rain भइरहेको छ।",
"यो wind ले कति चिसो बनाएको! It's freezing!",
"हिजो राति तराईमा thick fog लागेको थियो।",
"सुन्दर weather मा हरियो डाँडाकाँडा घुम्न जान मन लाग्छ, especially during spring.",
"आकाशमा beautiful rainbow देखिएको छ।",
"भोलिको weather forecast कस्तो छ? Is it going to rain?",
"रुखहरूमा new leaves पलाएको छ।",
"यो waterfall हेर्न कति amazing!",
"I love walking on the beach, तर नेपालमा beach छैन।",
# --- Places and Travel (with Code-Switching) ---
"नेपाल एक beautiful देश हो, full of mountains, hills, and plains.",
"काठमाडौं नेपालको capital city हो, with a rich history.",
"पोखरा फेवातालको side मा अवस्थित छ, it's very picturesque.",
"चितवन National Park मा tigers and rhinos हेर्न पाइन्छ।",
"लुम्बिनी भगवान बुद्धको birthplace हो, a very sacred place.",
"सगरमाथा climb गर्न कति cost लाग्छ होला? It must be expensive.",
"म अर्को month मुक्तिनाथ दर्शन गर्न जाँदैछु, it's a famous pilgrimage site.",
"नेपालमा धेरै attractive tourist destinations छन्।",
"Excuse me, यहाँबाट सबैभन्दा नजिकको hotel कुन हो?",
"बसको ticket कहाँ किन्न पाइन्छ? Can I book online?",
# --- Daily Activities (with Code-Switching) ---
"म आज बिहान छिट्टै उठेँ and I am going to school now.",
"म प्रायः evening मा पार्कमा jogging गर्न जान्छु for some exercise.",
"तपाईंले breakfast खानु भयो? I just had mine.",
"मेरो आज धेरै work बाँकी छ, I need to finish it by tonight.",
"म आज office मा meetings ले गर्दा धेरै busy थिएँ।",
"म अहिले dinner बनाउँदै छु।",
"Are you free today? मसँग बजार जानुहुन्छ?",
"मैले homework सकेर I'll go play with friends.",
"राति सुत्नुअघि म usually a book पढ्छु।",
"Nowadays, I am trying to sleep early and wake up early.",
# --- Food and Culture (with Code-Switching) ---
"मलाई नेपाली traditional खाना, especially दाल, भात, तरकारी, I love it!",
"मःमः, सेल रोटी and ढिँडो are my favorite Nepali dishes.",
"तपाईंले lunch मा दाल भात खाउनु भयो? What did you have?",
"नेपालमा Tihar को बेला देउसी-भैलो खेल्ने old tradition छ।",
"दशैं is the biggest festival for Nepalis.",
"यो गुन्द्रुकको pickle साह्रै delicious रहेछ।",
"Do you like Newari food? It's quite unique.",
"विभिन्न ethnic groups का आ-आफ्नै cultural traditions छन्।",
"नेपाली folk music सुन्दा I feel so relaxed.",
"हाम्रो culture मा 'अतिथि देवो भवः' meaning guest is god भन्ने मान्यता छ।",
# --- Technology and Media (with Code-Switching) ---
"म अहिले new model को smartphone प्रयोग गर्दैछु।",
"म हरेक दिन Zoom मार्फत online class लिन्छु।",
"आजकलका youngsters Social Media मा धेरै time बिताउँछन्।",
"मैले भर्खरै एउटा useful mobile application develop गरेको छु।",
"आफ्ना thoughts express गर्न blog लेख्न मलाई रमाइलो लाग्छ, it's a good hobby.",
"Internet ले संसारलाई एउटा global village बनाएको छ।",
"Did you see that viral video? It's everywhere.",
"Artificial Intelligence, or AI, भविष्यको technology हो।",
"म online news portals regularly पढ्छु to stay updated.",
"Digital payment ले transactions लाई धेरै easy बनाएको छ।",
# --- Shopping and Services (with Code-Switching) ---
"म अहिले market जान्छु, do you need anything?",
"Excuse me, कति पर्छ यो किताब? What's the price?",
"यो beautiful पश्मिना shawl कता made in होला?",
"मलाई यो item को payment मेरो mobile wallet बाट गर्न मन छ, is that possible?",
"तपाईंको shop ठ्याक्कै कहाँ छ? Can you give me the location?",
"Do you have online ordering facility?",
"मलाई यो shoes को size अलि मिलेन, can I exchange it?",
"बैंक कति बजे open हुन्छ?",
"मलाई electricity bill pay गर्नु छ।",
"यो pharmacy मा सबै A-Z medicine पाइन्छ।",
# --- Work and Office Talk (with Code-Switching) ---
"यो project को deadline कहिले हो?",
"Can we schedule a meeting for tomorrow morning?",
"मैले presentation prepare गरिसकेँ।",
"Please send me the report by end of day.",
"हाम्रो team ले target achieve गर्यो।",
"I have a conference call at 3 PM.",
"यो task लाई prioritize गर्नुपर्छ।",
"Could you please follow up on that email?",
"Let's brainstorm some new ideas for the campaign.",
"The client is very happy with our work.",
# --- Casual Conversation Snippets (with Code-Switching) ---
"Actually, मलाई त्यस्तो लाग्दैन।",
"Seriously? त्यो त great news हो!",
"By the way, तपाईंले त्यो movie हेर्नुभयो?",
"Okay, no problem, म manage गर्छु।",
"I think, हामीले plan B मा जानुपर्छ।",
"To be honest, मलाई यो idea मन परेन।",
"Wow, that's amazing! Congratulations!",
"Sorry, I am a bit late today.",
"What's up? सब ठीक छ?",
"Let's catch up soon, है त?",
# --- Asking for Help or Information (with Code-Switching) ---
"Excuse me, can you help me with this address?",
"मलाई यो form fill up गर्न अलि confusion भयो।",
"Do you know where the nearest ATM is?",
"यो ठाउँको बारेमा more information दिन सक्नुहुन्छ?",
"What time does the next bus to Pokhara leave?",
"I am looking for a good restaurant, any recommendations?",
"Could you please repeat that? मैले बुझिनँ।",
"How much does this cost? Is there any discount?",
"Is Wi-Fi available here?",
"Sorry to bother you, तर मलाई direction चाहिएको थियो।",
# --- Greetings and Introductions (with Code-Switching) ---
"नमस्ते, मेरो नाम __ हो। म नेपाली बोल्छु। and I also speak English.",
"हाई! तपाईंलाई कस्तो छ? Are you feeling okay today?",
"शुभ रात्री, good night, राम्रोसँग सुत्नुहोस्।",
"मेरो family मा चार जना छन्: बुबा, आमा, दाइ र म।",
"तपाईं कहाँबाट हुनुहुन्छ? I am from Kathmandu.",
"म अलि sick छु, please मलाई सहयोग गर्नुहोस्।",
"तपाईंसँग भेटेर खुसी लाग्यो, it was nice meeting you.",
"मेरो घर पोखरामा छ, it's a beautiful city.",
"के म तपाईंको name जान्न सक्छु? What should I call you?",
"उहाँ मेरो best friend हुनुहुन्छ, हामी सँगै हुर्कियौं।",
"मेरो परिवारमा पाँच जना सदस्य हुनुहुन्छ।",
"I have been living here for the past 10 years.",
# --- Weather and Nature (with Code-Switching) ---
"आज मौसम धेरै राम्रो छ, it's very sunny and pleasant.",
"Oh no! आज बिहानदेखि heavy rain भइरहेको छ।",
"यो wind ले कति चिसो बनाएको! It's freezing!",
"हिजो राति तराईमा thick fog लागेको थियो।",
"सुन्दर weather मा हरियो डाँडाकाँडा घुम्न जान मन लाग्छ, especially during spring.",
"आकाशमा beautiful rainbow देखिएको छ।",
"भोलिको weather forecast कस्तो छ? Is it going to rain?",
"रुखहरूमा new leaves पलाएको छ।",
"यो waterfall हेर्न कति amazing!",
"I love walking on the beach, तर नेपालमा beach छैन।",
# --- Places and Travel (with Code-Switching) ---
"नेपाल एक beautiful देश हो, full of mountains, hills, and plains.",
"काठमाडौं नेपालको capital city हो, with a rich history.",
"पोखरा फेवातालको side मा अवस्थित छ, it's very picturesque.",
"चितवन National Park मा tigers and rhinos हेर्न पाइन्छ।",
"लुम्बिनी भगवान बुद्धको birthplace हो, a very sacred place.",
"सगरमाथा climb गर्न कति cost लाग्छ होला? It must be expensive.",
"म अर्को month मुक्तिनाथ दर्शन गर्न जाँदैछु, it's a famous pilgrimage site.",
"नेपालमा धेरै attractive tourist destinations छन्।",
"Excuse me, यहाँबाट सबैभन्दा नजिकको hotel कुन हो?",
"बसको ticket कहाँ किन्न पाइन्छ? Can I book online?",
"सगरमाथाको उचाई ८८४८.८६ मिटर छ।",
"यो यात्रामा करिब ३ दिन लाग्नेछ।",
"Our flight departs at 6:45 AM.",
# --- Daily Activities (with Code-Switching) ---
"म आज बिहान छिट्टै उठेँ and I am going to school now.",
"म प्रायः evening मा पार्कमा jogging गर्न जान्छु for some exercise.",
"तपाईंले breakfast खानु भयो? I just had mine.",
"मेरो आज धेरै work बाँकी छ, I need to finish it by tonight.",
"म आज office मा meetings ले गर्दा धेरै busy थिएँ।",
"म अहिले dinner बनाउँदै छु।",
"Are you free today? मसँग बजार जानुहुन्छ?",
"मैले homework सकेर I'll go play with friends.",
"राति सुत्नुअघि म usually a book पढ्छु।",
"Nowadays, I am trying to sleep early and wake up early.",
"म हरेक दिन बिहान ६ बजे उठ्छु।",
"I usually work for 8 hours a day.",
# --- Food and Culture (with Code-Switching) ---
"मलाई नेपाली traditional खाना, especially दाल, भात, तरकारी, I love it!",
"मःमः, सेल रोटी and ढिँडो are my favorite Nepali dishes.",
"तपाईंले lunch मा दाल भात खाउनु भयो? What did you have?",
"नेपालमा Tihar को बेला देउसी-भैलो खेल्ने old tradition छ।",
"दशैं is the biggest festival for Nepalis.",
"यो गुन्द्रुकको pickle साह्रै delicious रहेछ।",
"Do you like Newari food? It's quite unique.",
"विभिन्न ethnic groups का आ-आफ्नै cultural traditions छन्।",
"नेपाली folk music सुन्दा I feel so relaxed.",
"हाम्रो culture मा 'अतिथि देवो भवः' meaning guest is god भन्ने मान्यता छ।",
"एउटा मःमः प्लेटमा सामान्यतया १० वटा हुन्छ।",
"This recipe requires 2 cups of flour.",
# --- History and Religion ---
"भगवान गौतम बुद्ध नेपालको लुम्बिनीमा जन्मिएका थिए।",
"विश्वको सर्वोच्च शिखर सगरमाथा नेपालमा पर्दछ।",
"पोखराको तालबाराही मन्दिर तालको बीचमा रहेको छ।",
"नेपालमा लिच्छविकालीन, मल्लकालीन मठ मन्दिरहरु र वास्तुकला प्रसिद्ध छन्।",
"काठमाडौंमा रहेको पशुपतिनाथ मन्दिर बागमती नदीको किनारमा अवस्थित छ।",
"पृथ्वीनारायण शाहले आधुनिक नेपालको एकीकरण गरेका थिए।",
"स्वयम्भूनाथ स्तूपामा धेरै बाँदरहरू छन्।",
"जानकी मन्दिर सीताको जन्मस्थल जनकपुरमा रहेको छ।",
"नेपालमा हिन्दु र बौद्ध धर्मावलम्बीहरूको बाहुल्यता छ।",
"मनकामना मन्दिर दर्शन गर्न केबलकार चढेर जानुपर्छ।",
# --- Emotions ---
"यो सफलता पाएर म आज निकै खुशी छु।",
"परीक्षामा असफल हुँदा ऊ धेरै दुखी देखिन्छ।",
"किन यस्तो व्यवहार गरेको? तिमी रिसाएको जस्तो देखिन्छौ।",
"यो अनौठो समाचारले मलाई साँच्चै अचम्मित बनाएको छ।",
"आज म सामान्य र शान्त महसुस गर्दैछु, कुनै विशेष कुरा छैन।",
"मलाई अलिकति डर लागिरहेको छ।",
"उनी आफ्नो प्रस्तुतिलाई लिएर उत्साहित छिन्।",
"मैले गरेको गल्तीमा मलाई पछुतो छ।",
"यो कस्तो अचम्मको कुरा हो!",
"मलाई एकदमै दिक्क लाग्यो।",
# --- Hobbies and Interests ---
"म फुर्सदको समयमा विभिन्न प्रकारका पुस्तक पढ्न मन पराउँछु।",
"मैले आजकल गितार बजाउन र गीत गाउन सिक्दैछु।",
"के तपाईंलाई क्रिकेट हेर्न वा फुटबल खेल्न रुचाउनु हुन्छ?",
"मलाई प्रकृति र मानिसहरूको चित्रकला गर्न औधी मन पर्छ।",
"हामी अर्को हप्ता पदयात्रामा जान उत्साहित छौं।",
"बागवानी गर्नु मेरो सोख हो।",
"मलाई विभिन्न देशका मुद्राहरू संकलन गर्न मनपर्छ।",
"के तपाईंलाई खाना पकाउन आउँछ?",
"मलाई नयाँ ठाउँहरू घुम्न र नयाँ संस्कृतिहरू सिक्न मन पर्छ।",
"फोटोग्राफी मेरो रुचिको विषय हो।",
# --- Education and Work (with Code-Switching) ---
"म त्रिभुवन विश्वविद्यालयमा बीए द्वितीय वर्षमा मानविकी संकायमा अध्ययन गर्दैछु।",
"उहाँ एक अनुभवी र सफल वकील हुनुहुन्छ।",
"मैले भर्खरै एउटा नयाँ सामाजिक उद्यम project सुरु गरेको छु।",
"अन्ततः, मैले लोकसेवाको examination प्रथम श्रेणीमा उत्तीर्ण गरेँ।",
"आजकल तपाईंको business र कामकाज कस्तो चल्दैछ?",
"म एक software engineer को रूपमा काम गर्छु।",
"Teaching एउटा सम्मानित पेशा हो।",
"के तपाईंले आफ्नो master's degree पूरा गर्नुभयो?",
"म job को खोजीमा छु।",
"Workshop मा धेरै useful जानकारी पाइयो।",
"म कलेजमा बीए प्रथम वर्षमा अध्ययन गर्दैछु।",
"My presentation is scheduled for 11:00 AM on Friday.",
"यो कम्पनी सन् २००५ मा स्थापना भएको हो।",
# --- Technology and Media (with Code-Switching) ---
"म अहिले new model को smartphone प्रयोग गर्दैछु।",
"म हरेक दिन Zoom मार्फत online class लिन्छु।",
"आजकलका youngsters Social Media मा धेरै time बिताउँछन्।",
"मैले भर्खरै एउटा useful mobile application develop गरेको छु।",
"आफ्ना thoughts express गर्न blog लेख्न मलाई रमाइलो लाग्छ, it's a good hobby.",
"Internet ले संसारलाई एउटा global village बनाएको छ।",
"Did you see that viral video? It's everywhere.",
"Artificial Intelligence, or AI, भविष्यको technology हो।",
"म online news portals regularly पढ्छु to stay updated.",
"Digital payment ले transactions लाई धेरै easy बनाएको छ।",
# --- Health and Fitness ---
"म आफ्नो शारीरिक र मानसिक स्वास्थ्यका लागि दैनिक योग अभ्यास गर्छु।",
"लामो र स्वस्थ जीवनका लागि सन्तुलित खानपान आवश्यक छ।",
"हामी सबै रोगमुक्त र सुखी जीवन चाहन्छौं।",
"यदि तपाईंलाई अस्वस्थ महसुस भइरहेको छ भने तुरुन्त डाक्टरको सल्लाह लिनुहोस्।",
"नियमित व्यायामले हाम्रो शरीरलाई बलियो र स्फूर्त बनाउँछ।",
"पर्याप्त निद्रा स्वास्थ्यका लागि महत्त्वपूर्ण छ।",
"तनाव व्यवस्थापन गर्न ध्यान गर्नु राम्रो हुन्छ।",
"धुम्रपान स्वास्थ्यका लागि हानिकारक छ।",
"म हरेक बिहान जगिङ गर्न जान्छु।",
"फलफूल र हरियो सागसब्जी प्रशस्त खानुपर्छ।",
# --- Shopping and Services (with Code-Switching) ---
"म अहिले market जान्छु, do you need anything?",
"Excuse me, कति पर्छ यो किताब? What's the price?",
"यो beautiful पश्मिना shawl कता made in होला?",
"मलाई यो item को payment मेरो mobile wallet बाट गर्न मन छ, is that possible?",
"तपाईंको shop ठ्याक्कै कहाँ छ? Can you give me the location?",
"Do you have online ordering facility?",
"मलाई यो shoes को size अलि मिलेन, can I exchange it?",
"बैंक कति बजे open हुन्छ?",
"मलाई electricity bill pay गर्नु छ।",
"यो pharmacy मा सबै A-Z medicine पाइन्छ।",
"मलाई २ किलो आलु र १ दर्जन केरा दिनुहोस्।",
"यो मोबाइलको वारेन्टी १ वर्षको छ।",
"The total bill is 1,270 rupees.",
# --- Family and Relationships ---
"मेरो जेठो दाई गाउँको सरकारी विद्यालयमा पढाउनुहुन्छ।",
"हामी सबै परिवारका सदस्यहरू एक आपसमा धेरै माया र सम्मान गर्छौं।",
"चित्रमा देखिनुहुने व्यक्तिहरू मेरा आदरणीय पुर्खाहरु हुन्।",
"हाम्रो संयुक्त परिवार निकै ठूलो र रमाइलो छ।",
"मेरा बाल्यकालका केही मिल्ने साथीहरु आज मलाई भेट्न आउँदैछन्।",
"आमाबुबाको आज्ञा पालन गर्नु हाम्रो कर्तव्य हो।",
"छिमेकीहरूसँग राम्रो सम्बन्ध राख्नुपर्छ।",
"के तपाईं विवाहित हुनुहुन्छ?",
"मेरा भाइबहिनीहरू धेरै चकचके छन्।",
"सम्बन्धमा विश्वास सबैभन्दा महत्त्वपूर्ण कुरा हो।",
# --- Work and Office Talk (with Code-Switching) ---
"यो project को deadline कहिले हो?",
"Can we schedule a meeting for tomorrow morning?",
"मैले presentation prepare गरिसकेँ।",
"Please send me the report by end of day.",
"हाम्रो team ले target achieve गर्यो।",
"I have a conference call at 3 PM.",
"यो task लाई prioritize गर्नुपर्छ।",
"Could you please follow up on that email?",
"Let's brainstorm some new ideas for the campaign.",
"The client is very happy with our work.",
# --- Casual Conversation Snippets (with Code-Switching) ---
"Actually, मलाई त्यस्तो लाग्दैन।",
"Seriously? त्यो त great news हो!",
"By the way, तपाईंले त्यो movie हेर्नुभयो?",
"Okay, no problem, म manage गर्छु।",
"I think, हामीले plan B मा जानुपर्छ।",
"To be honest, मलाई यो idea मन परेन।",
"Wow, that's amazing! Congratulations!",
"Sorry, I am a bit late today.",
"What's up? सब ठीक छ?",
"Let's catch up soon, है त?",
# --- Asking for Help or Information (with Code-Switching) ---
"Excuse me, can you help me with this address?",
"मलाई यो form fill up गर्न अलि confusion भयो।",
"Do you know where the nearest ATM is?",
"यो ठाउँको बारेमा more information दिन सक्नुहुन्छ?",
"What time does the next bus to Pokhara leave?",
"I am looking for a good restaurant, any recommendations?",
"Could you please repeat that? मैले बुझिनँ।",
"How much does this cost? Is there any discount?",
"Is Wi-Fi available here?",
"Sorry to bother you, तर मलाई direction चाहिएको थियो。",
# --- Prompts Involving Numbers (Nepali and Code-Switched) ---
"मसँग पाँच सय रुपैयाँ मात्र छ।",
"यो सामानको मूल्य दुई हजार तीन सय पचास हो।",
"आज मिति २०८० साल, फाल्गुण महिनाको १५ गते हो।",
"बिहानको साढे सात बज्यो, उठ्ने बेला भयो।",
"मेरो फोन नम्बर ९८४१-१२३४५६ हो। (कृपया यो नम्बर रेकर्ड नगर्नुहोस्)",
"यो कक्षामा पच्चीस जना विद्यार्थी छन्।",
"मैले तीनवटा किताब किनेँ।",
"उहाँ पहिलो पटक काठमाडौं आउनुभएको हो।",
"हाम्रो घर नम्बर १०२/४ हो।",
"यो गाडीको गति प्रति घण्टा साठी किलोमिटर छ।",
"मैले दौडमा दोस्रो स्थान हासिल गरेँ।",
"यो कोठाको लम्बाई १२ फिट र चौडाई १० फिट छ।",
"बैंक खातामा लगभग पचास हजार रुपैयाँ बाँकी छ।",
"कार्यक्रम दिउँसोको ठीक ३ बजे सुरु हुनेछ।",
"यो वर्षको बजेट अनुमानित १७ खर्बको छ।",
"There are 7 days in a week.",
"My appointment is on October 21st at 2:30 PM.",
"The score was 3-2 in favor of our team.",
"Please dial extension 101.",
"This laptop costs around 75,000 rupees.",
"I need to buy 2 kilograms of sugar and 1 liter of milk.",
"The building has 15 floors.",
"Her flight number is RA 205.",
"The temperature today is 28 degrees Celsius.",
"Can you give me a 10% discount?",
"मेरो जन्म सन् १९९५ मा भएको थियो।",
"यो फिल्मको अवधि २ घण्टा ३० मिनेट छ।",
"उनले १०० मा ९० अंक प्राप्त गरिन्।",
"यो बाटो लगभग ५ किलोमिटर लामो छ।",
"We need to submit the assignment by the 5th of next month."
]
EMOTIONS = ["सामान्य (Neutral)", "खुसी (Happy)", "दुःखी (Sad)", "रिसाएको (Angry)", "अचम्मित (Surprised)"]
GENDERS = ["पुरुष (Male)", "महिला (Female)", "अन्य (Other)", "भन्न चाहन्न (Prefer not to say)"]
AGE_GROUPS = ["18 भन्दा कम", "18-24", "25-34", "35-44", "45-54", "55-64", "65+"]
REGIONS = [
"प्रदेश १ (Province 1)", "मधेश प्रदेश (Madhesh Province)", "बागमती प्रदेश (Bagmati Province)",
"गण्डकी प्रदेश (Gandaki Province)", "लुम्बिनी प्रदेश (Lumbini Province)",
"कर्णाली प्रदेश (Karnali Province)", "सुदूरपश्चिम प्रदेश (Sudurpashchim Province)"
]
COMMON_LAST_NAMES = {
"पहाडी (Pahadi)": ["शर्मा (Sharma)", "पौडेल (Poudel)", "खनाल (Khanal)", "अधिकारी (Adhikari)", "भट्टराई (Bhattarai)", "अन्य पहाडी (Other Pahadi)"],
"नेवार (Newar)": ["श्रेष्ठ (Shrestha)", "प्रधान (Pradhan)", "महर्जन (Maharjan)", "बज्राचार्य (Bajracharya)", "अन्य नेवार (Other Newar)"],
"मधेसी (Madhesi)": ["यादव (Yadav)", "साह (Shah)", "सिंह (Singh)", "गुप्ता (Gupta)", "अन्य मधेसी (Other Madhesi)"],
"थारु (Tharu)": ["चौधरी (Chaudhary)", "थारु (Tharu)", "अन्य थारु (Other Tharu)"],
"मगर (Magar)": ["मगर (Magar)", "थापा (Thapa)", "राना (Rana)", "अन्य मगर (Other Magar)"],
"तामाङ (Tamang)": ["तामाङ (Tamang)", "लामा (Lama)", "अन्य तामाङ (Other Tamang)"],
"राई (Rai)": ["राई (Rai)", "अन्य राई (Other Rai)"],
"गुरुङ (Gurung)": ["गुरुङ (Gurung)", "अन्य गुरुङ (Other Gurung)"],
"लिम्बु (Limbu)": ["लिम्बु (Limbu)", "अन्य लिम्बु (Other Limbu)"],
"शेर्पा (Sherpa)": ["शेर्पा (Sherpa)", "अन्य शेर्पा (Other Sherpa)"],
"अन्य (Other)": ["अन्य (Other)"]
}
# --- Directory and File Paths (Local to the Space) ---
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # Ensures paths are relative to app.py
RECORDINGS_DIR = os.path.join(BASE_DIR, "recordings")
METADATA_DIR = os.path.join(BASE_DIR, "metadata")
RATINGS_DIR = os.path.join(BASE_DIR, "ratings")
LOCAL_METADATA_FILE = os.path.join(METADATA_DIR, "local_metadata.csv")
LOCAL_RATINGS_FILE = os.path.join(RATINGS_DIR, "local_ratings.json")
HF_UPLOAD_LOG_FILE = os.path.join(METADATA_DIR, "hf_upload_log.csv") # To track HF uploads
# --- Hugging Face Configuration (from Space Secrets) ---
# These will be fetched from environment variables set by Space Secrets
# HF_TOKEN: Your HF Write Token
# ADMIN_UPLOAD_PASSWORD: Password for admin functions
# TARGET_HF_DATASET_REPO_ID: e.g., "yourusername/your-dataset-repo"
# --- Initialization ---
def initialize_data_storage():
os.makedirs(RECORDINGS_DIR, exist_ok=True)
os.makedirs(METADATA_DIR, exist_ok=True)
os.makedirs(RATINGS_DIR, exist_ok=True)
if not os.path.exists(LOCAL_METADATA_FILE):
pd.DataFrame(columns=[
"id", "text", "local_audio_path", "gender", "age_group", "ethnicity",
"last_name", "region", "emotion", "timestamp", "recording_type",
"hf_audio_uploaded", "hf_metadata_uploaded" # Track HF upload status
]).to_csv(LOCAL_METADATA_FILE, index=False)
if not os.path.exists(LOCAL_RATINGS_FILE):
with open(LOCAL_RATINGS_FILE, 'w') as f:
json.dump({}, f)
if not os.path.exists(HF_UPLOAD_LOG_FILE):
pd.DataFrame(columns=["id", "timestamp", "hf_repo_id", "type", "status", "message"]).to_csv(HF_UPLOAD_LOG_FILE, index=False)
initialize_data_storage()
# --- Helper: Log HF Upload Attempts ---
def log_hf_upload_attempt(recording_id, hf_repo_id, upload_type, status, message=""):
log_df = pd.read_csv(HF_UPLOAD_LOG_FILE)
new_log_entry = pd.DataFrame([{
"id": recording_id,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"hf_repo_id": hf_repo_id,
"type": upload_type, # "audio", "metadata_entry", "ratings_sync"
"status": status, # "success", "failure"
"message": message
}])
updated_log_df = pd.concat([log_df, new_log_entry], ignore_index=True)
updated_log_df.to_csv(HF_UPLOAD_LOG_FILE, index=False)
# --- Core Functions ---
def save_and_direct_upload_recording(audio_input, text, gender, age_group, ethnicity, last_name, region, emotion, recording_type):
"""Saves recording locally and attempts immediate upload to Hugging Face."""
if audio_input is None:
return "कृपया पहिले रेकर्डिङ गर्नुहोस्। (Please record audio first)", None
# --- Get HF Config from Secrets ---
hf_token = os.environ.get("HF_TOKEN")
target_hf_repo_id = os.environ.get("TARGET_HF_DATASET_REPO_ID")
if not hf_token or not target_hf_repo_id:
# Critical config missing, only save locally
status_msg, _ = save_recording_locally(
audio_input, text, gender, age_group, ethnicity, last_name, region, emotion, recording_type,
hf_audio_uploaded=False, hf_metadata_uploaded=False # Mark as not uploaded
)
return f"{status_msg} (HF config missing in secrets, saved locally only)", None
# --- Save Locally First (always) ---
status_msg_local, recording_id, local_audio_path = save_recording_locally(
audio_input, text, gender, age_group, ethnicity, last_name, region, emotion, recording_type,
hf_audio_uploaded=False, hf_metadata_uploaded=False # Initial state
)
if not recording_id: # Failed to save locally
return status_msg_local, None
# --- Attempt Direct HF Upload ---
hf_upload_success = True
final_status_message = status_msg_local # Start with local save message
try:
api = HfApi(token=hf_token)
# Ensure base repo and standard subfolders exist
create_repo(repo_id=target_hf_repo_id, token=hf_token, repo_type="dataset", exist_ok=True, private=False)
for folder in ["audio", "metadata_entries", "ratings_entries"]:
try:
api.create_folder(repo_id=target_hf_repo_id, folder_path=folder, repo_type="dataset", exist_ok=True)
except Exception: pass # Ignore if folder exists
# 1. Upload Audio File to HF
hf_audio_path = f"audio/{os.path.basename(local_audio_path)}"
api.upload_file(
path_or_fileobj=local_audio_path,
path_in_repo=hf_audio_path,
repo_id=target_hf_repo_id,
repo_type="dataset",
commit_message=f"feat: Add audio for recording {recording_id}"
)
log_hf_upload_attempt(recording_id, target_hf_repo_id, "audio", "success")
update_local_metadata_hf_status(recording_id, hf_audio_uploaded=True)
final_status_message += f"\nअडियो सफलतापूर्वक HF मा अपलोड गरियो। (Audio uploaded to HF successfully.)"
# 2. Prepare and Upload Metadata Entry to HF
single_metadata_dict_for_hf = {
"id": recording_id, "text": text, "hf_audio_path": hf_audio_path,
"gender": gender, "age_group": age_group, "ethnicity": ethnicity,
"last_name": last_name, "region": region, "emotion": emotion,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), # Use current time for HF metadata
"recording_type": recording_type
# Initial ratings are not part of this base metadata; they'll be separate
}
hf_metadata_entry_path = f"metadata_entries/{recording_id}.json"
api.upload_file(
path_or_fileobj=io.BytesIO(json.dumps(single_metadata_dict_for_hf, ensure_ascii=False, indent=2).encode('utf-8')),
path_in_repo=hf_metadata_entry_path,
repo_id=target_hf_repo_id,
repo_type="dataset",
commit_message=f"feat: Add metadata for recording {recording_id}"
)
log_hf_upload_attempt(recording_id, target_hf_repo_id, "metadata_entry", "success")
update_local_metadata_hf_status(recording_id, hf_metadata_uploaded=True)
final_status_message += f"\nमेटाडाटा सफलतापूर्वक HF मा अपलोड गरियो। (Metadata uploaded to HF successfully.)"
except Exception as e:
tb_str = traceback.format_exc()
error_message = f"HF अपलोडको क्रममा त्रुटि: {str(e)}. (Error during HF upload.)\nविवरण (Details): {tb_str}"
log_hf_upload_attempt(recording_id, target_hf_repo_id, "audio_or_metadata_entry_direct", "failure", error_message)
final_status_message += f"\n{error_message}\nडाटा स्थानीय रूपमा सुरक्षित गरिएको छ। (Data saved locally.)"
hf_upload_success = False # Mark that direct upload had issues
return final_status_message, None # Clear audio input
def save_recording_locally(audio_input, text, gender, age_group, ethnicity, last_name, region, emotion, recording_type, hf_audio_uploaded=False, hf_metadata_uploaded=False):
"""Saves recording and metadata locally in the Space."""
recording_id = str(uuid.uuid4())
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
audio_filename_relative = f"{recording_id}.wav"
local_audio_path = os.path.join(RECORDINGS_DIR, audio_filename_relative)
try:
if isinstance(audio_input, tuple):
sr, data = audio_input
sf.write(local_audio_path, data, sr)
elif isinstance(audio_input, str) and os.path.exists(audio_input):
shutil.copy(audio_input, local_audio_path)
else:
return "अडियो फाइल बचत गर्न सकिएन। (Could not save audio file. Invalid audio input.)", None, None
except Exception as e:
return f"स्थानीय रूपमा अडियो बचत गर्दा त्रुटि भयो: {e} (Error saving audio locally: {e})", None, None
# Save to local metadata CSV
try:
metadata_df = pd.read_csv(LOCAL_METADATA_FILE)
new_row = pd.DataFrame([{
"id": recording_id, "text": text, "local_audio_path": local_audio_path,
"gender": gender, "age_group": age_group, "ethnicity": ethnicity,
"last_name": last_name, "region": region, "emotion": emotion,
"timestamp": timestamp, "recording_type": recording_type,
"hf_audio_uploaded": hf_audio_uploaded, "hf_metadata_uploaded": hf_metadata_uploaded
}])
updated_metadata = pd.concat([metadata_df, new_row], ignore_index=True)
updated_metadata.to_csv(LOCAL_METADATA_FILE, index=False)
except Exception as e:
# If metadata save fails, try to clean up audio to avoid orphans
if os.path.exists(local_audio_path): os.remove(local_audio_path)
return f"स्थानीय मेटाडाटा बचत गर्दा त्रुटि: {e} (Error saving local metadata: {e})", None, None
# Initialize local ratings
try:
with open(LOCAL_RATINGS_FILE, 'r+') as f:
ratings = json.load(f)
ratings[recording_id] = {"upvotes": 0, "downvotes": 0, "quality_score": 0, "quality_votes": 0, "correctness_score": 0, "correctness_votes": 0}
f.seek(0)
json.dump(ratings, f, indent=2, ensure_ascii=False)
f.truncate()
except Exception as e:
# Non-critical for recording saving, but log it
print(f"Warning: Could not initialize local ratings for {recording_id}: {e}")
return f"रेकर्डिङ सफलतापूर्वक स्थानीय रूपमा सुरक्षित गरियो! ID: {recording_id} (Recording saved locally successfully!)", recording_id, local_audio_path
def update_local_metadata_hf_status(recording_id, hf_audio_uploaded=None, hf_metadata_uploaded=None):
"""Updates the HF upload status flags in the local metadata CSV."""
try:
metadata_df = pd.read_csv(LOCAL_METADATA_FILE)
idx = metadata_df[metadata_df['id'] == recording_id].index
if not idx.empty:
if hf_audio_uploaded is not None:
metadata_df.loc[idx, 'hf_audio_uploaded'] = hf_audio_uploaded
if hf_metadata_uploaded is not None:
metadata_df.loc[idx, 'hf_metadata_uploaded'] = hf_metadata_uploaded
metadata_df.to_csv(LOCAL_METADATA_FILE, index=False)
except Exception as e:
print(f"Error updating local metadata HF status for {recording_id}: {e}")
def get_random_prompt(): return random.choice(SAMPLE_PROMPTS)
def get_ethnicity_based_last_names(ethnicity): return gr.Dropdown.update(choices=COMMON_LAST_NAMES.get(ethnicity, COMMON_LAST_NAMES["अन्य (Other)"]))
def vote_recording(recording_id, vote_type, vote_value_str):
if not recording_id: return "कृपया पहिले समीक्षा गर्न रेकर्डिङ चयन गर्नुहोस्।"
if not os.path.exists(LOCAL_RATINGS_FILE): return "स्थानीय रेटिङ फाइल भेटिएन।"
try: vote_value = int(vote_value_str)
except ValueError: vote_value = 0
try:
with open(LOCAL_RATINGS_FILE, 'r+') as f:
ratings = json.load(f)
if recording_id not in ratings: return "यस रेकर्डिङको लागि स्थानीय मूल्याङ्कन भेटिएन।"
rec_ratings = ratings[recording_id]
if vote_type == "upvote": rec_ratings["upvotes"] += 1
elif vote_type == "downvote": rec_ratings["downvotes"] += 1
elif vote_type == "quality":
new_votes = rec_ratings.get("quality_votes", 0) + 1
rec_ratings["quality_score"] = ((rec_ratings.get("quality_score", 0) * rec_ratings.get("quality_votes", 0)) + vote_value) / new_votes
rec_ratings["quality_votes"] = new_votes
elif vote_type == "correctness":
new_votes = rec_ratings.get("correctness_votes", 0) + 1
rec_ratings["correctness_score"] = ((rec_ratings.get("correctness_score", 0) * rec_ratings.get("correctness_votes", 0)) + vote_value) / new_votes
rec_ratings["correctness_votes"] = new_votes
else: return "अमान्य मतदान प्रकार।"
f.seek(0); json.dump(ratings, f, indent=2, ensure_ascii=False); f.truncate()
return "स्थानीय मतदान सफलतापूर्वक दर्ता गरियो!"
except Exception as e: return f"स्थानीय मतदान दर्ता गर्दा त्रुटि: {str(e)}"
def get_local_recording_audio(recording_id):
if not recording_id: return None, "कुनै रेकर्डिङ आईडी प्रदान गरिएको छैन।"
if not os.path.exists(LOCAL_METADATA_FILE): return None, "स्थानीय मेटाडाटा फाइल भेटिएन।"
try: metadata = pd.read_csv(LOCAL_METADATA_FILE)
except pd.errors.EmptyDataError: return None, "स्थानीय मेटाडाटा खाली छ।"
recording = metadata[metadata['id'] == recording_id]
if len(recording) == 0: return None, "रेकर्डिङ भेटिएन।"
audio_path = recording['local_audio_path'].iloc[0]
text = recording['text'].iloc[0]
if not os.path.exists(audio_path): return None, f"स्थानीय अडियो फाइल भेटिएन: {audio_path}"
return audio_path, text
def get_local_recording_ratings(recording_id):
if not recording_id: return "रेकर्डिङ आईडी चयन गर्नुहोस्।"
if not os.path.exists(LOCAL_RATINGS_FILE): return "स्थानीय मूल्याङ्कन डाटा भेटिएन।"
with open(LOCAL_RATINGS_FILE, 'r') as f: ratings_data = json.load(f)
if recording_id not in ratings_data: return "यस रेकर्डिङको लागि कुनै स्थानीय मूल्याङ्कन भेटिएन।"
r = ratings_data[recording_id]
return (f"👍 Upvotes: {r.get('upvotes',0)} | 👎 Downvotes: {r.get('downvotes',0)}\n"
f"गुणस्तर (Quality): {r.get('quality_score',0):.1f}/5 ({r.get('quality_votes',0)} मत)\n"
f"शुद्धता (Correctness): {r.get('correctness_score',0):.1f}/5 ({r.get('correctness_votes',0)} मत)")
def update_local_count():
if os.path.exists(LOCAL_METADATA_FILE):
try:
metadata = pd.read_csv(LOCAL_METADATA_FILE)
uploaded_audio_count = metadata['hf_audio_uploaded'].sum()
uploaded_metadata_count = metadata['hf_metadata_uploaded'].sum()
return (f"कुल स्थानीय रेकर्डिङ: {len(metadata)}\n"
f"HF मा अडियो अपलोड गरिएको: {uploaded_audio_count}\n"
f"HF मा मेटाडाटा अपलोड गरिएको: {uploaded_metadata_count}")
except pd.errors.EmptyDataError: return "स्थानीय रेकर्डिङ: 0"
return "कुनै स्थानीय रेकर्डिङ भेटिएन।"
def list_local_recordings(num_items=10):
if not os.path.exists(LOCAL_METADATA_FILE): return pd.DataFrame()
try: metadata = pd.read_csv(LOCAL_METADATA_FILE)
except pd.errors.EmptyDataError: return pd.DataFrame()
if len(metadata) == 0: return pd.DataFrame()
metadata['timestamp'] = pd.to_datetime(metadata['timestamp'], errors='coerce')
sorted_metadata = metadata.sort_values('timestamp', ascending=False).head(int(num_items))
display_df = sorted_metadata[['id', 'text', 'ethnicity', 'region', 'timestamp', 'hf_audio_uploaded', 'hf_metadata_uploaded']].copy()
display_df['timestamp'] = display_df['timestamp'].dt.strftime('%Y-%m-%d %H:%M').fillna('N/A')
return display_df.reset_index(drop=True)
# --- Admin Functions for HF Syncing ---
def admin_retry_failed_uploads(admin_password_attempt):
hf_token = os.environ.get("HF_TOKEN")
target_hf_repo_id = os.environ.get("TARGET_HF_DATASET_REPO_ID")
expected_admin_password = os.environ.get("ADMIN_UPLOAD_PASSWORD")
if admin_password_attempt != expected_admin_password: return "अमान्य प्रशासक पासवर्ड।"
if not hf_token or not target_hf_repo_id: return "HF कन्फिगरेसन गोप्यमा हराइरहेको छ।"
if not os.path.exists(LOCAL_METADATA_FILE): return "कुनै स्थानीय मेटाडाटा फाइल भेटिएन।"
local_meta_df = pd.read_csv(LOCAL_METADATA_FILE)
# Find recordings where audio or metadata upload is marked as False
to_retry_df = local_meta_df[~(local_meta_df['hf_audio_uploaded'] & local_meta_df['hf_metadata_uploaded'])]
if to_retry_df.empty: return "पुनः प्रयास गर्न कुनै असफल अपलोडहरू भेटिएन।"
api = HfApi(token=hf_token)
success_count = 0
failure_count = 0
messages = []
for _, row in to_retry_df.iterrows():
rec_id = row['id']
local_audio_p = row['local_audio_path']
hf_audio_path = f"audio/{os.path.basename(local_audio_p)}"
current_status_msg = f"Retrying {rec_id}: "
try:
# Retry audio if not uploaded
if not row['hf_audio_uploaded'] and os.path.exists(local_audio_p):
api.upload_file(path_or_fileobj=local_audio_p, path_in_repo=hf_audio_path, repo_id=target_hf_repo_id, repo_type="dataset", commit_message=f"fix: Retry audio upload for {rec_id}")
update_local_metadata_hf_status(rec_id, hf_audio_uploaded=True)
log_hf_upload_attempt(rec_id, target_hf_repo_id, "audio_retry", "success")
current_status_msg += "Audio OK. "
elif row['hf_audio_uploaded']:
current_status_msg += "Audio already uploaded. "
# Retry metadata if not uploaded
if not row['hf_metadata_uploaded']:
# Reconstruct metadata dict for HF
hf_meta_dict = {
"id": rec_id, "text": row["text"], "hf_audio_path": hf_audio_path,
"gender": row["gender"], "age_group": row["age_group"], "ethnicity": row["ethnicity"],
"last_name": row["last_name"], "region": row["region"], "emotion": row["emotion"],
"timestamp": row["timestamp"], "recording_type": row["recording_type"]
}
hf_meta_entry_path = f"metadata_entries/{rec_id}.json"
api.upload_file(
path_or_fileobj=io.BytesIO(json.dumps(hf_meta_dict, ensure_ascii=False, indent=2).encode('utf-8')),
path_in_repo=hf_meta_entry_path, repo_id=target_hf_repo_id, repo_type="dataset",
commit_message=f"fix: Retry metadata entry upload for {rec_id}"
)
update_local_metadata_hf_status(rec_id, hf_metadata_uploaded=True)
log_hf_upload_attempt(rec_id, target_hf_repo_id, "metadata_entry_retry", "success")
current_status_msg += "Metadata OK."
elif row['hf_metadata_uploaded']:
current_status_msg += "Metadata already uploaded."
success_count += 1
messages.append(f"SUCCESS: {current_status_msg}")
except Exception as e:
failure_count += 1
err_msg = f"FAILURE for {rec_id}: {str(e)}"
messages.append(err_msg)
log_hf_upload_attempt(rec_id, target_hf_repo_id, "audio_or_metadata_retry", "failure", str(e))
return f"पुनः प्रयास सम्पन्न। सफलता: {success_count}, असफलता: {failure_count}\n" + "\n".join(messages)
def admin_sync_ratings_to_hf(admin_password_attempt):
hf_token = os.environ.get("HF_TOKEN")
target_hf_repo_id = os.environ.get("TARGET_HF_DATASET_REPO_ID")
expected_admin_password = os.environ.get("ADMIN_UPLOAD_PASSWORD")
if admin_password_attempt != expected_admin_password: return "अमान्य प्रशासक पासवर्ड।"
if not hf_token or not target_hf_repo_id: return "HF कन्फिगरेसन गोप्यमा हराइरहेको छ।"
if not os.path.exists(LOCAL_RATINGS_FILE): return "कुनै स्थानीय मूल्याङ्कन फाइल भेटिएन।"
with open(LOCAL_RATINGS_FILE, 'r') as f:
local_ratings = json.load(f)
if not local_ratings: return "सिंक गर्न कुनै स्थानीय मूल्याङ्कन छैन।"
api = HfApi(token=hf_token)
fs = HfFileSystem(token=hf_token) # For checking file existence
success_count = 0
failure_count = 0
messages = []
for rec_id, ratings_data in local_ratings.items():
# Only sync if there are any votes/scores
if not any(ratings_data.values()):
continue
hf_ratings_path = f"ratings_entries/{rec_id}.json"
try:
# Optional: Check if ratings on HF are older or different before uploading.
# For simplicity, we'll just overwrite/create.
api.upload_file(
path_or_fileobj=io.BytesIO(json.dumps(ratings_data, ensure_ascii=False, indent=2).encode('utf-8')),
path_in_repo=hf_ratings_path,
repo_id=target_hf_repo_id,
repo_type="dataset",
commit_message=f"chore: Sync ratings for recording {rec_id}"
)
success_count += 1
log_hf_upload_attempt(rec_id, target_hf_repo_id, "ratings_sync", "success")
messages.append(f"SUCCESS: Synced ratings for {rec_id}")
except Exception as e:
failure_count += 1
err_msg = f"FAILURE syncing ratings for {rec_id}: {str(e)}"
messages.append(err_msg)
log_hf_upload_attempt(rec_id, target_hf_repo_id, "ratings_sync", "failure", str(e))
return f"मूल्याङ्कन सिंक सम्पन्न। सफलता: {success_count}, असफलता: {failure_count}\n" + "\n".join(messages)
# --- Gradio UI Build ---
def build_ui():
with gr.Blocks(title="नेपाली ASR डाटा संकलन") as app:
gr.Markdown("# नेपाली ASR डाटा संकलन (Nepali ASR Data Collection)")
gr.Markdown(
"यस प्लेटफर्मले नेपाली भाषाको स्वचालित भाषण पहिचान (ASR) प्रविधिको विकासका लागि आवाज डाटा संकलन गर्दछ। "
"कृपया आफ्नो आवाज रेकर्ड गरेर योगदान दिनुहोस्। तपाईंको प्रत्येक रेकर्डिङ सिधै हाम्रो खुला हगिङ फेस डेटासेटमा योगदान गरिनेछ।\n\n"
f"**हाम्रो सार्वजनिक हगिङ फेस डेटासेट हेर्नुहोस् (View our public Hugging Face Dataset): [nepali-asr-community-data](https://huggingface.co/datasets/darvilab/nepali-asr-community-data)**\n\n"
"*This platform collects voice data for the development of Nepali Automatic Speech Recognition (ASR) technology. "
"Please contribute by recording your voice. Each of your recordings will be directly contributed to our open Hugging Face Dataset.*\n\n"
f"**View our public Hugging Face Dataset: [nepali-asr-community-data](https://huggingface.co/datasets/darvilab/nepali-asr-community-data)**"
)
with gr.Tabs():
with gr.TabItem("१. आवाज रेकर्ड गर्नुहोस् (Record Voice)"):
with gr.Tabs():
with gr.TabItem("स्वतन्त्र पाठ (Free Text)"):
# ... (UI elements as before, but change .click) ...
free_audio_input = gr.Audio(label="आवाज रेकर्ड गर्नुहोस्", type="filepath", sources=["microphone"]) # Corrected
free_text_input = gr.Textbox(label="पाठ", placeholder="यहाँ लेख्नुहोस्...", lines=3)
# ... (gender, age, ethnicity, lastname, region, emotion dropdowns) ...
free_gender_dd = gr.Dropdown(label="लिङ्ग", choices=GENDERS, value=GENDERS[0])
free_age_dd = gr.Dropdown(label="उमेर समूह", choices=AGE_GROUPS, value=AGE_GROUPS[1])
free_ethnicity_dd = gr.Dropdown(label="जातीयता", choices=list(COMMON_LAST_NAMES.keys()), value=list(COMMON_LAST_NAMES.keys())[0])
free_lastname_dd = gr.Dropdown(label="थर", choices=COMMON_LAST_NAMES[list(COMMON_LAST_NAMES.keys())[0]])
free_ethnicity_dd.change(fn=get_ethnicity_based_last_names, inputs=free_ethnicity_dd, outputs=free_lastname_dd)
free_region_dd = gr.Dropdown(label="क्षेत्र", choices=REGIONS, value=REGIONS[2])
free_emotion_dd = gr.Dropdown(label="भावना", choices=EMOTIONS, value=EMOTIONS[0])
free_submit_btn = gr.Button("सुरक्षित र अपलोड गर्नुहोस्")
free_status_output = gr.Textbox(label="स्थिति", interactive=False, lines=3)
free_submit_btn.click(
save_and_direct_upload_recording,
inputs=[free_audio_input, free_text_input, free_gender_dd, free_age_dd, free_ethnicity_dd, free_lastname_dd, free_region_dd, free_emotion_dd, gr.Textbox(value="free_text", visible=False)],
outputs=[free_status_output, free_audio_input]
)
with gr.TabItem("निर्देशित पाठ (Prompted Text)"):
# ... (UI elements as before, but change .click) ...
prompt_text_display = gr.Textbox(label="कृपया यो पाठ पढ्नुहोस्", value=get_random_prompt(), lines=3, interactive=False)
new_prompt_btn = gr.Button("नयाँ पाठ")
prompt_audio_input = gr.Audio(label="आवाज रेकर्ड गर्नुहोस्", type="filepath", sources=["microphone"]) # Corrected
# ... (gender, age, ethnicity, lastname, region, emotion dropdowns) ...
prompt_gender_dd = gr.Dropdown(label="लिङ्ग", choices=GENDERS, value=GENDERS[0])
prompt_age_dd = gr.Dropdown(label="उमेर समूह", choices=AGE_GROUPS, value=AGE_GROUPS[1])
prompt_ethnicity_dd = gr.Dropdown(label="जातीयता", choices=list(COMMON_LAST_NAMES.keys()), value=list(COMMON_LAST_NAMES.keys())[0])
prompt_lastname_dd = gr.Dropdown(label="थर", choices=COMMON_LAST_NAMES[list(COMMON_LAST_NAMES.keys())[0]])
prompt_ethnicity_dd.change(fn=get_ethnicity_based_last_names, inputs=prompt_ethnicity_dd, outputs=prompt_lastname_dd)
prompt_region_dd = gr.Dropdown(label="क्षेत्र", choices=REGIONS, value=REGIONS[2])
prompt_emotion_dd = gr.Dropdown(label="भावना", choices=EMOTIONS, value=EMOTIONS[0])
new_prompt_btn.click(get_random_prompt, outputs=prompt_text_display)
prompt_submit_btn = gr.Button("सुरक्षित र अपलोड गर्नुहोस्")
prompt_status_output = gr.Textbox(label="स्थिति", interactive=False, lines=3)
prompt_submit_btn.click(
save_and_direct_upload_recording,
inputs=[prompt_audio_input, prompt_text_display, prompt_gender_dd, prompt_age_dd, prompt_ethnicity_dd, prompt_lastname_dd, prompt_region_dd, prompt_emotion_dd, gr.Textbox(value="prompted_text", visible=False)],
outputs=[prompt_status_output, prompt_audio_input]
)
with gr.TabItem("२. रेकर्डिङ समीक्षा गर्नुहोस् (Review Local Recordings)"):
gr.Markdown("स्थानीय रूपमा सुरक्षित गरिएका हालसालैका रेकर्डिङहरू हेर्नुहोस् र मत दिनुहोस्। (View and vote on recent locally saved recordings.)")
num_review_items = gr.Number(value=10, label="देखाउने वस्तुहरूको संख्या", minimum=1, maximum=50, step=1)
refresh_review_list_btn = gr.Button("स्थानीय सूची ताजा गर्नुहोस्")
review_list_df = gr.DataFrame(
headers=['id', 'text', 'ethnicity', 'region', 'timestamp', 'hf_audio_uploaded', 'hf_metadata_uploaded'],
label="हालका स्थानीय रेकर्डिङहरू", interactive=False,
datatype=['str', 'str', 'str', 'str', 'str', 'bool', 'bool']
)
# ... (Rest of review UI, using get_local_recording_audio and get_local_recording_ratings) ...
selected_review_id = gr.Textbox(label="चयन गरिएको आईडी", interactive=False)
selected_review_text = gr.Textbox(label="रेकर्डिङ पाठ", interactive=False, lines=2)
review_audio_player = gr.Audio(label="रेकर्डिङ सुन्नुहोस्", type="filepath")
current_ratings_display = gr.Textbox(label="वर्तमान स्थानीय मूल्याङ्कन", interactive=False, lines=3)
def select_for_review(evt: gr.SelectData, df_data: pd.DataFrame):
if evt.index is None or df_data is None or len(df_data) == 0 or evt.index[0] >= len(df_data):
return "", "", None, "कुनै रेकर्डिङ चयन गरिएको छैन"
selected_id_val = df_data.iloc[evt.index[0]]['id']
audio_p, text_val = get_local_recording_audio(selected_id_val) # Use local getter
ratings_text_val = get_local_recording_ratings(selected_id_val) # Use local getter
return selected_id_val, text_val, audio_p, ratings_text_val
review_list_df.select(select_for_review, inputs=[review_list_df], outputs=[selected_review_id, selected_review_text, review_audio_player, current_ratings_display])
refresh_review_list_btn.click(list_local_recordings, inputs=[num_review_items], outputs=review_list_df)
gr.Markdown("### स्थानीय मतदान गर्नुहोस् (Cast Your Local Vote)")
# ... (voting buttons as before, using vote_recording which now acts locally) ...
upvote_btn = gr.Button("👍 मन पर्यो")
downvote_btn = gr.Button("👎 मन परेन")
quality_rating_slider = gr.Slider(minimum=1, maximum=5, step=1, label="गुणस्तर मूल्याङ्कन", value=3)
submit_quality_btn = gr.Button("गुणस्तर मत दिनुहोस्")
correctness_rating_slider = gr.Slider(minimum=1, maximum=5, step=1, label="शुद्धता मूल्याङ्कन", value=3)
submit_correctness_btn = gr.Button("शुद्धता मत दिनुहोस्")
vote_status_output = gr.Textbox(label="मतदान स्थिति", interactive=False)
def vote_and_refresh_local(rec_id, vote_t, vote_val_str):
status = vote_recording(rec_id, vote_t, str(vote_val_str))
new_ratings = get_local_recording_ratings(rec_id) if rec_id else "रेकर्डिङ चयन गर्नुहोस्"
return status, new_ratings
upvote_btn.click(vote_and_refresh_local, inputs=[selected_review_id, gr.Textbox(value="upvote", visible=False), gr.Number(value=0, visible=False)], outputs=[vote_status_output, current_ratings_display])
downvote_btn.click(vote_and_refresh_local, inputs=[selected_review_id, gr.Textbox(value="downvote", visible=False), gr.Number(value=0, visible=False)], outputs=[vote_status_output, current_ratings_display])
submit_quality_btn.click(vote_and_refresh_local, inputs=[selected_review_id, gr.Textbox(value="quality", visible=False), quality_rating_slider], outputs=[vote_status_output, current_ratings_display])
submit_correctness_btn.click(vote_and_refresh_local, inputs=[selected_review_id, gr.Textbox(value="correctness", visible=False), correctness_rating_slider], outputs=[vote_status_output, current_ratings_display])
with gr.TabItem("३. प्रशासक: सिंक र प्रगति (Admin: Sync & Progress)"):
gr.Markdown("## स्थानीय संकलन प्रगति (Local Collection Progress)")
total_count_display = gr.Textbox(label="स्थानीय तथ्याङ्क", interactive=False, lines=3)
refresh_total_count_btn = gr.Button("स्थानीय गणना ताजा गर्नुहोस्")
refresh_total_count_btn.click(update_local_count, outputs=total_count_display)
gr.Markdown("---")
gr.Markdown("## प्रशासक कार्यहरू (Admin Actions)")
gr.Markdown("यी कार्यहरूका लागि प्रशासक पासवर्ड आवश्यक छ (गोप्यमा `ADMIN_UPLOAD_PASSWORD` को रूपमा सेट गरिएको)। "
"HF टोकन र लक्ष्य रिपो आईडी पनि गोप्यमा (`HF_TOKEN`, `TARGET_HF_DATASET_REPO_ID`) हुनुपर्छ।")
admin_password_input_sync = gr.Textbox(label="प्रशासक पासवर्ड", type="password", placeholder="प्रशासक पासवर्ड प्रविष्ट गर्नुहोस्")
with gr.Row():
retry_failed_uploads_btn = gr.Button("असफल HF अपलोडहरू पुनः प्रयास गर्नुहोस्")
sync_ratings_btn = gr.Button("स्थानीय मूल्याङ्कनहरू HF मा सिंक गर्नुहोस्")
admin_action_status_output = gr.Textbox(label="प्रशासक कार्य स्थिति", interactive=False, lines=10)
retry_failed_uploads_btn.click(admin_retry_failed_uploads, inputs=[admin_password_input_sync], outputs=admin_action_status_output)
sync_ratings_btn.click(admin_sync_ratings_to_hf, inputs=[admin_password_input_sync], outputs=admin_action_status_output)
with gr.TabItem("४. जानकारी (Information)"):
gr.Markdown(render_info_page())
app.load(fn=update_local_count, inputs=None, outputs=total_count_display)
app.load(fn=lambda n: list_local_recordings(n), inputs=[num_review_items], outputs=review_list_df)
return app
def render_info_page():
return """
## नेपाली ASR डाटा संकलन प्रोजेक्टको बारेमा (About the Nepali ASR Data Collection Project)
यो प्रोजेक्टले नेपाली भाषाको स्वचालित भाषण पहिचान (ASR) प्रविधिको विकासका लागि आवश्यक डाटा संकलन गर्दछ।
तपाईंको प्रत्येक रेकर्डिङ सिधै हाम्रो खुला हगिङ फेस डेटासेटमा योगदान गरिनेछ।
### कसरी योगदान दिने (How to Contribute):
1. **आवाज रेकर्ड गर्नुहोस् (Record Voice)** ट्याबमा जानुहोस् र आफ्नो आवाज रेकर्ड गर्नुहोस्।
2. **रेकर्डिङ समीक्षा गर्नुहोस् (Review Local Recordings)** ट्याबमा गएर अरूले गरेका (वा तपाईंले गरेका) स्थानीय रूपमा सुरक्षित गरिएका रेकर्डिङहरू सुन्नुहोस् र मत दिनुहोस्। यी मतहरू पछि हगिङ फेसमा सिंक गर्न सकिन्छ।
### गोपनीयता नीति (Privacy Policy):
- तपाईंको आवाज रेकर्डिङ र मेटाडाटा सार्वजनिक अनुसन्धान उद्देश्यका लागि हगिङ फेसमा खुला रूपमा उपलब्ध हुनेछ।
- कृपया व्यक्तिगत पहिचान गर्न सकिने जानकारी शेयर नगर्नुहोस्।
""" # Keep your more detailed version
# --- Main Execution ---
if __name__ == "__main__":
initialize_data_storage()
app_ui = build_ui()
app_ui.launch() |