1 00:00:00,000 --> 00:00:03,466 [No Audio] 2 00:00:03,466 --> 00:00:06,036 What we did so far with our program, is we build 3 00:00:06,037 --> 00:00:08,868 the first page where the user can Login, and we 4 00:00:08,869 --> 00:00:12,916 also built the Sign Up page, where new users can Sign 5 00:00:12,917 --> 00:00:16,233 Up and be a member in our JSON database. 6 00:00:16,690 --> 00:00:17,908 In this lecture we're going 7 00:00:17,909 --> 00:00:20,906 to implement the Login functionality. 8 00:00:20,907 --> 00:00:23,044 Let me show you, how the 9 00:00:23,045 --> 00:00:25,900 finished version of the program works. 10 00:00:25,901 --> 00:00:28,892 I'm not showing you the code, not yet. 11 00:00:28,893 --> 00:00:31,612 Just how the Login will work. 12 00:00:31,613 --> 00:00:33,868 Ignore the nice looking interface for 13 00:00:33,869 --> 00:00:35,228 now, we will do that later. 14 00:00:35,229 --> 00:00:38,002 Now we have to think about the functionality. 15 00:00:38,003 --> 00:00:41,433 So when the user Logs In, they enter the data, 16 00:00:41,434 --> 00:00:43,800 [Author Typing] 17 00:00:43,801 --> 00:00:44,966 they press Login, 18 00:00:46,100 --> 00:00:49,696 and they go to this internal page of the program. 19 00:00:49,697 --> 00:00:53,204 So here then we have a button, which if we hover the 20 00:00:53,205 --> 00:00:58,452 mouse, it will become red and if we click, it will Log 21 00:00:58,453 --> 00:01:02,240 us out, and it will take us back to the Login page. 22 00:01:02,870 --> 00:01:05,233 If the data are wrong, 23 00:01:06,333 --> 00:01:09,250 it will say, Wrong username or password. 24 00:01:09,990 --> 00:01:12,420 So again, when the data are correct, 25 00:01:13,590 --> 00:01:15,224 it will take us to this page. 26 00:01:15,225 --> 00:01:16,988 So in this lecture, let's go 27 00:01:16,989 --> 00:01:19,308 ahead and build this screen. 28 00:01:19,309 --> 00:01:23,190 I made a screenshot of that, so we have it here for reference. 29 00:01:24,890 --> 00:01:26,972 So we need to add one more 30 00:01:26,973 --> 00:01:29,692 screen in the list of screens here. 31 00:01:29,693 --> 00:01:35,200 Let's name this screen, LoginScreenSuccess 32 00:01:36,666 --> 00:01:46,666 and name. Let's be on the same lines login_screen_success in quotes. 33 00:01:47,766 --> 00:01:51,360 And then create, a rule for that screen. 34 00:01:51,970 --> 00:01:54,180 I'm just going to copy and paste it. 35 00:01:54,180 --> 00:01:57,190 [No Audio] 36 00:01:57,191 --> 00:01:59,496 And so what do we have here? 37 00:01:59,497 --> 00:02:05,990 Well, we start with the GridLayout, which has one column. 38 00:02:05,991 --> 00:02:10,729 For now, I'm just going to provide a simple button. 39 00:02:10,730 --> 00:02:13,682 Later on we will implement the functionality 40 00:02:13,683 --> 00:02:15,634 that you just show with that animation, 41 00:02:15,635 --> 00:02:17,148 when you put your mouse over the 42 00:02:17,149 --> 00:02:19,233 button, the button will become red. 43 00:02:19,666 --> 00:02:22,933 So for now let's just use a simple Button, 44 00:02:22,934 --> 00:02:25,700 [Author Typing] 45 00:02:25,701 --> 00:02:31,650 with text, Logout, on_press. 46 00:02:31,651 --> 00:02:35,630 So we're going to have to create a LoginScreenSuccess class 47 00:02:35,631 --> 00:02:37,620 in the Python code, and create 48 00:02:37,621 --> 00:02:42,058 a function there, to Logout the user. 49 00:02:42,059 --> 00:02:46,296 So log_out, yeah, that's how I would like to call 50 00:02:46,297 --> 00:02:49,416 the function in the LoginScreenSuccess class, 51 00:02:49,417 --> 00:02:51,096 that we are going to create. 52 00:02:51,097 --> 00:02:53,096 Let's leave the button like that, 53 00:02:53,097 --> 00:02:55,330 and then we have a Label. 54 00:02:55,333 --> 00:02:57,290 [Author Typing] 55 00:02:57,291 --> 00:03:01,200 How do you feel? that is Label text. 56 00:03:01,201 --> 00:03:08,000 [Author Typing] 57 00:03:08,010 --> 00:03:10,688 So we are asking the user How they feel, so 58 00:03:10,689 --> 00:03:13,936 they can enter a feeling and then we give them 59 00:03:13,937 --> 00:03:17,632 some quotes depending on how they feel, to make them 60 00:03:17,633 --> 00:03:20,678 feel better or to enhance their feeling. 61 00:03:20,679 --> 00:03:22,500 Quotes are a good thing. 62 00:03:22,501 --> 00:03:25,108 Very smart people have thought well about them, 63 00:03:25,109 --> 00:03:28,020 so, let's use them, let's make use of them. 64 00:03:28,021 --> 00:03:29,099 TextInput 65 00:03:29,100 --> 00:03:31,700 [Author Typing] 66 00:03:31,701 --> 00:03:33,300 with hint_text. 67 00:03:35,030 --> 00:03:37,816 So here you can write whatever you like, but 68 00:03:37,817 --> 00:03:40,632 I'd like to give them a hint to let 69 00:03:40,633 --> 00:03:43,256 them know what they can enter here. 70 00:03:43,257 --> 00:03:48,236 So without having to include any big description, here 71 00:03:48,237 --> 00:03:51,740 in the body of the interface of the page, 72 00:03:51,741 --> 00:03:54,796 let's keep the interface clean and we make use 73 00:03:54,797 --> 00:03:58,300 of this area here in the text box. 74 00:03:58,830 --> 00:04:07,450 So Things to try, happy, sad, unloved. 75 00:04:08,270 --> 00:04:10,416 Yeah, that should be okay. 76 00:04:10,417 --> 00:04:14,240 And then we have another button with text 77 00:04:15,650 --> 00:04:18,755 Enlighten me, feel free to use any name. 78 00:04:18,756 --> 00:04:21,459 That's how far my imagination goes. 79 00:04:21,460 --> 00:04:24,728 Now on press, what are we going to 80 00:04:24,729 --> 00:04:27,736 do when the user presses that button? 81 00:04:27,737 --> 00:04:30,888 Well, when the user presses that button, we are 82 00:04:30,889 --> 00:04:35,140 going to display some text, below the button. 83 00:04:35,750 --> 00:04:38,800 So therefore we'll need a Label, 84 00:04:38,801 --> 00:04:41,300 [Author Typing] 85 00:04:41,301 --> 00:04:44,242 and its text for now is just an empty string. 86 00:04:44,243 --> 00:04:47,042 So let's include an onpress attribute 87 00:04:47,043 --> 00:04:48,928 for the button later on. 88 00:04:48,929 --> 00:04:51,566 For now, let me go ahead and, 89 00:04:51,567 --> 00:04:54,100 [No Audio] 90 00:04:54,101 --> 00:05:00,666 write a class LoginScreenSuccess, 91 00:05:02,133 --> 00:05:04,533 which inherits of course from Screen, 92 00:05:04,534 --> 00:05:07,400 [Author Typing] 93 00:05:07,401 --> 00:05:16,264 and it has a method log_out, log_out to log the user out. 94 00:05:16,265 --> 00:05:18,300 And here I would like to, 95 00:05:18,301 --> 00:05:20,400 [Author Typing] 96 00:05:20,401 --> 00:05:21,500 first 97 00:05:21,501 --> 00:05:24,533 [Author Typing] 98 00:05:24,534 --> 00:05:29,068 define a direction for the transition of this screen. 99 00:05:29,069 --> 00:05:30,812 Let's put it right. 100 00:05:30,813 --> 00:05:33,532 So the logout is going back to the previous page. 101 00:05:33,533 --> 00:05:36,572 So it makes sense to have a right direction for the 102 00:05:36,573 --> 00:05:43,248 transition and then of course, manager.current equal to where do 103 00:05:43,249 --> 00:05:45,888 we want to take the user after they Logout? 104 00:05:45,889 --> 00:05:48,256 We want to take the user to the 105 00:05:48,266 --> 00:05:51,233 Login screen again, that makes some sense, right? 106 00:05:52,166 --> 00:05:56,388 So login_screen, alright, so we 107 00:05:56,389 --> 00:05:58,733 have the page, we constructed the 108 00:05:58,734 --> 00:06:04,950 LoginScreenSuccess page, which was this one in here. 109 00:06:05,133 --> 00:06:08,100 So let me close this to have more room for the code. 110 00:06:08,870 --> 00:06:13,096 However, we haven't yet implemented the 111 00:06:13,097 --> 00:06:15,530 functionality of the Login button. 112 00:06:15,531 --> 00:06:19,276 So u1, p1, Login doesn't work. 113 00:06:19,277 --> 00:06:22,440 So let's locate the Login button 114 00:06:22,440 --> 00:06:24,890 [No Audio] 115 00:06:24,891 --> 00:06:26,920 which is in the LoginScreen. 116 00:06:27,850 --> 00:06:31,536 Yes, the LoginScreen, yes. 117 00:06:31,537 --> 00:06:34,358 So that's a button, Button, Login. 118 00:06:34,359 --> 00:06:39,980 So what do we want to do on, an on_press event? 119 00:06:40,770 --> 00:06:47,732 Well, we want to execute a root.login function, which we 120 00:06:47,733 --> 00:06:52,160 need to have in the LoginScreen class, just here. 121 00:06:52,690 --> 00:06:56,433 So it's basically the same idea as the add_user 122 00:06:57,040 --> 00:06:59,864 function, where we gave the add_user function, 123 00:06:59,865 --> 00:07:03,170 we provided it with the username and the password. 124 00:07:03,910 --> 00:07:12,732 So again we do the same thing with def login self, 125 00:07:12,733 --> 00:07:17,554 and, so here we need to give two arguments. 126 00:07:17,555 --> 00:07:22,700 The first one would be root.ids.username.text 127 00:07:23,310 --> 00:07:29,408 and the second would be root.ids.password.text. 128 00:07:29,409 --> 00:07:32,256 So we are talking here, sorry about the typo here. 129 00:07:32,257 --> 00:07:36,004 We are talking about the username, that the user enters in 130 00:07:36,005 --> 00:07:39,978 the text input box and the password that the user enters 131 00:07:39,979 --> 00:07:43,480 in the text input box in the LoginScreen. 132 00:07:43,481 --> 00:07:47,352 So root, refers to the LoginScreen, to the 133 00:07:47,353 --> 00:07:51,576 current rule, where you are writing the code here 134 00:07:51,577 --> 00:07:54,478 and we don't have an id for TextInput. 135 00:07:54,479 --> 00:08:02,550 So let's go ahead and do id username, same for password. 136 00:08:02,566 --> 00:08:06,966 [Author Typing] 137 00:08:06,970 --> 00:08:09,638 And so then we take this username 138 00:08:09,639 --> 00:08:12,592 and password in the login function. 139 00:08:12,593 --> 00:08:17,430 Let's use uname and pword as parameters. 140 00:08:17,431 --> 00:08:19,600 You can use whatever name you would like. 141 00:08:19,601 --> 00:08:21,834 You could also use username and password. 142 00:08:21,835 --> 00:08:24,298 So how do we login a user? 143 00:08:24,299 --> 00:08:28,292 Well, the idea is that we need to open to 144 00:08:28,293 --> 00:08:31,812 read the JSON file, where we have the user's data 145 00:08:31,813 --> 00:08:36,376 and check to see if that username and password are 146 00:08:36,377 --> 00:08:40,312 in that file or more accurately, if that username is 147 00:08:40,313 --> 00:08:43,022 in the file and it has as password, the password 148 00:08:43,023 --> 00:08:46,870 that the user is providing in the graphical user interface. 149 00:08:48,010 --> 00:08:52,764 If that is the case, then we switch the screen using 150 00:08:52,765 --> 00:08:58,640 a manager.current property, we switch the screen to the screen 151 00:08:58,641 --> 00:09:02,208 that I just showed you, that we just built, and that 152 00:09:02,209 --> 00:09:04,992 we haven't seen yet how it looks like. 153 00:09:04,993 --> 00:09:06,752 So let me quickly implement this 154 00:09:06,753 --> 00:09:12,122 with open users.json as file. 155 00:09:12,123 --> 00:09:15,520 So in read mode, when we don't define the r 156 00:09:16,050 --> 00:09:20,800 like that, that implicitly means that we are reading the file. 157 00:09:21,066 --> 00:09:28,110 users = json.load the file. 158 00:09:28,111 --> 00:09:30,894 So that will give us a dictionary. 159 00:09:30,895 --> 00:09:35,192 Users will be the dictionary containing all the data in the 160 00:09:35,193 --> 00:09:40,790 users.json file. And then if uname in users, 161 00:09:41,370 --> 00:09:46,040 so what we are doing here, is let me show you. 162 00:09:46,040 --> 00:09:48,110 [Author Typing] 163 00:09:48,111 --> 00:09:50,620 So we need this JSON library and 164 00:09:50,633 --> 00:09:52,750 [Author Typing] 165 00:09:52,751 --> 00:09:57,470 users will be the dictionary, right? 166 00:09:57,471 --> 00:10:02,340 Lots of data there and if we say for example, if 167 00:10:02,341 --> 00:10:08,132 u7, u7 in users, we are going to get 168 00:10:08,133 --> 00:10:13,274 true, because u7 is actually among the dictionary keys. 169 00:10:13,275 --> 00:10:17,352 So here u7, you can ignore the user there, 170 00:10:17,353 --> 00:10:20,328 they are just a prefix to denote that, these are 171 00:10:20,329 --> 00:10:23,326 Unicode data, but these are the strings inside the quotes. 172 00:10:23,327 --> 00:10:27,300 So u7 is among the dictionary keys. 173 00:10:27,690 --> 00:10:32,440 You can also get a clear list of the keys with that. 174 00:10:33,050 --> 00:10:37,880 So users.keys, you see that u7 is among those data. 175 00:10:37,880 --> 00:10:39,770 [Author Typing] 176 00:10:39,771 --> 00:10:42,432 So that is why we get true and we can make 177 00:10:42,433 --> 00:10:45,990 use of that and say, if uname is in users. 178 00:10:45,991 --> 00:10:48,864 So first we check if the username is in 179 00:10:48,865 --> 00:10:53,332 the database, but we also need to check and 180 00:10:53,333 --> 00:11:01,280 users uname, password equal to pword. 181 00:11:01,280 --> 00:11:03,750 [Author Typing] 182 00:11:03,751 --> 00:11:06,333 So that is our condition actually. 183 00:11:08,070 --> 00:11:11,688 So the first is that, the username has to exist and the 184 00:11:11,689 --> 00:11:18,120 second is that the users, uname, let's say u7, 185 00:11:19,690 --> 00:11:23,160 so users u7 is the equivalent of this. 186 00:11:24,170 --> 00:11:27,954 So that will give us the dictionary, 187 00:11:27,955 --> 00:11:30,430 that the key u7 has. 188 00:11:30,431 --> 00:11:33,900 This is like the value, that the key u7 has. 189 00:11:35,150 --> 00:11:37,472 So it's a dictionary and if we 190 00:11:37,473 --> 00:11:44,202 continue, our accessing chain, we do password. 191 00:11:44,203 --> 00:11:47,716 So we are accessing the value of key password every, 192 00:11:47,717 --> 00:11:52,196 each of these dictionaries have this password, as a key 193 00:11:52,197 --> 00:11:55,790 and the value of that password is the actual password. 194 00:11:55,791 --> 00:11:57,780 So p7 in this case. 195 00:11:59,110 --> 00:12:02,606 So we are checking if the password of that user, 196 00:12:02,607 --> 00:12:05,960 is a password that the user is providing here. 197 00:12:07,370 --> 00:12:13,148 So, password.text goes in here, this has 198 00:12:13,149 --> 00:12:16,570 to be equal not an assignment operator. 199 00:12:16,571 --> 00:12:20,440 So if that is the case then, 200 00:12:20,441 --> 00:12:27,381 self.manager.current equal to the LoginSuccess page, 201 00:12:27,382 --> 00:12:34,724 LoginScreenSuccess, which we created, right? 202 00:12:34,725 --> 00:12:38,036 And we also need to add an else conditional there. 203 00:12:38,037 --> 00:12:41,428 But let me try to see what we have so 204 00:12:41,429 --> 00:12:44,020 far and debug the code if we have some problems. 205 00:12:45,830 --> 00:12:51,592 So u7, p7, Login and here is a screen. 206 00:12:51,593 --> 00:12:53,672 So this is a button Logout. 207 00:12:53,673 --> 00:12:54,856 How do you feel? 208 00:12:54,857 --> 00:12:57,272 The text box we created, Enlighten me. 209 00:12:57,273 --> 00:13:01,910 And, this is the area where the text would be displayed. 210 00:13:03,210 --> 00:13:05,362 For now it doesn't work, because we haven't 211 00:13:05,363 --> 00:13:09,184 attached a function to the Enlighten me button. 212 00:13:09,185 --> 00:13:11,420 Let me now try the Logout button. 213 00:13:13,310 --> 00:13:17,930 So log_out is not defined, as you can see here the error. 214 00:13:18,590 --> 00:13:20,599 So our Logout button 215 00:13:20,600 --> 00:13:23,733 [No Audio] 216 00:13:23,734 --> 00:13:25,690 which is here on_press, 217 00:13:26,300 --> 00:13:31,220 it's pointing to, actually we should write root.log_out. 218 00:13:31,221 --> 00:13:32,782 So it's pointing to the 219 00:13:32,783 --> 00:13:36,190 LoginScreenSuccess, Logout function. 220 00:13:36,200 --> 00:13:38,960 [No Audio] 221 00:13:38,961 --> 00:13:40,482 So that was a problem. 222 00:13:40,483 --> 00:13:43,298 We didn't specify the class 223 00:13:43,299 --> 00:13:46,034 that had this log_out button. 224 00:13:46,035 --> 00:13:47,570 So let me try again. 225 00:13:47,570 --> 00:13:53,433 [Author Typing] 226 00:13:53,434 --> 00:13:57,430 p7 Login, Logout, and we are back 227 00:13:57,431 --> 00:14:01,430 to the Login page. When we do Logout and 228 00:14:02,000 --> 00:14:06,858 if we enter some wrong data, nothing will happen. 229 00:14:06,859 --> 00:14:08,730 So here is what we are going to do. 230 00:14:08,731 --> 00:14:11,978 We are going to add a label just under the 231 00:14:11,979 --> 00:14:15,950 Login button, between these two buttons and the Login button. 232 00:14:15,951 --> 00:14:17,982 So let's go ahead and do that. 233 00:14:17,983 --> 00:14:19,412 We are talking about the Login 234 00:14:19,413 --> 00:14:22,798 screen, that is the Login button. 235 00:14:22,799 --> 00:14:24,666 So let's add the label 236 00:14:26,333 --> 00:14:29,778 with text as empty for now. 237 00:14:29,779 --> 00:14:30,933 So save that, 238 00:14:30,934 --> 00:14:32,966 [No Audio] 239 00:14:32,967 --> 00:14:35,170 close that window, run again. 240 00:14:35,171 --> 00:14:36,774 Now we have a space here. 241 00:14:36,775 --> 00:14:39,292 So that's a label, and in that label 242 00:14:39,293 --> 00:14:42,998 now, when the data are correct, we are 243 00:14:42,999 --> 00:14:46,530 going to the login_screen_success page, else, 244 00:14:47,300 --> 00:14:50,960 so now we need to get access to the id of the Label. 245 00:14:50,961 --> 00:14:55,910 So let's first put an id to the Label login_wrong. 246 00:14:56,840 --> 00:15:00,944 So here now we need to access that Label. 247 00:15:00,945 --> 00:15:03,198 The way you do that is using self, 248 00:15:03,199 --> 00:15:06,730 so self points to the LoginScreen object. 249 00:15:07,260 --> 00:15:14,434 Then we look for the ids of self, login_wrong id. 250 00:15:14,435 --> 00:15:17,266 So that is the label object. 251 00:15:17,267 --> 00:15:19,672 Now we need to access the text of the label 252 00:15:19,673 --> 00:15:25,740 object, and assign the text, Wrong username or password. 253 00:15:25,740 --> 00:15:28,020 [Author Typing] 254 00:15:28,021 --> 00:15:31,782 So make sure you save the kivy file and run the 255 00:15:31,783 --> 00:15:36,860 code, just some random data which are not in the database, 256 00:15:36,861 --> 00:15:42,820 Login and we get the label there, as we expected. 257 00:15:42,833 --> 00:15:45,240 [No Audio] 258 00:15:45,241 --> 00:15:51,110 u7, p7, Login and we go to the Login page. 259 00:15:51,110 --> 00:15:53,740 [No Audio] 260 00:15:53,741 --> 00:15:58,724 So that is how you access elements from the kivy file. 261 00:15:58,725 --> 00:16:01,636 So when you are in the kivy file, root 262 00:16:01,637 --> 00:16:05,272 will point to the associated class of that rule. 263 00:16:05,273 --> 00:16:08,850 So LoginScreen, LoginScreen class, these 264 00:16:08,851 --> 00:16:10,430 names have to be the same. 265 00:16:11,120 --> 00:16:14,114 And when you are in the Python file, self 266 00:16:14,115 --> 00:16:18,290 is pointing to that class, LoginScreen class. 267 00:16:19,300 --> 00:16:22,438 And since LoginScreen here and LoginScreen there 268 00:16:22,439 --> 00:16:25,398 communicate to each other, they get and receive data. 269 00:16:25,399 --> 00:16:30,156 That means the self object knows about the ids 270 00:16:30,157 --> 00:16:34,028 and all the widgets, that the LoginScreen contains. 271 00:16:34,029 --> 00:16:39,452 So therefore you look for the login_wrong id, to give you this label. 272 00:16:39,453 --> 00:16:41,254 This object of the login screen. 273 00:16:41,255 --> 00:16:45,470 And then you access text, so self here, root there. 274 00:16:45,471 --> 00:16:48,574 And that's it. Let's go in the next lecture now and 275 00:16:48,575 --> 00:16:52,033 make some more cool things about the interface, thanks.